Esempio n. 1
0
        public RepositoryViewModel(ISessionService applicationService,
                                   IAccountsRepository accountsService, IActionMenuFactory actionMenuService)
        {
            ApplicationService = applicationService;
            _accountsService   = accountsService;

            var validRepositoryObservable = this.WhenAnyValue(x => x.Repository).Select(x => x != null);

            this.WhenAnyValue(x => x.RepositoryName).Subscribe(x => Title = x);

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

            this.WhenAnyValue(x => x.Repository).Subscribe(x =>
            {
                Stargazers = (int?)x?.StargazersCount;
                Watchers   = (int?)x?.SubscribersCount;
            });

            this.WhenAnyValue(x => x.Repository.Description)
            .Select(x => Emojis.FindAndReplace(x))
            .ToProperty(this, x => x.Description, out _description);

            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 (AccountType.Organization.Equals(x.Type))
                {
                    var vm = this.CreateViewModel <OrganizationViewModel>();
                    vm.Init(RepositoryOwner);
                    NavigateTo(vm);
                }
                else
                {
                    var vm = this.CreateViewModel <UserViewModel>();
                    vm.Init(RepositoryOwner);
                    NavigateTo(vm);
                }
            });

            PinCommand = ReactiveCommand.Create(validRepositoryObservable);
            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             = this.CreateViewModel <RepositoryViewModel>();
                vm.RepositoryOwner = Repository.Parent.Owner.Login;
                vm.RepositoryName  = Repository.Parent.Name;
                vm.Repository      = Repository.Parent;
                NavigateTo(vm);
            });

            GoToStargazersCommand = ReactiveCommand.Create();
            GoToStargazersCommand.Subscribe(_ =>
            {
                var vm = this.CreateViewModel <RepositoryStargazersViewModel>();
                vm.Init(RepositoryOwner, RepositoryName);
                NavigateTo(vm);
            });

            GoToWatchersCommand = ReactiveCommand.Create();
            GoToWatchersCommand.Subscribe(_ =>
            {
                var vm = this.CreateViewModel <RepositoryWatchersViewModel>();
                vm.Init(RepositoryOwner, RepositoryName);
                NavigateTo(vm);
            });

            GoToEventsCommand = ReactiveCommand.Create();
            GoToEventsCommand.Subscribe(_ => {
                var vm = this.CreateViewModel <RepositoryEventsViewModel>();
                vm.Init(RepositoryOwner, RepositoryName);
                NavigateTo(vm);
            });

            GoToIssuesCommand = ReactiveCommand.Create();
            GoToIssuesCommand
            .Select(_ => this.CreateViewModel <IssuesViewModel>())
            .Select(x => x.Init(RepositoryOwner, RepositoryName))
            .Subscribe(NavigateTo);

            GoToReadmeCommand = ReactiveCommand.Create();
            GoToReadmeCommand
            .Select(_ => this.CreateViewModel <ReadmeViewModel>())
            .Select(x => x.Init(RepositoryOwner, RepositoryName))
            .Subscribe(NavigateTo);

            GoToBranchesCommand = ReactiveCommand.Create();
            GoToBranchesCommand
            .Select(_ => this.CreateViewModel <CommitBranchesViewModel>())
            .Select(x => x.Init(RepositoryOwner, RepositoryName))
            .Subscribe(NavigateTo);

            GoToCommitsCommand = ReactiveCommand.Create();
            GoToCommitsCommand.Subscribe(_ =>
            {
                if (Branches != null && Branches.Count == 1)
                {
                    var vm     = this.CreateViewModel <CommitsViewModel>();
                    var branch = Repository == null ? null : Repository.DefaultBranch;
                    NavigateTo(vm.Init(RepositoryOwner, RepositoryName, branch));
                }
                else
                {
                    GoToBranchesCommand.ExecuteIfCan();
                }
            });

            GoToPullRequestsCommand = ReactiveCommand.Create();
            GoToPullRequestsCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <PullRequestsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                NavigateTo(vm);
            });

            GoToSourceCommand = ReactiveCommand.Create();
            GoToSourceCommand.Subscribe(_ =>
            {
                var vm             = this.CreateViewModel <BranchesAndTagsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                NavigateTo(vm);
            });

            GoToContributors = ReactiveCommand.Create();
            GoToContributors.Subscribe(_ =>
            {
                var vm = this.CreateViewModel <RepositoryContributorsViewModel>();
                vm.Init(RepositoryOwner, RepositoryName);
                NavigateTo(vm);
            });

            GoToForksCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <RepositoryForksViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                NavigateTo(vm);
            });

            GoToReleasesCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm             = this.CreateViewModel <ReleasesViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                NavigateTo(vm);
            });

            ShareCommand = ReactiveCommand.Create(validRepositoryObservable);
            ShareCommand.Subscribe(sender => actionMenuService.ShareUrl(sender, Repository.HtmlUrl));

            var canShowMenu = this.WhenAnyValue(x => x.Repository, x => x.IsStarred, x => x.IsWatched)
                              .Select(x => x.Item1 != null && x.Item2 != null && x.Item3 != null);

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(canShowMenu, sender => {
                var menu = actionMenuService.Create();
                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);
                menu.AddButton("Share", ShareCommand);
                return(menu.Show(sender));
            });

            var gotoWebUrl = new Action <string>(x =>
            {
                var vm = this.CreateViewModel <WebBrowserViewModel>();
                vm.Init(x);
                NavigateTo(vm);
            });

            GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            GoToHtmlUrlCommand.Select(_ => Repository.HtmlUrl).Subscribe(gotoWebUrl);

            GoToHomepageCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.Homepage)));
            GoToHomepageCommand.Select(_ => Repository.Homepage).Subscribe(gotoWebUrl);

            LoadCommand = ReactiveCommand.CreateAsyncTask(async _ => {
                var t1 = applicationService.GitHubClient.Repository.Get(RepositoryOwner, RepositoryName);

                applicationService.GitHubClient.Repository.Content.GetReadme(RepositoryOwner, RepositoryName)
                .ToBackground(x => Readme = x);

                applicationService.GitHubClient.Repository.GetAllBranches(RepositoryOwner, RepositoryName)
                .ToBackground(x => Branches = x);

                applicationService.GitHubClient.Activity.Watching.CheckWatched(RepositoryOwner, RepositoryName)
                .ToBackground(x => IsWatched = x);

                applicationService.GitHubClient.Activity.Starring.CheckStarred(RepositoryOwner, RepositoryName)
                .ToBackground(x => IsStarred = x);

                applicationService.Client.ExecuteAsync(applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetContributors())
                .ToBackground(x => Contributors = x.Data.Count);

//                applicationService.GitHubClient.Repository.GetAllLanguages(RepositoryOwner, RepositoryName)
//                    .ToBackground(x => Languages = x.Count);

                applicationService.Client.ExecuteAsync(applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].GetReleases())
                .ToBackground(x => Releases = x.Data.Count);

                Repository = await t1;
            });
        }
