Exemple #1
0
        public SourceViewModel(IApplicationService applicationService, IAccountsService accountsService, IFilesystemService filesystemService)
            : base(accountsService)
        {
            GoToEditCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SourceItem, x => x.TrueBranch).Select(x => x.Item1 != null && x.Item2));
            GoToEditCommand.Subscribe(_ =>
            {
                var vm        = CreateViewModel <EditSourceViewModel>();
                vm.Path       = Path;
                vm.Branch     = Branch;
                vm.Username   = Username;
                vm.Repository = Repository;
                ShowViewModel(vm);
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                string filepath;
                string mime;

                using (var stream = filesystemService.CreateTempFile(out filepath))
                {
                    mime = await applicationService.Client.DownloadRawResource2(GitUrl, stream) ?? string.Empty;
                }

                // We can force a binary representation if it was passed during init. In which case we don't care to figure out via the mime.
                var isBinary = !mime.Contains("charset");
                var fileUri  = new Uri(filepath);
                SourceItem   = new FileSourceItemViewModel(fileUri, ForceBinary || isBinary);
            });
        }
Exemple #2
0
        public SourceViewModel(IApplicationService applicationService, IAccountsService accountsService, IFilesystemService filesystemService)
        {
            GoToEditCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SourceItem, x => x.TrueBranch).Select(x => x.Item1 != null && x.Item2));
            GoToEditCommand.Subscribe(_ =>
            {
                var vm        = CreateViewModel <EditSourceViewModel>();
                vm.Path       = CurrentItem.Path;
                vm.Branch     = Branch;
                vm.Username   = Username;
                vm.Repository = Repository;
                ShowViewModel(vm);
            });

            Theme = applicationService.Account.CodeEditTheme;
            this.WhenAnyValue(x => x.Theme).Skip(1).Subscribe(x =>
            {
                applicationService.Account.CodeEditTheme = x;
                accountsService.Update(applicationService.Account);
            });

            this.WhenAnyValue(x => x.CurrentItem)
            .Skip(1)
            .Where(x => x != null)
            .Subscribe(_ => LoadCommand.ExecuteIfCan());

            _loadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var fileName = System.IO.Path.GetFileName(CurrentItem.Name);
                if (fileName == null)
                {
                    return;
                }

                string filepath;
                string mime;

                using (var stream = filesystemService.CreateTempFile(out filepath))
                {
                    mime = await applicationService.Client.DownloadRawResource2(CurrentItem.GitUrl, stream) ?? string.Empty;
                }

                // We can force a binary representation if it was passed during init. In which case we don't care to figure out via the mime.
                var isBinary = !mime.Contains("charset");
                SourceItem   = new FileSourceItemViewModel {
                    FilePath = filepath, IsBinary = (CurrentItem.ForceBinary || isBinary)
                };
            });

            SetupRx();
        }
Exemple #3
0
        public SourceViewModel(IApplicationService applicationService, IAccountsService accountsService, IFilesystemService filesystemService)
            : base(accountsService)
        {
            GoToEditCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SourceItem, x => x.TrueBranch).Select(x => x.Item1 != null && x.Item2));
            GoToEditCommand.Subscribe(_ =>
            {
                var vm        = CreateViewModel <EditSourceViewModel>();
                vm.Path       = Path;
                vm.Branch     = Branch;
                vm.Username   = RepositoryOwner;
                vm.Repository = RepositoryName;
                ShowViewModel(vm);
            });

            this.WhenAnyValue(x => x.Name).Subscribe(x => Title = x ?? string.Empty);

            _isMarkdown = this.WhenAnyValue(x => x.Path).IsNotNull().Select(x =>
                                                                            MarkdownExtensions.Any(Path.EndsWith)).ToProperty(this, x => x.IsMarkdown);

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                string filepath;
                bool isBinary = false;

                using (var stream = filesystemService.CreateTempFile(out filepath))
                {
                    if (MarkdownExtensions.Any(Path.EndsWith))
                    {
                        var renderedContent = await applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFileRendered(Path, Branch);
                        using (var stringWriter = new StreamWriter(stream))
                        {
                            await stringWriter.WriteAsync(renderedContent);
                        }
                    }
                    else
                    {
                        var mime = await applicationService.Client.DownloadRawResource2(GitUrl, stream) ?? string.Empty;
                        isBinary = !(mime ?? string.Empty).Contains("charset");
                    }
                }

                // We can force a binary representation if it was passed during init. In which case we don't care to figure out via the mime.
                var fileUri = new Uri(filepath);
                SourceItem  = new FileSourceItemViewModel(fileUri, ForceBinary || isBinary);
            });
        }
