예제 #1
0
        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));
            });
        }
예제 #2
0
        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);
            });
        }