Esempio n. 2
0
        protected BaseIssueViewModel(
            IApplicationService applicationService,
            IMarkdownService markdownService)
        {
            _applicationService = applicationService;

            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue, x => x.CanModify)
                                          .Select(x => x.Item1 != null && x.Item2);

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

            _participants = Events.Changed
                            .Select(_ => Events.Select(y => y.Actor).Distinct().Count())
                            .Select(x => x == 0 ? 1 : x)
                            .ToProperty(this, x => x.Participants);

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

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

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

            _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);

            _isClosed = this.WhenAnyValue(x => x.Issue.State)
                        .Select(x => x == Octokit.ItemState.Closed)
                        .ToProperty(this, x => x.IsClosed);

            Assignees = new IssueAssigneeViewModel(
                () => applicationService.GitHubClient.Issue.Assignee.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue.Assignee),
                x => UpdateIssue(new Octokit.IssueUpdate
            {
                Assignee  = x.With(y => y.Login),
                Milestone = AssignedMilestone.With(y => (int?)y.Number)
            }));

            Milestones = new IssueMilestonesViewModel(
                () => applicationService.GitHubClient.Issue.Milestone.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult(Issue.Milestone),
                x => UpdateIssue(new Octokit.IssueUpdate
            {
                Assignee  = AssignedUser.With(y => y.Login),
                Milestone = x.With(y => (int?)y.Number)
            }));

            Labels = new IssueLabelsViewModel(
                () => applicationService.GitHubClient.Issue.Labels.GetForRepository(RepositoryOwner, RepositoryName),
                () => Task.FromResult((IReadOnlyList <Octokit.Label>) new ReadOnlyCollection <Octokit.Label>(Issue.Labels.ToList())),
                x =>
            {
                var update = new Octokit.IssueUpdate
                {
                    Assignee  = AssignedUser.With(y => y.Login),
                    Milestone = AssignedMilestone.With(y => (int?)y.Number),
                };

                foreach (var label in x.Select(y => y.Name))
                {
                    update.AddLabel(label);
                }
                return(UpdateIssue(update));
            });

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

            LoadCommand = ReactiveCommand.CreateAsyncTask(t => Load(applicationService));

            GoToOwnerCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Issue).Select(x => x != null));
            GoToOwnerCommand.Select(_ => Issue.User).Subscribe(x =>
            {
                var vm      = this.CreateViewModel <UserViewModel>();
                vm.Username = x.Login;
                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);
                }
            });

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


            GoToUrlCommand = ReactiveCommand.Create();
            GoToUrlCommand.OfType <string>().Subscribe(x =>
            {
                var vm = this.CreateViewModel <WebBrowserViewModel>();
                vm.Url = x;
                NavigateTo(vm);
            });
            GoToUrlCommand.OfType <Uri>().Subscribe(x =>
            {
                var vm = this.CreateViewModel <WebBrowserViewModel>();
                vm.Url = x.AbsoluteUri;
                NavigateTo(vm);
            });
        }