Exemple #4
0
        public IssueViewModel(
            IApplicationService applicationService,
            IActionMenuFactory actionMenuFactory,
            IMarkdownService markdownService)
            : base(applicationService, markdownService)
        {
            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue).Select(x => x != null);

            this.WhenAnyValue(x => x.Id)
            .Subscribe(x => Title = "Issue #" + x);

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            ShareCommand.Subscribe(_ => actionMenuFactory.ShareUrl(Issue.HtmlUrl));

            GoToEditCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToEditCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
//                vm.Issue = Issue;
//                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                NavigateTo(vm);
            });

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Issue).Select(x => x != null),
                _ =>
            {
                var menu = actionMenuFactory.Create(Title);
                menu.AddButton(Issue.State == Octokit.ItemState.Open ? "Close" : "Open", ToggleStateCommand);
//
//
//                var editButton = _actionSheet.AddButton("Edit");
//                var commentButton = _actionSheet.AddButton("Comment");
//                var shareButton = _actionSheet.AddButton("Share");
//                var showButton = _actionSheet.AddButton("Show in GitHub");

                return(menu.Show());
            });
        }
Exemple #5
0
        public SourceViewModel(ISessionService sessionService, IActionMenuFactory actionMenuFactory,
                               IFilesystemService filesystemService)
            : base(sessionService)
        {
            var canEdit = this.WhenAnyValue(x => x.SourceItem, x => x.TrueBranch, x => x.PushAccess)
                          .Select(x => x.Item1 != null && x.Item2 && !x.Item1.IsBinary && x.Item3.HasValue && x.Item3.Value);

            GoToEditCommand = ReactiveCommand.Create(canEdit);
            GoToEditCommand.Subscribe(_ => {
                var vm = this.CreateViewModel <EditFileViewModel>();
                vm.Init(RepositoryOwner, RepositoryName, Path, null, Branch);
                vm.SaveCommand.Subscribe(x => {
                    GitUrl = x.Content.GitUrl.AbsoluteUri;
                    LoadCommand.ExecuteIfCan();
                });
                NavigateTo(vm);
            });

            this.WhenAnyValue(x => x.Name).Subscribe(x => Title = x ?? string.Empty);

            _isMarkdown = this.WhenAnyValue(x => x.Path).IsNotNull().Select(x =>
                                                                            MarkdownExtensions.Any(Path.EndsWith)).ToProperty(this, x => x.IsMarkdown);

            OpenInGitHubCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.HtmlUrl).Select(x => !string.IsNullOrEmpty(x)));
            OpenInGitHubCommand
            .Select(_ => this.CreateViewModel <WebBrowserViewModel>())
            .Select(x => x.Init(this.HtmlUrl))
            .Subscribe(NavigateTo);

            var canShowMenu = this.WhenAnyValue(x => x.SourceItem).Select(x => x != null);

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(canShowMenu, sender => {
                var menu = actionMenuFactory.Create();
                if (GoToEditCommand.CanExecute(null))
                {
                    menu.AddButton("Edit", GoToEditCommand);
                }
                menu.AddButton("Open With", OpenWithCommand);
                if (OpenInGitHubCommand.CanExecute(null))
                {
                    menu.AddButton("Open in GitHub", OpenInGitHubCommand);
                }
                return(menu.Show(sender));
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                string filepath;
                bool isBinary = false;

                if (!PushAccess.HasValue)
                {
                    sessionService.GitHubClient.Repository.Get(RepositoryOwner, RepositoryName)
                    .ToBackground(x => PushAccess = x.Permissions.Push);
                }

                using (var stream = filesystemService.CreateTempFile(out filepath, Name))
                {
                    if (MarkdownExtensions.Any(Path.EndsWith))
                    {
                        var renderedContent = await sessionService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFileRendered(Path, Branch);
                        using (var stringWriter = new StreamWriter(stream))
                        {
                            await stringWriter.WriteAsync(renderedContent);
                        }
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(GitUrl) || string.IsNullOrEmpty(HtmlUrl))
                        {
                            var req  = sessionService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContentFile(Path, Branch);
                            var data = (await sessionService.Client.ExecuteAsync(req)).Data;
                            GitUrl   = data.GitUrl;
                            HtmlUrl  = data.HtmlUrl;
                        }

                        var mime = await sessionService.Client.DownloadRawResource2(GitUrl, stream) ?? string.Empty;
                        isBinary = !(mime ?? string.Empty).Contains("charset");
                    }
                }

                // We can force a binary representation if it was passed during init. In which case we don't care to figure out via the mime.
                var fileUri = new Uri(filepath);
                SourceItem  = new FileSourceItemViewModel(fileUri, ForceBinary || isBinary);
            });
        }
