public ReadmeViewModel(IApplicationService applicationService, IShareService shareService, IActionMenuService actionMenuService) { Title = "Readme"; var nonNullContentModel = this.WhenAnyValue(x => x.ContentModel).Select(x => x != null); ShareCommand = ReactiveCommand.Create(nonNullContentModel); ShareCommand.Subscribe(_ => shareService.ShareUrl(ContentModel.HtmlUrl)); GoToGitHubCommand = ReactiveCommand.Create(nonNullContentModel); GoToGitHubCommand.Select(_ => ContentModel.HtmlUrl).Subscribe(this.ShowWebBrowser); GoToLinkCommand = ReactiveCommand.Create(); GoToLinkCommand.OfType <string>().Subscribe(this.ShowWebBrowser); ShowMenuCommand = ReactiveCommand.CreateAsyncTask(nonNullContentModel, _ => { var menu = actionMenuService.Create(Title); menu.AddButton("Share", ShareCommand); menu.AddButton("Show in GitHub", GoToGitHubCommand); return(menu.Show()); }); LoadCommand = ReactiveCommand.CreateAsyncTask(async x => { var repository = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName]; ContentText = await repository.GetReadmeRendered(); ContentModel = (await applicationService.Client.ExecuteAsync(repository.GetReadme())).Data; }); }
public SourceViewModel( string username, string repository, string branch, string path, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); GoToHtmlUrlCommand = ReactiveCommand.Create( () => NavigateTo(new WebBrowserViewModel(HtmlUrl)), this.WhenAnyValue(x => x.HtmlUrl).Select(x => !string.IsNullOrEmpty(x))); //Create the filename var fileName = Path.GetFileName(path); if (fileName == null) { fileName = path.Substring(path.LastIndexOf('/') + 1); } //Create the temp file path Title = fileName; var extension = Path.GetExtension(path); IsMarkdown = MarkdownExtensions.Any(x => x == extension); var canExecute = this.WhenAnyValue(x => x.HtmlUrl).Select(x => x != null); var canOpen = this.WhenAnyValue(x => x.FilePath).Select(x => x != null); var canShow = Observable.CombineLatest(canExecute, canOpen, (x, y) => x && y); ShowMenuCommand = ReactiveCommand.CreateFromTask <object>(sender => { var menu = actionMenuService.Create(); menu.AddButton("Open In", x => actionMenuService.OpenIn(x, FilePath)); menu.AddButton("Share", x => actionMenuService.ShareUrl(x, HtmlUrl)); menu.AddButton("Show in Bitbucket", _ => GoToHtmlUrlCommand.ExecuteNow()); return(menu.Show(sender)); }, canShow); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { var filePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(fileName)); using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { await applicationService.Client.Repositories.GetRawFile(username, repository, branch, path, stream); } using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var buffer = new byte[1024]; var read = stream.Read(buffer, 0, 1024); IsText = !buffer.Take(read).Any(x => x == 0); } FilePath = filePath; HtmlUrl = $"https://bitbucket.org/{username}/{repository}/raw/{branch}/{path.TrimStart('/')}"; }); }
public ReleaseViewModel(IApplicationService applicationService, IShareService shareService, IUrlRouterService urlRouterService, IActionMenuService actionMenuService) { this.WhenAnyValue(x => x.ReleaseModel) .Select(x => x == null ? "Release" : x.Name).Subscribe(x => Title = x); ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null)); ShareCommand.Subscribe(_ => shareService.ShareUrl(ReleaseModel.HtmlUrl)); var gotoUrlCommand = this.CreateUrlCommand(); GoToGitHubCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null)); GoToGitHubCommand.Select(_ => ReleaseModel.HtmlUrl).Subscribe(gotoUrlCommand.ExecuteIfCan); GoToLinkCommand = ReactiveCommand.Create(); GoToLinkCommand.OfType <string>().Subscribe(x => { var handledViewModel = urlRouterService.Handle(x); if (handledViewModel != null && applicationService.Account.OpenUrlsInApp) { ShowViewModel(handledViewModel); } else { gotoUrlCommand.ExecuteIfCan(x); } }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.ReleaseModel).Select(x => x != null), _ => { var menu = actionMenuService.Create(Title); menu.AddButton("Share", ShowMenuCommand); menu.AddButton("Show in GitHub", GoToGitHubCommand); return(menu.Show()); }); _contentText = this.WhenAnyValue(x => x.ReleaseModel).IsNotNull() .Select(x => x.BodyHtml).ToProperty(this, x => x.ContentText); LoadCommand = ReactiveCommand.CreateAsyncTask(x => this.RequestModel(applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetRelease(ReleaseId), x as bool?, r => ReleaseModel = r.Data)); }
public ReadmeViewModel( string username, string repository, string filename, IApplicationService applicationService = null, IMarkdownService markdownService = null, IActionMenuService actionMenuService = null) { applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); markdownService = markdownService ?? Locator.Current.GetService <IMarkdownService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); var canShowMenu = this.WhenAnyValue(x => x.ContentModel).Select(x => x != null); ShowMenuCommand = ReactiveCommand.CreateFromTask(sender => { var menu = actionMenuService.Create(); menu.AddButton("Share", x => actionMenuService.ShareUrl(x, new Uri(_htmlUrl))); menu.AddButton("Show in Bitbucket", _ => NavigateTo(new WebBrowserViewModel(_htmlUrl))); return(menu.Show(sender)); }, canShowMenu); Title = "Readme"; LoadCommand = ReactiveCommand.CreateFromTask(async t => { var filepath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), filename); var mainBranch = (await applicationService.Client.Repositories.GetPrimaryBranch(username, repository)).Name; ContentModel = await applicationService.Client.Repositories.GetFile(username, repository, mainBranch, filename); var readme = ContentModel.Data; _htmlUrl = "http://bitbucket.org/" + username + "/" + repository + "/src/" + mainBranch + "/" + filename; if (filepath.EndsWith("textile", StringComparison.Ordinal)) { ContentText = markdownService.ConvertTextile(readme); } else { ContentText = markdownService.ConvertMarkdown(readme); } }); }
public PullRequestViewModel(IApplicationService applicationService, IMarkdownService markdownService, IActionMenuService actionMenuService) { _applicationService = applicationService; _markdownService = markdownService; GoToUrlCommand = this.CreateUrlCommand(); Comments = new ReactiveList <Octokit.IssueComment>(); Events = new ReactiveList <Octokit.IssueEvent>(); this.WhenAnyValue(x => x.Id).Subscribe(x => Title = "Pull Request #" + x); _canMerge = this.WhenAnyValue(x => x.PullRequest) .Select(x => x != null && !x.Merged) .ToProperty(this, x => x.CanMerge); var canMergeObservable = this.WhenAnyValue(x => x.PullRequest).Select(x => x != null && !x.Merged && x.Mergeable.HasValue && x.Mergeable.Value); MergeCommand = ReactiveCommand.CreateAsyncTask(canMergeObservable, async t => { var req = new Octokit.MergePullRequest(null); var response = await _applicationService.GitHubClient.PullRequest.Merge(RepositoryOwner, RepositoryName, Id, req); if (!response.Merged) { throw new Exception(string.Format("Unable to merge pull request: {0}", response.Message)); } LoadCommand.ExecuteIfCan(); }); ToggleStateCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.PullRequest).Select(x => x != null), async t => { var newState = PullRequest.State == Octokit.ItemState.Open ? Octokit.ItemState.Closed : Octokit.ItemState.Open; try { var req = new Octokit.PullRequestUpdate { State = newState }; PullRequest = await _applicationService.GitHubClient.PullRequest.Update(RepositoryOwner, RepositoryName, Id, req); } catch (Exception e) { throw new Exception("Unable to " + (newState == Octokit.ItemState.Closed ? "close" : "open") + " the item. " + e.Message, e); } }); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.PullRequest).Select(x => x != null)); GoToHtmlUrlCommand.Select(_ => PullRequest.HtmlUrl).Subscribe(this.ShowWebBrowser); GoToCommitsCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <PullRequestCommitsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.PullRequestId = Id; ShowViewModel(vm); }); GoToFilesCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <PullRequestFilesViewModel>(); vm.Username = RepositoryOwner; vm.Repository = RepositoryName; vm.PullRequestId = Id; ShowViewModel(vm); }); // // ShareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.PullRequest).Select(x => x != null && !string.IsNullOrEmpty(x.HtmlUrl))) // .WithSubscription(_ => shareService.ShareUrl(PullRequest.HtmlUrl)); GoToEditCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = 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); ShowViewModel(vm); }); GoToLabelsCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null)).WithSubscription(_ => { var vm = CreateViewModel <IssueLabelsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.IssueId = Id; 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)).WithSubscription(_ => { var vm = CreateViewModel <IssueMilestonesViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.IssueId = Id; 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)).WithSubscription(_ => { var vm = CreateViewModel <IssueAssignedToViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.IssueId = Id; 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().WithSubscription(_ => { var vm = CreateViewModel <IssueCommentViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.Id = Id; vm.CommentAdded.Subscribe(Comments.Add); ShowViewModel(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.PullRequest).Select(x => x != null), _ => { var menu = actionMenuService.Create(Title); menu.AddButton("Edit", GoToEditCommand); menu.AddButton(PullRequest.State == Octokit.ItemState.Closed ? "Open" : "Close", ToggleStateCommand); menu.AddButton("Comment", GoToAddCommentCommand); menu.AddButton("Share", ShareCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return(menu.Show()); }); _markdownDescription = this.WhenAnyValue(x => x.PullRequest).IsNotNull() .Select(x => _markdownService.Convert(x.Body)) .ToProperty(this, x => x.MarkdownDescription); LoadCommand = ReactiveCommand.CreateAsyncTask(async _ => { var pullRequest = _applicationService.GitHubClient.PullRequest.Get(RepositoryOwner, RepositoryName, Id); var comments = _applicationService.GitHubClient.PullRequest.Comment.GetAll(RepositoryOwner, RepositoryName, Id); var events = _applicationService.GitHubClient.Issue.Events.GetForIssue(RepositoryOwner, RepositoryName, Id); var issue = _applicationService.GitHubClient.Issue.Get(RepositoryOwner, RepositoryName, Id); await Task.WhenAll(pullRequest, issue, comments, events); PullRequest = pullRequest.Result; Issue = issue.Result; }); }
public RepositoryViewModel(IApplicationService applicationService, IAccountsService accountsService, IActionMenuService actionMenuService) { ApplicationService = applicationService; _accountsService = accountsService; this.WhenAnyValue(x => x.RepositoryName).Subscribe(x => Title = x); ToggleStarCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsStarred).Select(x => x.HasValue), t => ToggleStar()); ToggleWatchCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsWatched, x => x.HasValue), t => ToggleWatch()); GoToOwnerCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository).Select(x => x != null)); GoToOwnerCommand.Select(_ => Repository.Owner).Subscribe(x => { if (string.Equals(x.Type, "organization", StringComparison.OrdinalIgnoreCase)) { var vm = CreateViewModel <OrganizationViewModel>(); vm.Username = RepositoryOwner; ShowViewModel(vm); } else { var vm = CreateViewModel <UserViewModel>(); vm.Username = RepositoryOwner; ShowViewModel(vm); } }); PinCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository).Select(x => x != null)); PinCommand.Subscribe(x => PinRepository()); GoToForkParentCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && x.Fork && x.Parent != null)); GoToForkParentCommand.Subscribe(x => { var vm = CreateViewModel <RepositoryViewModel>(); vm.RepositoryOwner = Repository.Parent.Owner.Login; vm.RepositoryName = Repository.Parent.Name; vm.Repository = Repository.Parent; ShowViewModel(vm); }); GoToStargazersCommand = ReactiveCommand.Create(); GoToStargazersCommand.Subscribe(_ => { var vm = CreateViewModel <RepositoryStargazersViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToWatchersCommand = ReactiveCommand.Create(); GoToWatchersCommand.Subscribe(_ => { var vm = CreateViewModel <RepositoryWatchersViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToEventsCommand = ReactiveCommand.Create(); GoToEventsCommand.Subscribe(_ => { var vm = CreateViewModel <RepositoryEventsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToIssuesCommand = ReactiveCommand.Create(); GoToIssuesCommand.Subscribe(_ => { var vm = CreateViewModel <IssuesViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToReadmeCommand = ReactiveCommand.Create(); GoToReadmeCommand.Subscribe(_ => { var vm = CreateViewModel <ReadmeViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToBranchesCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <CommitBranchesViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToCommitsCommand = ReactiveCommand.Create(); GoToCommitsCommand.Subscribe(_ => { if (Branches != null && Branches.Count == 1) { var vm = CreateViewModel <ChangesetsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.Branch = Repository == null ? null : Repository.DefaultBranch; ShowViewModel(vm); } else { GoToBranchesCommand.ExecuteIfCan(); } }); GoToPullRequestsCommand = ReactiveCommand.Create(); GoToPullRequestsCommand.Subscribe(_ => { var vm = CreateViewModel <PullRequestsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToSourceCommand = ReactiveCommand.Create(); GoToSourceCommand.Subscribe(_ => { var vm = CreateViewModel <BranchesAndTagsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToContributors = ReactiveCommand.Create(); GoToContributors.Subscribe(_ => { var vm = CreateViewModel <RepositoryContributorsViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToForksCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <RepositoryForksViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToReleasesCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <ReleasesViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Repository, x => x.IsStarred, x => x.IsWatched) .Select(x => x.Item1 != null && x.Item2 != null && x.Item3 != null), _ => { var menu = actionMenuService.Create(Title); menu.AddButton(IsPinned ? "Unpin from Slideout Menu" : "Pin to Slideout Menu", PinCommand); menu.AddButton(IsStarred.Value ? "Unstar This Repo" : "Star This Repo", ToggleStarCommand); menu.AddButton(IsWatched.Value ? "Unwatch This Repo" : "Watch This Repo", ToggleWatchCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return(menu.Show()); }); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl))); GoToHtmlUrlCommand.Select(_ => Repository.HtmlUrl).Subscribe(this.ShowWebBrowser); GoToHomepageCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.Homepage))); GoToHomepageCommand.Select(_ => Repository.Homepage).Subscribe(this.ShowWebBrowser); LoadCommand = ReactiveCommand.CreateAsyncTask(t => { var forceCacheInvalidation = t as bool?; var t1 = this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Get(), forceCacheInvalidation, response => Repository = response.Data); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetReadme(), forceCacheInvalidation, response => Readme = response.Data).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetBranches(), forceCacheInvalidation, response => Branches = response.Data).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].IsWatching(), forceCacheInvalidation, response => IsWatched = response.Data).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].IsStarred(), forceCacheInvalidation, response => IsStarred = response.Data).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContributors(), forceCacheInvalidation, response => Contributors = response.Data.Count).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetLanguages(), forceCacheInvalidation, response => Languages = response.Data.Count).FireAndForget(); this.RequestModel(ApplicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetReleases(), forceCacheInvalidation, response => Releases = response.Data.Count).FireAndForget(); return(t1); }); }
public PullRequestViewModel( string username, string repository, int pullRequestId, IMarkdownService markdownService = null, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { _applicationService = applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); markdownService = markdownService ?? Locator.Current.GetService <IMarkdownService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); Title = $"Pull Request #{pullRequestId}"; Username = username; Repository = repository; PullRequestId = pullRequestId; Comments = _comments.CreateDerivedCollection(x => { var name = x.User.DisplayName ?? x.User.Username ?? "Unknown"; var avatar = new Avatar(x.User.Links?.Avatar?.Href); return(new CommentItemViewModel(name, avatar, x.CreatedOn.Humanize(), x.Content.Html)); }); Comments.Changed.Subscribe(_ => CommentCount = Comments.Count); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { PullRequest = await applicationService.Client.PullRequests.Get(username, repository, pullRequestId); _comments.Clear(); await applicationService .Client.ForAllItems( x => x.PullRequests.GetComments(username, repository, pullRequestId), y => { var items = y.Where(x => !string.IsNullOrEmpty(x.Content.Raw) && x.Inline == null) .OrderBy(x => (x.CreatedOn)); _comments.Reset(items); }); }); GoToCommitsCommand = ReactiveCommand.CreateFromTask(t => { if (PullRequest?.Source?.Repository == null) { throw new Exception("The author has deleted the source repository for this pull request."); } var viewModel = new PullRequestCommitsViewModel(username, repository, pullRequestId); NavigateTo(viewModel); return(Task.FromResult(Unit.Default)); }); var canMerge = this.WhenAnyValue(x => x.PullRequest) .Select(x => string.Equals(x?.State, "open", StringComparison.OrdinalIgnoreCase)); canMerge.ToProperty(this, x => x.IsOpen, out _open); MergeCommand = ReactiveCommand.Create(() => { }, canMerge); RejectCommand = ReactiveCommand.CreateFromTask( t => applicationService.Client.PullRequests.Decline(username, repository, pullRequestId), canMerge); RejectCommand.Subscribe(x => PullRequest = x); GoToUserCommand = ReactiveCommand.Create <string>(user => NavigateTo(new UserViewModel(user))); ToggleApproveButton = ReactiveCommand.CreateFromTask(async _ => { if (Approved) { await applicationService.Client.PullRequests.Unapprove(username, repository, pullRequestId); } else { await applicationService.Client.PullRequests.Approve(username, repository, pullRequestId); } PullRequest = await applicationService.Client.PullRequests.Get(username, repository, pullRequestId); }); //ToggleApproveButton.ThrownExceptions // .Subscribe(x => DisplayAlert("Unable to approve commit: " + x.Message).ToBackground()); var participantObs = this.WhenAnyValue(x => x.PullRequest.Participants) .Select(x => x ?? Enumerable.Empty <PullRequestParticipant>()); var currentUsername = applicationService.Account.Username; participantObs .Select(x => x.FirstOrDefault(y => string.Equals(y.User.Username, currentUsername, StringComparison.OrdinalIgnoreCase))?.Approved ?? false) .ToProperty(this, x => x.Approved, out _approved); participantObs .Select(x => new int?(x.Count())) .ToProperty(this, x => x.ParticipantCount, out _participants); participantObs .Select(x => new int?(x.Count(y => y.Approved))) .ToProperty(this, x => x.ApprovalCount, out _approvalCount); this.WhenAnyValue(x => x.PullRequest.Description) .Select(x => string.IsNullOrEmpty(x) ? null : markdownService.ConvertMarkdown(x)) .ToProperty(this, x => x.Description, out _description); this.WhenAnyValue(x => x.PullRequest.Participants) .Select(participants => { return((participants ?? Enumerable.Empty <PullRequestParticipant>()) .Where(x => x.Approved) .Select(x => { var avatar = new Avatar(x.User?.Links?.Avatar?.Href); var vm = new UserItemViewModel(x.User?.Username, x.User?.DisplayName, avatar); vm.GoToCommand .Select(_ => new UserViewModel(x.User)) .Subscribe(NavigateTo); return vm; })); }) .Select(x => x.ToArray()) .ToProperty(this, x => x.Approvals, out _approvals, new UserItemViewModel[0]); ShowMenuCommand = ReactiveCommand.CreateFromTask(sender => { var menu = actionMenuService.Create(); menu.AddButton("Show in Bitbucket", _ => { NavigateTo(new WebBrowserViewModel(PullRequest?.Links?.Html?.Href)); }); return(menu.Show(sender)); }); }
public WikiViewModel( string username, string repository, string page = null, IMarkdownService markdownService = null, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); markdownService = markdownService ?? Locator.Current.GetService <IMarkdownService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); page = page ?? "Home"; CanEdit = true; if (page.StartsWith("/", StringComparison.Ordinal)) { page = page.Substring(1); } Title = page; //GoToWebCommand = ReactiveCommand.Create<string>(path => //{ // var url = string.Format("https://bitbucket.org/{0}/{1}/wiki/{2}", username, repository, path); // NavigateTo(new WebBrowserViewModel(url)); //}); ShowMenuCommand = ReactiveCommand.CreateFromTask(sender => { var menu = actionMenuService.Create(); //menu.AddButton("Fork Repository", ForkCommand); menu.AddButton("Show in Bitbucket", _ => { var htmlUrl = $"https://bitbucket.org/{username.ToLower()}/{repository.ToLower()}/wiki/{page}"; NavigateTo(new WebBrowserViewModel(htmlUrl)); }); return(menu.Show(sender)); }); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { Wiki = await applicationService.Client.Repositories.GetWiki(username, repository, page); string content = string.Empty; if (string.Equals(Wiki.Markup, "markdown")) { content = markdownService.ConvertMarkdown(Wiki.Data); } else if (string.Equals(Wiki.Markup, "creole")) { content = markdownService.ConvertCreole(Wiki.Data); } else if (string.Equals(Wiki.Markup, "textile")) { content = markdownService.ConvertTextile(Wiki.Data); } else { content = Wiki.Data; } Content = content; }); GoToWebCommand = ReactiveCommand.Create <string>(uri => { if (Uri.TryCreate(uri, UriKind.Absolute, out Uri result)) { if (new [] { "http", "https" }.Contains(result.Scheme)) { NavigateTo(new WebBrowserViewModel(result.AbsoluteUri)); } else if (result.Scheme == "file") { page = result.AbsolutePath.Split('/').LastOrDefault(); LoadCommand.ExecuteNow(); } } }); }
public RepositoryViewModel( string username, string repositoryName, Repository repository = null, IApplicationService applicationService = null, IActionMenuService actionMenuService = null) { applicationService = _applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); Repository = repository; _branches.Changed .Select(_ => _branches.Count) .ToProperty(this, x => x.BranchesCount, out _branchesCount); this.WhenAnyValue(x => x.Repository.Name) .StartWith(repositoryName) .Subscribe(x => Title = x); LoadCommand = ReactiveCommand.CreateFromTask(async _ => { Repository = await applicationService.Client.Repositories.Get(username, repositoryName); _applicationService.Client.Repositories.GetWatchers(username, repositoryName) .ToBackground(x => Watchers = x.Size); _applicationService.Client.Repositories.GetForks(username, repositoryName) .ToBackground(x => Forks = x.Size); _applicationService.Client.Repositories.GetBranches(username, repositoryName) .ToBackground(x => _branches.Reset(x)); if (!Repository.HasIssues) { Issues = 0; } else { _applicationService.Client.Issues.GetAll(username, repositoryName, limit: 0) .ToBackground(x => Issues = x.Count); } LoadReadme(username, repositoryName).ToBackground(); }); ForkCommand = ReactiveCommand.CreateFromTask(async _ => { var fork = await applicationService.Client.Repositories.Fork(username, repositoryName); NavigateTo(new RepositoryViewModel(fork.Owner, fork.Slug)); }); var canGoToFork = this.WhenAnyValue(x => x.Repository) .Select(x => x?.Parent != null); GoToForkParentCommand = ReactiveCommand.Create(() => { var id = RepositoryIdentifier.FromFullName(Repository.Parent.FullName); NavigateTo(new RepositoryViewModel(id.Owner, id.Name)); }, canGoToFork); GoToReadmeCommand = ReactiveCommand.Create( () => NavigateTo(new ReadmeViewModel(username, repositoryName, _readmeFilename)), this.WhenAnyValue(x => x.HasReadme)); GoToPullRequestsCommand .Select(_ => new PullRequestsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToWikiCommand = ReactiveCommand.Create( () => NavigateTo(new WikiViewModel(username, repositoryName)), this.WhenAnyValue(x => x.Repository.HasWiki)); GoToSourceCommand .Select(_ => new BranchesAndTagsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToIssuesCommand .Select(_ => new IssuesViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToOwnerCommand .Select(_ => new UserViewModel(username)) .Subscribe(NavigateTo); GoToStargazersCommand .Select(_ => new RepositoryWatchersViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToEventsCommand .Select(_ => new RepositoryEventsViewModel(username, repositoryName)) .Subscribe(NavigateTo); GoToBranchesCommand .Select(_ => BranchesViewModel.ForSource(username, repositoryName)) .Subscribe(NavigateTo); var validWebsite = this.WhenAnyValue(x => x.Repository.Website) .Select(x => !string.IsNullOrEmpty(x)); GoToWebsiteCommand = ReactiveCommand.Create( () => NavigateTo(new WebBrowserViewModel(Repository.Website)), validWebsite); GoToCommitsCommand .Subscribe(_ => { if (_branches.Count == 1) { NavigateTo(new CommitsViewModel(username, repositoryName, _branches.FirstOrDefault()?.Node)); } else { NavigateTo(BranchesViewModel.ForCommits(username, repositoryName)); } }); ShowMenuCommand = ReactiveCommand.CreateFromTask(sender => { var menu = actionMenuService.Create(); var isPinned = applicationService .Account.PinnedRepositories .Any(x => string.Equals(x.Owner, username, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Slug, repositoryName, StringComparison.OrdinalIgnoreCase)); var pinned = isPinned ? "Unpin from Slideout Menu" : "Pin to Slideout Menu"; menu.AddButton(pinned, _ => PinRepository()); menu.AddButton("Fork Repository", _ => ForkCommand.ExecuteNow()); menu.AddButton("Show in Bitbucket", _ => { var htmlUrl = ("https://bitbucket.org/" + username + "/" + repositoryName).ToLower(); NavigateTo(new WebBrowserViewModel(htmlUrl)); }); return(menu.Show(sender)); }); }
public CommitViewModel( string username, string repository, string node, bool showRepository = false, IApplicationService applicationService = null, IActionMenuService actionMenuService = null, IAlertDialogService alertDialogService = null) { _applicationService = applicationService = applicationService ?? Locator.Current.GetService <IApplicationService>(); actionMenuService = actionMenuService ?? Locator.Current.GetService <IActionMenuService>(); alertDialogService = alertDialogService ?? Locator.Current.GetService <IAlertDialogService>(); Username = username; Repository = repository; Node = node; ShowRepository = showRepository; var shortNode = node.Substring(0, node.Length > 7 ? 7 : node.Length); Title = $"Commit {shortNode}"; var changesetFiles = this.WhenAnyValue(x => x.Changeset) .Where(x => x != null) .Select(x => x.Files ?? Enumerable.Empty <Client.V1.ChangesetFile>()); changesetFiles .Select(x => x.Count(y => y.Type == "added")) .ToProperty(this, x => x.DiffAdditions, out _diffAdditions); changesetFiles .Select(x => x.Count(y => y.Type == "removed")) .ToProperty(this, x => x.DiffDeletions, out _diffDeletions); changesetFiles .Select(x => x.Count(y => y.Type != "added" && y.Type != "removed")) .ToProperty(this, x => x.DiffModifications, out _diffModifications); Comments = _comments.CreateDerivedCollection(comment => { var name = comment.User.DisplayName ?? comment.User.Username; var avatar = new Avatar(comment.User.Links?.Avatar?.Href); return(new CommentItemViewModel(name, avatar, comment.CreatedOn.Humanize(), comment.Content.Raw)); }, x => x.Inline == null); GoToUserCommand = ReactiveCommand.Create <string>(user => NavigateTo(new UserViewModel(user))); GoToRepositoryCommand .Select(_ => new RepositoryViewModel(username, repository)) .Subscribe(NavigateTo); GoToAddedFiles = ReactiveCommand.Create( () => { }, this.WhenAnyValue(x => x.DiffAdditions).Select(x => x > 0)); GoToRemovedFiles = ReactiveCommand.Create( () => { }, this.WhenAnyValue(x => x.DiffDeletions).Select(x => x > 0)); GoToModifiedFiles = ReactiveCommand.Create( () => { }, this.WhenAnyValue(x => x.DiffModifications).Select(x => x > 0)); var canShowMenu = this.WhenAnyValue(x => x.Commit).Select(x => x != null); ShowMenuCommand = ReactiveCommand.Create <object>(sender => { var uri = new Uri($"https://bitbucket.org/{username}/{repository}/commits/{node}"); var menu = actionMenuService.Create(); menu.AddButton("Add Comment", _ => AddCommentCommand.ExecuteNow()); menu.AddButton("Copy SHA", _ => actionMenuService.SendToPasteBoard(node)); menu.AddButton("Share", x => actionMenuService.ShareUrl(x, uri)); menu.AddButton("Show In Bitbucket", _ => NavigateTo(new WebBrowserViewModel(uri.AbsoluteUri))); menu.Show(sender); }, canShowMenu); ToggleApproveButton = ReactiveCommand.CreateFromTask(async _ => { if (Approved) { await applicationService.Client.Commits.Unapprove(username, repository, node); } else { await applicationService.Client.Commits.Approve(username, repository, node); } var shouldBe = !Approved; var commit = await applicationService.Client.Commits.Get(username, repository, node); var currentUsername = applicationService.Account.Username; var me = commit.Participants.FirstOrDefault( y => string.Equals(currentUsername, y?.User?.Username, StringComparison.OrdinalIgnoreCase)); if (me != null) { me.Approved = shouldBe; } Commit = commit; }); ToggleApproveButton .ThrownExceptions .Subscribe(x => alertDialogService.Alert("Error", "Unable to approve commit: " + x.Message).ToBackground()); var commitFiles = new ReactiveList <Client.V1.ChangesetFile>(); CommitFiles = commitFiles.CreateDerivedCollection(x => { var vm = new CommitFileItemViewModel(username, repository, node, Changeset.Parents.FirstOrDefault(), x); vm.GoToCommand .Select(_ => new ChangesetDiffViewModel(username, repository, node, x)) .Subscribe(NavigateTo); return(vm); }); this.WhenAnyValue(x => x.Commit.Participants) .Select(participants => { return((participants ?? Enumerable.Empty <CommitParticipant>()) .Where(x => x.Approved) .Select(x => { var avatar = new Avatar(x.User?.Links?.Avatar?.Href); var vm = new UserItemViewModel(x.User?.Username, x.User?.DisplayName, avatar); vm.GoToCommand .Select(_ => new UserViewModel(x.User)) .Subscribe(NavigateTo); return vm; })); }) .Select(x => x.ToArray()) .ToProperty(this, x => x.Approvals, out _approvals, new UserItemViewModel[0]); this.WhenAnyValue(x => x.Changeset) .Subscribe(x => commitFiles.Reset(x?.Files ?? Enumerable.Empty <Client.V1.ChangesetFile>())); this.WhenAnyValue(x => x.Commit) .Subscribe(x => { var currentUsername = applicationService.Account.Username; Approved = x?.Participants ?.FirstOrDefault(y => string.Equals(currentUsername, y?.User?.Username, StringComparison.OrdinalIgnoreCase)) ?.Approved ?? false; }); LoadCommand = ReactiveCommand.CreateFromTask(_ => { var commit = applicationService.Client.Commits.Get(username, repository, node) .OnSuccess(x => Commit = x); var changeset = applicationService.Client.Commits.GetChangeset(username, repository, node) .OnSuccess(x => Changeset = x); applicationService.Client.AllItems(x => x.Commits.GetComments(username, repository, node)) .ToBackground(_comments.Reset); return(Task.WhenAll(commit, changeset)); }); }
public GistViewModel(IApplicationService applicationService, IShareService shareService, IActionMenuService actionMenuService, IStatusIndicatorService statusIndicatorService) { Comments = new ReactiveList <GistCommentModel>(); Title = "Gist"; GoToUrlCommand = this.CreateUrlCommand(); 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(_ => shareService.ShareUrl(Gist.HtmlUrl)); ToggleStarCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsStarred).Select(x => x.HasValue), async t => { try { if (!IsStarred.HasValue) { return; } var request = IsStarred.Value ? applicationService.Client.Gists[Id].Unstar() : applicationService.Client.Gists[Id].Star(); await applicationService.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 data = await applicationService.Client.ExecuteAsync(applicationService.Client.Gists[Id].ForkGist()); var forkedGist = data.Data; var vm = CreateViewModel <GistViewModel>(); vm.Id = forkedGist.Id; vm.Gist = forkedGist; ShowViewModel(vm); }); ForkCommand.IsExecuting.Subscribe(x => { if (x) { statusIndicatorService.Show("Forking..."); } else { statusIndicatorService.Hide(); } }); GoToEditCommand = ReactiveCommand.Create(); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null && !string.IsNullOrEmpty(x.HtmlUrl))); GoToHtmlUrlCommand.Select(_ => Gist.HtmlUrl).Subscribe(this.ShowWebBrowser); GoToFileSourceCommand = ReactiveCommand.Create(); GoToFileSourceCommand.OfType <GistFileModel>().Subscribe(x => { var vm = CreateViewModel <GistFileViewModel>(); vm.Id = Id; vm.GistFile = x; vm.Filename = x.Filename; ShowViewModel(vm); }); GoToUserCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Gist).Select(x => x != null && x.Owner != null)); GoToUserCommand.Subscribe(x => { var vm = CreateViewModel <UserViewModel>(); vm.Username = Gist.Owner.Login; ShowViewModel(vm); }); AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <GistCommentViewModel>(); vm.Id = Id; vm.CommentAdded.Subscribe(Comments.Add); ShowViewModel(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Gist).Select(x => x != null), _ => { var menu = actionMenuService.Create(Title); if (Gist.Owner != null && string.Equals(applicationService.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()); }); LoadCommand = ReactiveCommand.CreateAsyncTask(t => { var forceCacheInvalidation = t as bool?; var t1 = this.RequestModel(applicationService.Client.Gists[Id].Get(), forceCacheInvalidation, response => Gist = response.Data); this.RequestModel(applicationService.Client.Gists[Id].IsGistStarred(), forceCacheInvalidation, response => IsStarred = response.Data).FireAndForget(); Comments.SimpleCollectionLoad(applicationService.Client.Gists[Id].GetComments(), forceCacheInvalidation).FireAndForget(); return(t1); }); }
public LoginViewModel(ILoginService loginFactory, IAccountsService accountsService, IActionMenuService actionMenuService, IStatusIndicatorService statusIndicatorService, IAlertDialogService alertDialogService) { _loginFactory = loginFactory; Title = "Login"; GoToOldLoginWaysCommand = ReactiveCommand.Create(); GoToOldLoginWaysCommand.Subscribe(_ => ShowViewModel(CreateViewModel <AddAccountViewModel>())); var loginCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.Code).Select(x => !string.IsNullOrEmpty(x)), _ => Login(Code)); loginCommand.Subscribe(x => accountsService.ActiveAccount = x); loginCommand.Subscribe(x => MessageBus.Current.SendMessage(new LogoutMessage())); LoginCommand = loginCommand; ShowLoginOptionsCommand = ReactiveCommand.CreateAsyncTask(t => { var actionMenu = actionMenuService.Create(Title); actionMenu.AddButton("Login via BASIC", GoToOldLoginWaysCommand); return(actionMenu.Show()); }); LoginCommand.IsExecuting.Skip(1).Subscribe(x => { if (x) { statusIndicatorService.Show("Logging in..."); } else { statusIndicatorService.Hide(); } }); _loginUrl = this.WhenAnyValue(x => x.WebDomain) .IsNotNull() .Select(x => x.TrimEnd('/')) .Select(x => string.Format(x + "/login/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}", ClientId, Uri.EscapeDataString(RedirectUri), Uri.EscapeDataString("user,repo,notifications,gist"))) .ToProperty(this, x => x.LoginUrl); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { if (IsEnterprise && string.IsNullOrEmpty(WebDomain)) { var response = await alertDialogService.PromptTextBox("Enterprise URL", "Please enter the webpage address for the GitHub Enterprise installation", DefaultWebDomain, "Ok"); WebDomain = response; } else { WebDomain = DefaultWebDomain; } }); LoadCommand.ThrownExceptions.Take(1).Subscribe(x => DismissCommand.ExecuteIfCan()); }
public ChangesetViewModel(IApplicationService applicationService, IActionMenuService actionMenuService) { _applicationService = applicationService; Title = "Commit"; GoToUrlCommand = this.CreateUrlCommand(); Comments = new ReactiveList <CommentModel>(); var goToUrlCommand = this.CreateUrlCommand(); GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Commit).Select(x => x != null)); GoToHtmlUrlCommand.Select(x => Commit.HtmlUrl).Subscribe(goToUrlCommand.ExecuteIfCan); GoToRepositoryCommand = ReactiveCommand.Create(); GoToRepositoryCommand.Subscribe(_ => { var vm = CreateViewModel <RepositoryViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; ShowViewModel(vm); }); GoToCommentCommand = ReactiveCommand.Create().WithSubscription(_ => { var vm = CreateViewModel <CommitCommentViewModel>(); vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; vm.Node = Node; vm.CommentAdded.Subscribe(Comments.Add); ShowViewModel(vm); }); GoToFileCommand = ReactiveCommand.Create(); GoToFileCommand.OfType <CommitModel.CommitFileModel>().Subscribe(x => { if (x.Patch == null) { var vm = CreateViewModel <SourceViewModel>(); vm.Branch = Commit.Sha; vm.RepositoryOwner = RepositoryOwner; vm.RepositoryName = RepositoryName; // vm.Items = new [] // { // new SourceViewModel.SourceItemModel // { // ForceBinary = true, // GitUrl = x.BlobUrl, // Name = x.Filename, // Path = x.Filename, // HtmlUrl = x.BlobUrl // } // }; // vm.CurrentItemIndex = 0; ShowViewModel(vm); } else { var vm = CreateViewModel <ChangesetDiffViewModel>(); vm.Username = RepositoryOwner; vm.Repository = RepositoryName; vm.Branch = Commit.Sha; vm.Filename = x.Filename; ShowViewModel(vm); } }); var copyShaCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Commit).Select(x => x != null)) .WithSubscription(x => actionMenuService.SendToPasteBoard(this.Commit.Sha)); var shareCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Commit).Select(x => x != null)) .WithSubscription(x => actionMenuService.ShareUrl(this.Commit.HtmlUrl)); ShowMenuCommand = ReactiveCommand.CreateAsyncTask(_ => { var menu = actionMenuService.Create(Title); menu.AddButton("Add Comment", GoToCommentCommand); menu.AddButton("Copy SHA", copyShaCommand); menu.AddButton("Share", shareCommand); menu.AddButton("Show in GitHub", GoToHtmlUrlCommand); return(menu.Show()); }); LoadCommand = ReactiveCommand.CreateAsyncTask(t => { var forceCacheInvalidation = t as bool?; var t1 = this.RequestModel(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Commits[Node].Get(), forceCacheInvalidation, response => Commit = response.Data); Comments.SimpleCollectionLoad(_applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Commits[Node].Comments.GetAll(), forceCacheInvalidation).FireAndForget(); return(t1); }); }
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; } }); }
public GistFileViewModel(IAccountsService accounts, IApplicationService applicationService, IFilesystemService filesystemService, IShareService shareService, IActionMenuService actionMenuService) : base(accounts) { this.WhenAnyValue(x => x.Filename).Subscribe(x => { Title = x == null ? "Gist" : x.Substring(x.LastIndexOf('/') + 1); }); GoToUrlCommand = this.CreateUrlCommand(); OpenWithCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SourceItem).Select(x => x != null)); _isMarkdown = this.WhenAnyValue(x => x.GistFile).IsNotNull().Select(x => string.Equals(x.Language, MarkdownLanguage, StringComparison.OrdinalIgnoreCase)).ToProperty(this, x => x.IsMarkdown); ShowThemePickerCommand = ReactiveCommand.CreateAsyncTask(async _ => { var path = System.IO.Path.Combine("WebResources", "styles"); if (!System.IO.Directory.Exists(path)) { return; } var themes = System.IO.Directory.GetFiles(path) .Where(x => x.EndsWith(".css", StringComparison.Ordinal)) .Select(x => System.IO.Path.GetFileNameWithoutExtension(x)) .ToList(); var picker = actionMenuService.CreatePicker(); themes.ForEach(picker.Options.Add); picker.SelectedOption = themes.IndexOf(Theme ?? "idea"); var selected = await picker.Show(); if (selected >= 0 && selected <= themes.Count) { Theme = themes[selected]; } }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.SourceItem).Select(x => x != null), _ => { var menu = actionMenuService.Create(Title); menu.AddButton("Open With", OpenWithCommand); if (!IsMarkdown) { menu.AddButton("Change Theme", ShowThemePickerCommand); } return(menu.Show()); }); LoadCommand = ReactiveCommand.CreateAsyncTask(async t => { if (GistFile == null) { var data = await applicationService.Client.ExecuteAsync(applicationService.Client.Gists[_id].Get()); GistFile = data.Data.Files[_filename]; } //Check to make sure... if (GistFile == null || GistFile.Content == null) { throw new Exception("Unable to retreive gist!"); } var content = GistFile.Content; if (MarkdownLanguage.Equals(GistFile.Language, StringComparison.OrdinalIgnoreCase)) { content = await applicationService.Client.Markdown.GetMarkdown(content); } var gistFileName = System.IO.Path.GetFileName(GistFile.Filename); string filePath; using (var stream = filesystemService.CreateTempFile(out filePath, gistFileName)) { using (var fs = new System.IO.StreamWriter(stream)) { fs.Write(content); } } var fileUri = new Uri(filePath); SourceItem = new FileSourceItemViewModel(fileUri, false); }); }
public UserViewModel(IApplicationService applicationService, IActionMenuService actionMenuService) { _applicationService = applicationService; ToggleFollowingCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsFollowing).Select(x => x.HasValue), t => ToggleFollowing()); GoToGistsCommand = ReactiveCommand.Create(); GoToGistsCommand.Subscribe(_ => { var vm = CreateViewModel <UserGistsViewModel>(); vm.Username = Username; ShowViewModel(vm); }); GoToRepositoriesCommand = ReactiveCommand.Create(); GoToRepositoriesCommand.Subscribe(_ => { var vm = CreateViewModel <UserRepositoriesViewModel>(); vm.Username = Username; ShowViewModel(vm); }); GoToOrganizationsCommand = ReactiveCommand.Create(); GoToOrganizationsCommand.Subscribe(_ => { var vm = CreateViewModel <OrganizationsViewModel>(); vm.Username = Username; ShowViewModel(vm); }); GoToEventsCommand = ReactiveCommand.Create(); GoToEventsCommand.Subscribe(_ => { var vm = CreateViewModel <UserEventsViewModel>(); vm.Username = Username; ShowViewModel(vm); }); GoToFollowingCommand = ReactiveCommand.Create(); GoToFollowingCommand.Subscribe(_ => { var vm = CreateViewModel <UserFollowingsViewModel>(); vm.Username = Username; ShowViewModel(vm); }); GoToFollowersCommand = ReactiveCommand.Create(); GoToFollowersCommand.Subscribe(_ => { var vm = CreateViewModel <UserFollowersViewModel>(); vm.Username = Username; ShowViewModel(vm); }); ShowMenuCommand = ReactiveCommand.CreateAsyncTask( this.WhenAnyValue(x => x.IsFollowing).Select(x => x.HasValue), _ => { var menu = actionMenuService.Create(Title); menu.AddButton(IsFollowing.Value ? "Unfollow" : "Follow", ToggleFollowingCommand); return(menu.Show()); }); LoadCommand = ReactiveCommand.CreateAsyncTask(t => { this.RequestModel(applicationService.Client.AuthenticatedUser.IsFollowing(Username), t as bool?, x => IsFollowing = x.Data).FireAndForget(); return(this.RequestModel(applicationService.Client.Users[Username].Get(), t as bool?, response => User = response.Data)); }); }