Esempio n. 3
0
        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);
            });
        }
Esempio n. 4
0
        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));
            });
        }
Esempio n. 5
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);
            });
        }
Esempio n. 6
0
        public GistViewModel(IApplicationService applicationService,
                             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(_ => actionMenuService.ShareUrl(new Uri(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         = this.CreateViewModel <GistViewModel>();
                vm.Id          = forkedGist.Id;
                vm.Gist        = forkedGist;
                NavigateTo(vm);
            });

            ForkCommand.IsExecuting.Subscribe(x =>
            {
                if (x)
                {
                    alertDialogFactory.Show("Forking...");
                }
                else
                {
                    alertDialogFactory.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(x =>
            {
                var vm = this.CreateViewModel <WebBrowserViewModel>();
                vm.Url = x;
                NavigateTo(vm);
            });

            GoToFileSourceCommand = ReactiveCommand.Create();
            GoToFileSourceCommand.OfType <GistFileModel>().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).Select(x => x != null && x.Owner != null));
            GoToOwnerCommand.Subscribe(x =>
            {
                var vm      = this.CreateViewModel <UserViewModel>();
                vm.Username = Gist.Owner.Login;
                NavigateTo(vm);
            });

            AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ =>
            {
                var vm = this.CreateViewModel <GistCommentViewModel>();
                vm.Id  = Id;
                vm.SaveCommand.Subscribe(Comments.Add);
                NavigateTo(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);
                Comments.SimpleCollectionLoad(applicationService.Client.Gists[Id].GetComments(), forceCacheInvalidation);
                return(t1);
            });
        }
Esempio n. 7
0
        public RepositoryViewModel(IApplicationService applicationService, IAccountsService accountsService)
        {
            ApplicationService = applicationService;
            _accountsService   = accountsService;

            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();
            GoToOwnerCommand.Subscribe(_ =>
            {
                var vm      = CreateViewModel <ProfileViewModel>();
                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);
            });

            GoToCommitsCommand = ReactiveCommand.Create();
            GoToCommitsCommand.Subscribe(_ =>
            {
                if (Branches != null && Branches.Count == 1)
                {
                    var vm             = CreateViewModel <ChangesetsViewModel>();
                    vm.RepositoryOwner = RepositoryOwner;
                    vm.RepositoryName  = RepositoryName;
                    ShowViewModel(vm);
                }
                else
                {
                    var vm             = CreateViewModel <ChangesetBranchesViewModel>();
                    vm.RepositoryOwner = RepositoryOwner;
                    vm.RepositoryName  = RepositoryName;
                    ShowViewModel(vm);
                }
            });

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

            GoToCollaboratorsCommand = ReactiveCommand.Create();
            GoToCollaboratorsCommand.Subscribe(_ =>
            {
                var vm             = CreateViewModel <RepositoryCollaboratorsViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                ShowViewModel(vm);
            });

            this.WhenAnyValue(x => x.Repository).Subscribe(x =>
            {
                if (x == null)
                {
                    RepositorySize = null;
                }
                else
                {
                    if (x.Size / 1024f < 1)
                    {
                        RepositorySize = string.Format("{0:0.##}KB", x.Size);
                    }
                    else if ((x.Size / 1024f / 1024f) < 1)
                    {
                        RepositorySize = string.Format("{0:0.##}MB", x.Size / 1024f);
                    }
                    else
                    {
                        RepositorySize = string.Format("{0:0.##}GB", x.Size / 1024f / 1024f);
                    }
                }
            });

            GoToHtmlUrlCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.Repository, x => x != null && !string.IsNullOrEmpty(x.HtmlUrl)));
            GoToHtmlUrlCommand.Subscribe(_ => GoToUrlCommand.ExecuteIfCan(Repository.HtmlUrl));

            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].GetCollaborators(),
                                  forceCacheInvalidation, response => Collaborators = response.Data.Count).FireAndForget();

                return(t1);
            });
        }