Exemple #6
0
        public GistViewModel(
            ISessionService sessionService,
            IActionMenuFactory actionMenuService,
            IAlertDialogFactory alertDialogFactory)
        {
            Comments = new ReactiveList <GistCommentModel>();

            Title = "Gist";

            this.WhenAnyValue(x => x.Gist).Where(x => x != null && x.Files != null && x.Files.Count > 0)
            .Select(x => x.Files.First().Key).Subscribe(x =>
                                                        Title = x);

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null));
            ShareCommand.Subscribe(sender => actionMenuService.ShareUrl(sender, new Uri(Gist.HtmlUrl)));

            this.WhenAnyValue(x => x.Gist.Owner.AvatarUrl)
            .Select(x => new GitHubAvatar(x))
            .ToProperty(this, x => x.Avatar, out _avatar);

            ToggleStarCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.IsStarred).Select(x => x.HasValue),
                async t =>
            {
                try
                {
                    if (!IsStarred.HasValue)
                    {
                        return;
                    }
                    var request = IsStarred.Value ? sessionService.Client.Gists[Id].Unstar() : sessionService.Client.Gists[Id].Star();
                    await sessionService.Client.ExecuteAsync(request);
                    IsStarred = !IsStarred.Value;
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to start gist. Please try again.", e);
                }
            });

            ForkCommand = ReactiveCommand.CreateAsyncTask(async t => {
                var gist = await sessionService.GitHubClient.Gist.Fork(Id);
                var vm   = this.CreateViewModel <GistViewModel>();
                vm.Id    = gist.Id;
                vm.Gist  = gist;
                NavigateTo(vm);
            });

            ForkCommand.IsExecuting.Subscribe(x =>
            {
                if (x)
                {
                    alertDialogFactory.Show("Forking...");
                }
                else
                {
                    alertDialogFactory.Hide();
                }
            });

            GoToEditCommand = ReactiveCommand.Create();
            GoToEditCommand.Subscribe(_ =>
            {
                var vm  = this.CreateViewModel <GistEditViewModel>();
                vm.Gist = Gist;
                vm.SaveCommand.Subscribe(x => Gist = x);
                NavigateTo(vm);
            });

            GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            GoToHtmlUrlCommand
            .Select(_ => this.CreateViewModel <WebBrowserViewModel>())
            .Select(x => x.Init(Gist.HtmlUrl))
            .Subscribe(NavigateTo);

            GoToFileSourceCommand = ReactiveCommand.Create();
            GoToFileSourceCommand.OfType <GistFile>().Subscribe(x =>
            {
                var vm      = this.CreateViewModel <GistFileViewModel>();
                vm.Id       = Id;
                vm.GistFile = x;
                vm.Filename = x.Filename;
                NavigateTo(vm);
            });

            GoToOwnerCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist.Owner).Select(x => x != null));
            GoToOwnerCommand
            .Select(_ => this.CreateViewModel <UserViewModel>())
            .Select(x => x.Init(Gist.Owner.Login))
            .Subscribe(NavigateTo);

            AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ =>
                                                                          NavigateTo(new ComposerViewModel("Add Comment", async x => {
                var request = sessionService.Client.Gists[Id].CreateGistComment(x);
                Comments.Add((await sessionService.Client.ExecuteAsync(request)).Data);
            }, alertDialogFactory)));

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Gist).Select(x => x != null),
                sender => {
                var menu = actionMenuService.Create();
                if (Gist.Owner != null && string.Equals(sessionService.Account.Username, Gist.Owner.Login, StringComparison.OrdinalIgnoreCase))
                {
                    menu.AddButton("Edit", GoToEditCommand);
                }
                else
                {
                    menu.AddButton("Fork", ForkCommand);
                }
                menu.AddButton("Share", ShareCommand);
                menu.AddButton("Show in GitHub", GoToHtmlUrlCommand);
                return(menu.Show(sender));
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(async _ => {
                sessionService.GitHubClient.Gist.IsStarred(Id).ToBackground(x => IsStarred = x);
                Comments.SimpleCollectionLoad(sessionService.Client.Gists[Id].GetComments());
                Gist = await sessionService.GitHubClient.Gist.Get(Id);
            });
        }
