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); }); }
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(); }
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); }); }
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()); }); }
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); }); }
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); }); }
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); }); }
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()); }); }