Esempio n. 8
0
        protected BaseIssueViewModel(
            ISessionService applicationService,
            IMarkdownService markdownService,
            IActionMenuFactory actionMenuFactory,
            IAlertDialogFactory alertDialogFactory)
        {
            _applicationService = applicationService;
            _markdownService    = markdownService;
            _alertDialogFactory = alertDialogFactory;

            _assigneesCache = new Lazy <Task <IReadOnlyList <Octokit.User> > >(() =>
                                                                               _applicationService.GitHubClient.Issue.Assignee.GetAllForRepository(RepositoryOwner, RepositoryName));
            _milestonesCache = new Lazy <Task <IReadOnlyList <Octokit.Milestone> > >(() =>
                                                                                     _applicationService.GitHubClient.Issue.Milestone.GetAllForRepository(RepositoryOwner, RepositoryName));
            _labelsCache = new Lazy <Task <IReadOnlyList <Octokit.Label> > >(() =>
                                                                             _applicationService.GitHubClient.Issue.Labels.GetAllForRepository(RepositoryOwner, RepositoryName));

            IssueUpdated.Subscribe(x => Issue = x);

            _avatar = this.WhenAnyValue(x => x.Issue.User.AvatarUrl)
                      .Select(x => new GitHubAvatar(x))
                      .ToProperty(this, x => x.Avatar);

            var issuePresenceObservable = this.WhenAnyValue(x => x.Issue, x => x.CanModify)
                                          .Select(x => x.Item1 != null && x.Item2);

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

            this.WhenAnyValue(x => x.Issue.Comments)
            .ToProperty(this, x => x.CommentCount, out _commentsCount);

            _participants = Events.Changed
                            .Select(_ => Events.Select(y => y.Actor).Distinct().Count())
                            .Select(x => x == 0 ? 1 : x)
                            .ToProperty(this, x => x.Participants);

            GoToAssigneesCommand  = ReactiveCommand.Create(issuePresenceObservable);
            GoToLabelsCommand     = ReactiveCommand.Create(issuePresenceObservable);
            GoToMilestonesCommand = ReactiveCommand.Create(issuePresenceObservable);

            _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);

            _isClosed = this.WhenAnyValue(x => x.Issue.State)
                        .Select(x => x == Octokit.ItemState.Closed)
                        .ToProperty(this, x => x.IsClosed);

            _markdownDescription = this.WhenAnyValue(x => x.Issue)
                                   .Select(x => ((x == null || string.IsNullOrEmpty(x.Body)) ? null : x.Body))
                                   .Where(x => x != null)
                                   .Select(x => GetMarkdownDescription().ToObservable())
                                   .Switch()
                                   .ToProperty(this, x => x.MarkdownDescription, null, RxApp.MainThreadScheduler);

            LoadCommand = ReactiveCommand.CreateAsyncTask(t => Load(applicationService));

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

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

                RetrieveEvents().ToBackground(x => InternalEvents.Reset(x));
            });

            AddCommentCommand = ReactiveCommand.Create().WithSubscription(_ => {
                var vm = new ComposerViewModel(async s => {
                    var request = applicationService.Client.Users[RepositoryOwner].Repositories[RepositoryName].Issues[Id].CreateComment(s);
                    var comment = (await applicationService.Client.ExecuteAsync(request)).Data;
                    InternalEvents.Add(new IssueCommentItemViewModel(comment));
                    _commentAddedSubject.OnNext(comment);
                }, alertDialogFactory);
                NavigateTo(vm);
            });

            ShowMenuCommand = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.Issue).Select(x => x != null),
                sender => {
                var menu = actionMenuFactory.Create();
                menu.AddButton("Edit", GoToEditCommand);
                menu.AddButton(Issue.State == Octokit.ItemState.Closed ? "Open" : "Close", ToggleStateCommand);
                menu.AddButton("Comment", AddCommentCommand);
                menu.AddButton("Share", ShareCommand);
                menu.AddButton("Show in GitHub", GoToHtmlUrlCommand);
                return(menu.Show(sender));
            });

            GoToEditCommand = ReactiveCommand.Create().WithSubscription(_ => {
                var vm             = this.CreateViewModel <IssueEditViewModel>();
                vm.RepositoryOwner = RepositoryOwner;
                vm.RepositoryName  = RepositoryName;
                vm.Id    = Id;
                vm.Issue = Issue;
                vm.SaveCommand.Subscribe(_issueUpdatedObservable.OnNext);
                NavigateTo(vm);
            });

            GoToUrlCommand = ReactiveCommand.Create();
            GoToUrlCommand.OfType <string>().Subscribe(GoToUrl);
            GoToUrlCommand.OfType <Uri>().Subscribe(x => GoToUrl(x.AbsoluteUri));

            var hasHtmlObservable = this.WhenAnyValue(x => x.HtmlUrl).Select(x => x != null);

            ShareCommand = ReactiveCommand.Create(hasHtmlObservable);
            ShareCommand.Subscribe(sender => actionMenuFactory.ShareUrl(sender, HtmlUrl));

            GoToHtmlUrlCommand = ReactiveCommand.Create(hasHtmlObservable);
            GoToHtmlUrlCommand.Subscribe(_ => GoToUrl(HtmlUrl.AbsoluteUri));
        }