Exemple #7
0
        public IssueViewModel(IApplicationService applicationService, IShareService shareService)
        {
            _applicationService = applicationService;
            Comments            = new ReactiveList <IssueCommentModel>();
            Events = new ReactiveList <IssueEventModel>();
            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue).Select(x => x != null);

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            ShareCommand.Subscribe(_ => shareService.ShareUrl(Issue.HtmlUrl));

            AddCommentCommand = ReactiveCommand.Create();
            AddCommentCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel <CommentViewModel>();
                ReactiveUI.Legacy.ReactiveCommandMixins.RegisterAsyncTask(vm.SaveCommand, async t =>
                {
                    var issue   = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[IssueId];
                    var comment = await _applicationService.Client.ExecuteAsync(issue.CreateComment(vm.Comment));
                    Comments.Add(comment.Data);
                    vm.DismissCommand.ExecuteIfCan();
                });
                ShowViewModel(vm);
            });

            ToggleStateCommand = ReactiveCommand.CreateAsyncTask(issuePresenceObservable, async t =>
            {
                var close = string.Equals(Issue.State, "open", StringComparison.OrdinalIgnoreCase);
                try
                {
                    var issue = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[Issue.Number];
                    var data  = await _applicationService.Client.ExecuteAsync(issue.UpdateState(close ? "closed" : "open"));
                    Issue     = data.Data;
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to " + (close ? "close" : "open") + " the item. " + e.Message, e);
                }
            });

            GoToEditCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToEditCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id    = IssueId;
                vm.Issue = Issue;
                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                ShowViewModel(vm);
            });

            GoToAssigneeCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToAssigneeCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueAssignedToViewModel>();
                vm.SaveOnSelect    = true;
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.IssueId         = IssueId;
                vm.SelectedUser    = Issue.Assignee;
                vm.WhenAnyValue(x => x.SelectedUser).Subscribe(x =>
                {
                    Issue.Assignee = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToLabelsCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToLabelsCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueLabelsViewModel>();
                vm.SaveOnSelect    = true;
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.IssueId         = IssueId;
                vm.SelectedLabels.Reset(Issue.Labels);
                vm.WhenAnyValue(x => x.SelectedLabels).Subscribe(x =>
                {
                    Issue.Labels = x.ToList();
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToMilestoneCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToMilestoneCommand.Subscribe(_ =>
            {
                var vm               = CreateViewModel <IssueMilestonesViewModel>();
                vm.SaveOnSelect      = true;
                vm.RepositoryOwner   = RepositoryOwner;
                vm.RepositoryName    = RepositoryName;
                vm.IssueId           = IssueId;
                vm.SelectedMilestone = Issue.Milestone;
                vm.WhenAnyValue(x => x.SelectedMilestone).Subscribe(x =>
                {
                    Issue.Milestone = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(t =>
            {
                var forceCacheInvalidation = t as bool?;
                var issue = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[IssueId];
                var t1    = this.RequestModel(issue.Get(), forceCacheInvalidation, response => Issue = response.Data);
                Comments.SimpleCollectionLoad(issue.GetComments(), forceCacheInvalidation).FireAndForget();
                Events.SimpleCollectionLoad(issue.GetEvents(), forceCacheInvalidation).FireAndForget();
                return(t1);
            });
        }
        public PullRequestViewModel(IApplicationService applicationService, IMarkdownService markdownService, IShareService shareService)
        {
            _applicationService = applicationService;
            _markdownService    = markdownService;

            Comments = new ReactiveList <IssueCommentModel>();
            Events   = new ReactiveList <IssueEventModel>();

            MergeCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.PullRequest).Select(x =>
                                                             x != null && x.Merged.HasValue && !x.Merged.Value && x.Mergable.HasValue && x.Mergable.Value),
                async t =>
            {
                try
                {
                    var response = await _applicationService.Client.ExecuteAsync(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Merge());
                    if (!response.Data.Merged)
                    {
                        throw new Exception(response.Data.Message);
                    }
                    var pullRequest = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Get();
                    await this.RequestModel(pullRequest, true, r => PullRequest = r.Data);
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to Merge: " + e.Message, e);
                }
            });

            ToggleStateCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.PullRequest).Select(x => x != null), async t =>
            {
                var close = string.Equals(PullRequest.State, "open", StringComparison.OrdinalIgnoreCase);

                try
                {
                    var data = await _applicationService.Client.ExecuteAsync(
                        _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].UpdateState(close ? "closed" : "open"));
                    PullRequest = data.Data;
                }
                catch (Exception e)
                {
                    throw new Exception("Unable to " + (close ? "close" : "open") + " the item. " + e.Message, e);
                }
            });

            GoToCommitsCommand = ReactiveCommand.Create();
            GoToCommitsCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <PullRequestCommitsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.PullRequestId   = PullRequestId;
                ShowViewModel(vm);
            });

            GoToFilesCommand = ReactiveCommand.Create();
            GoToFilesCommand.Subscribe(_ =>
            {
                var vm           = CreateViewModel <PullRequestFilesViewModel>();
                vm.Username      = RepositoryOwner;
                vm.Repository    = RepositoryName;
                vm.PullRequestId = PullRequestId;
                ShowViewModel(vm);
            });

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.PullRequest).Select(x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            ShareCommand.Subscribe(_ => shareService.ShareUrl(PullRequest.HtmlUrl));

            GoToEditCommand = ReactiveCommand.Create();
            GoToEditCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id    = PullRequestId;
                vm.Issue = Issue;
                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                ShowViewModel(vm);
            });

            GoToLabelsCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            GoToLabelsCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueLabelsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.IssueId         = PullRequestId;
                vm.SaveOnSelect    = true;
                vm.SelectedLabels.Reset(Issue.Labels);
                vm.WhenAnyValue(x => x.Labels).Skip(1).Subscribe(x =>
                {
                    Issue.Labels = x.ToList();
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToMilestoneCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            GoToMilestoneCommand.Subscribe(_ =>
            {
                var vm               = CreateViewModel <IssueMilestonesViewModel>();
                vm.RepositoryOwner   = RepositoryOwner;
                vm.RepositoryName    = RepositoryName;
                vm.IssueId           = PullRequestId;
                vm.SaveOnSelect      = true;
                vm.SelectedMilestone = Issue.Milestone;
                vm.WhenAnyValue(x => x.SelectedMilestone).Skip(1).Subscribe(x =>
                {
                    Issue.Milestone = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToAssigneeCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            GoToAssigneeCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <IssueAssignedToViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.IssueId         = PullRequestId;
                vm.SaveOnSelect    = true;
                vm.SelectedUser    = Issue.Assignee;
                vm.WhenAnyValue(x => x.SelectedUser).Skip(1).Subscribe(x =>
                {
                    Issue.Assignee = x;
                    this.RaisePropertyChanged("Issue");
                });
                ShowViewModel(vm);
            });

            GoToAddCommentCommand = ReactiveCommand.Create();
            GoToAddCommentCommand.Subscribe(_ =>
            {
                var vm = CreateViewModel <CommentViewModel>();
                ReactiveUI.Legacy.ReactiveCommandMixins.RegisterAsyncTask(vm.SaveCommand, async t =>
                {
                    var req =
                        _applicationService.Client.Users[RepositoryOwner]
                        .Repositories[RepositoryName].Issues[PullRequestId].CreateComment(vm.Comment);
                    var comment = await _applicationService.Client.ExecuteAsync(req);
                    Comments.Add(comment.Data);
                    vm.DismissCommand.ExecuteIfCan();
                });
            });

            LoadCommand = ReactiveCommand.CreateAsyncTask(t =>
            {
                var forceCacheInvalidation = t as bool?;
                var pullRequest            = _applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].PullRequests[PullRequestId].Get();
                var t1 = this.RequestModel(pullRequest, forceCacheInvalidation, response => PullRequest = response.Data);
                Events.SimpleCollectionLoad(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].GetEvents(), forceCacheInvalidation).FireAndForget();
                Comments.SimpleCollectionLoad(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].GetComments(), forceCacheInvalidation).FireAndForget();
                this.RequestModel(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[PullRequestId].Get(), forceCacheInvalidation, response => Issue = response.Data).FireAndForget();
                return(t1);
            });
        }
Exemple #9
0
        public IssueViewModel(IApplicationService applicationService, IActionMenuFactory actionMenuFactory,
                              IMarkdownService markdownService, IGraphicService graphicsService)
        {
            _applicationService = applicationService;

            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue).Select(x => x != null);

            GoToAssigneesCommand = ReactiveCommand.Create(issuePresenceObservable)
                                   .WithSubscription(_ => Assignees.LoadCommand.ExecuteIfCan());

            GoToLabelsCommand = ReactiveCommand.Create(issuePresenceObservable)
                                .WithSubscription(_ => Labels.LoadCommand.ExecuteIfCan());

            GoToMilestonesCommand = ReactiveCommand.Create(issuePresenceObservable)
                                    .WithSubscription(_ => Milestones.LoadCommand.ExecuteIfCan());

            this.WhenAnyValue(x => x.Id)
            .Subscribe(x => Title = "Issue #" + x);

            _assignedUser = this.WhenAnyValue(x => x.Issue.Assignee)
                            .ToProperty(this, x => x.AssignedUser);

            _assignedMilestone = this.WhenAnyValue(x => x.Issue.Milestone)
                                 .ToProperty(this, x => x.AssignedMilestone);

            _assignedLabels = this.WhenAnyValue(x => x.Issue.Labels)
                              .ToProperty(this, x => x.AssignedLabels);

            _markdownDescription = this.WhenAnyValue(x => x.Issue)
                                   .Select(x => ((x == null || string.IsNullOrEmpty(x.Body)) ? null : markdownService.Convert(x.Body)))
                                   .ToProperty(this, x => x.MarkdownDescription);

            ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            ShareCommand.Subscribe(_ => actionMenuFactory.ShareUrl(Issue.HtmlUrl));

            var events = new ReactiveList <IIssueEventItemViewModel>();

            Events = events.CreateDerivedCollection(x => x);

            AddCommentCommand = ReactiveCommand.Create();
            AddCommentCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <IssueCommentViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
                vm.SaveCommand.Subscribe(x => events.Add(new IssueCommentItemViewModel(x)));
                NavigateTo(vm);
            });

            ToggleStateCommand = ReactiveCommand.CreateAsyncTask(issuePresenceObservable, async t =>
            {
                try
                {
                    Issue = await applicationService.GitHubClient.Issue.Update(RepositoryOwner, RepositoryName, Id, new Octokit.IssueUpdate {
                        State = (Issue.State == Octokit.ItemState.Open) ? Octokit.ItemState.Closed : Octokit.ItemState.Open
                    });
                }
                catch (Exception e)
                {
                    var close = (Issue.State == Octokit.ItemState.Open) ? "close" : "open";
                    throw new Exception("Unable to " + close + " the item. " + e.Message, e);
                }
            });

            GoToEditCommand = ReactiveCommand.Create(issuePresenceObservable);
            GoToEditCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id = Id;
//                vm.Issue = Issue;
//                vm.WhenAnyValue(x => x.Issue).Skip(1).Subscribe(x => Issue = x);
                NavigateTo(vm);
            });

            Assignees = new IssueAssigneeViewModel(
                () => applicationService.GitHubClient.Issue.Assignee.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue);

            Milestones = new IssueMilestonesViewModel(
                () => applicationService.GitHubClient.Issue.Milestone.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue);

            Labels = new IssueLabelsViewModel(
                () => applicationService.GitHubClient.Issue.Labels.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue),
                UpdateIssue,
                graphicsService);

            LoadCommand = ReactiveCommand.CreateAsyncTask(async t =>
            {
                var issueRequest = applicationService.GitHubClient.Issue.Get(RepositoryOwner, RepositoryName, Id)
                                   .ContinueWith(x => Issue = x.Result, new CancellationToken(), TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext());
                var eventsRequest   = applicationService.GitHubClient.Issue.Events.GetForIssue(RepositoryOwner, RepositoryName, Id);
                var commentsRequest = applicationService.GitHubClient.Issue.Comment.GetForIssue(RepositoryOwner, RepositoryName, Id);
                await Task.WhenAll(issueRequest, eventsRequest, commentsRequest);

                var tempList = new List <IIssueEventItemViewModel>(eventsRequest.Result.Count + commentsRequest.Result.Count);
                tempList.AddRange(eventsRequest.Result.Select(x => new IssueEventItemViewModel(x)));
                tempList.AddRange(commentsRequest.Result.Select(x => new IssueCommentItemViewModel(x)));
                events.Reset(tempList.OrderBy(x => x.CreatedAt));
            });

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Issue).Select(x => x != null),
                _ =>
            {
                var menu = actionMenuFactory.Create(Title);
                menu.AddButton(Issue.State == Octokit.ItemState.Open ? "Close" : "Open", ToggleStateCommand);
//
//
//                var editButton = _actionSheet.AddButton("Edit");
//                var commentButton = _actionSheet.AddButton("Comment");
//                var shareButton = _actionSheet.AddButton("Share");
//                var showButton = _actionSheet.AddButton("Show in GitHub");

                return(menu.Show());
            });
        }
Exemple #10
0
        public IssueViewModel(
            string username, string repository, int issueId,
            IApplicationService applicationService = null, IMarkdownService markdownService       = null,
            IMessageService messageService         = null, IAlertDialogService alertDialogService = null,
            IActionMenuService actionMenuService   = null)
        {
            _applicationService = applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>();
            messageService      = messageService ?? Locator.Current.GetService <IMessageService>();
            markdownService     = markdownService ?? Locator.Current.GetService <IMarkdownService>();
            alertDialogService  = alertDialogService ?? Locator.Current.GetService <IAlertDialogService>();
            actionMenuService   = actionMenuService ?? Locator.Current.GetService <IActionMenuService>();

            Title      = "Issue #" + issueId;
            Username   = username;
            Repository = repository;
            IssueId    = issueId;

            GoToWebCommand = ReactiveCommand.Create <string>(
                url => NavigateTo(new WebBrowserViewModel(url)));

            GoToReporterCommand = ReactiveCommand.Create(
                () => NavigateTo(new UserViewModel(Issue.ReportedBy.Username)),
                this.WhenAnyValue(x => x.Issue.ReportedBy.Username).Select(x => x != null));

            GoToAssigneeCommand = ReactiveCommand.Create(
                () => NavigateTo(new UserViewModel(Issue.Responsible.Username)),
                this.WhenAnyValue(x => x.Issue.Responsible.Username).Select(x => x != null));

            GoToEditCommand = ReactiveCommand.Create(
                () => NavigateTo(new IssueEditViewModel(username, repository, Issue)),
                this.WhenAnyValue(x => x.Issue).Select(x => x != null));

            this.WhenAnyValue(x => x.Issue)
            .Select(x => x?.Responsible?.Username ?? "Unassigned")
            .ToProperty(this, x => x.Assigned, out _assigned, "Unassigned");

            this.WhenAnyValue(x => x.Issue.Content)
            .Select(x => string.IsNullOrEmpty(x) ? null : markdownService.ConvertMarkdown(x))
            .ToProperty(this, x => x.Description, out _description);

            this.WhenAnyValue(x => x.Description)
            .Select(x => !string.IsNullOrEmpty(x))
            .ToProperty(this, x => x.ShowDescription, out _showDescription);

            Comments = _comments.CreateDerivedCollection(x =>
                                                         new CommentItemViewModel(x.AuthorInfo.Username,
                                                                                  new Utils.Avatar(x.AuthorInfo.Avatar),
                                                                                  x.UtcCreatedOn.Humanize(),
                                                                                  markdownService.ConvertMarkdown(x.Content)));

            LoadCommand = ReactiveCommand.CreateFromTask(async t => {
                var issueTask = applicationService.Client.Issues.Get(username, repository, issueId);
                applicationService.Client.Issues.GetComments(username, repository, issueId)
                .ToBackground(x => _comments.Reset(x.Where(y => !string.IsNullOrEmpty(y.Content))));
                Issue = await issueTask;
            });

            DeleteCommand = ReactiveCommand.CreateFromTask(async _ =>
            {
                try
                {
                    var prompt = await alertDialogService.PromptYesNo(
                        "Are you sure?", "You are about to permanently delete issue #" + Issue.LocalId + ".");

                    if (prompt)
                    {
                        await applicationService.Client.Issues.Delete(username, repository, Issue.LocalId);
                        messageService.Send(new IssueDeleteMessage(Issue));
                        DismissCommand.ExecuteNow();
                    }
                }
                catch (Exception e)
                {
                    this.Log().ErrorException("Error deleting issue", e);
                }
            });

            ShowMenuCommand = ReactiveCommand.CreateFromTask(sender =>
            {
                var menu = actionMenuService.Create();
                menu.AddButton("Edit", _ => GoToEditCommand.ExecuteNow());
                menu.AddButton("Delete", _ => DeleteCommand.ExecuteNow());
                return(menu.Show(sender));
            });

            _issueMessageBus = messageService.Listen <IssueUpdateMessage>(x =>
            {
                if (x.Issue.LocalId == issueId)
                {
                    Issue = x.Issue;
                }
            });
        }