/// <summary>
        /// Initializes a new instance of the <see cref="InlineCommentThreadViewModel"/> class.
        /// </summary>
        /// <param name="session">The current PR review session.</param>
        /// <param name="file">The file being commented on.</param>
        /// <param name="lineNumber">The 0-based line number in the file.</param>
        /// <param name="leftComparisonBuffer">
        /// True if the comment is being left on the left-hand-side of a diff; otherwise false.
        /// </param>
        public NewInlineCommentThreadViewModel(
            IPullRequestSession session,
            IPullRequestSessionFile file,
            int lineNumber,
            bool leftComparisonBuffer)
            : base(session.User)
        {
            Guard.ArgumentNotNull(session, nameof(session));
            Guard.ArgumentNotNull(file, nameof(file));

            Session              = session;
            File                 = file;
            LineNumber           = lineNumber;
            LeftComparisonBuffer = leftComparisonBuffer;

            PostComment = ReactiveCommand.CreateAsyncTask(
                this.WhenAnyValue(x => x.NeedsPush, x => !x),
                DoPostComment);

            var placeholder = CommentViewModel.CreatePlaceholder(this, CurrentUser);

            placeholder.BeginEdit.Execute(null);
            this.WhenAnyValue(x => x.NeedsPush).Subscribe(x => placeholder.IsReadOnly = x);
            Comments.Add(placeholder);

            file.WhenAnyValue(x => x.CommitSha).Subscribe(x => NeedsPush = x == null);
        }
        public async Task Initialize()
        {
            var buffer = peekSession.TextView.TextBuffer;
            var info   = sessionManager.GetTextBufferInfo(buffer);

            if (info != null)
            {
                relativePath = info.RelativePath;
                leftBuffer   = info.IsLeftComparisonBuffer;
                file         = await info.Session.GetFile(relativePath);

                session = info.Session;
                await UpdateThread();
            }
            else
            {
                relativePath = sessionManager.GetRelativePath(buffer);
                file         = await sessionManager.GetLiveFile(relativePath, peekSession.TextView, buffer);
                await SessionChanged(sessionManager.CurrentSession);

                sessionSubscription = sessionManager.WhenAnyValue(x => x.CurrentSession)
                                      .Skip(1)
                                      .Subscribe(x => SessionChanged(x).Forget());
            }

            fileSubscription = file.WhenAnyValue(x => x.InlineCommentThreads).Subscribe(_ => UpdateThread().Forget());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="InlineCommentThreadViewModel"/> class.
        /// </summary>
        /// <param name="commentService">The comment service</param>
        /// <param name="session">The current PR review session.</param>
        /// <param name="file">The file being commented on.</param>
        /// <param name="lineNumber">The 0-based line number in the file.</param>
        /// <param name="leftComparisonBuffer">
        ///     True if the comment is being left on the left-hand-side of a diff; otherwise false.
        /// </param>
        public NewInlineCommentThreadViewModel(ICommentService commentService,
                                               IPullRequestSession session,
                                               IPullRequestSessionFile file,
                                               int lineNumber,
                                               bool leftComparisonBuffer)
            : base(session.User)
        {
            Guard.ArgumentNotNull(session, nameof(session));
            Guard.ArgumentNotNull(file, nameof(file));

            Session              = session;
            File                 = file;
            LineNumber           = lineNumber;
            LeftComparisonBuffer = leftComparisonBuffer;

            PostComment = ReactiveCommand.CreateFromTask <string>(
                DoPostComment,
                this.WhenAnyValue(x => x.NeedsPush, x => !x));

            EditComment   = ReactiveCommand.Create <Tuple <string, string> >(_ => { });
            DeleteComment = ReactiveCommand.Create <Tuple <int, int> >(_ => { });

            var placeholder = PullRequestReviewCommentViewModel.CreatePlaceholder(session, commentService, this, CurrentUser);

            placeholder.BeginEdit.Execute().Subscribe();
            this.WhenAnyValue(x => x.NeedsPush).Subscribe(x => placeholder.IsReadOnly = x);
            Comments.Add(placeholder);

            file.WhenAnyValue(x => x.CommitSha).Subscribe(x => NeedsPush = x == null);
        }
        async Task SessionChanged(IPullRequestSession session)
        {
            sessionSubscription?.Dispose();
            this.session = session;

            if (file != null)
            {
                file = null;
                NotifyTagsChanged();
            }

            if (session == null)
            {
                return;
            }

            relativePath = session.GetRelativePath(fullPath);

            if (relativePath == null)
            {
                return;
            }

            var snapshot = buffer.CurrentSnapshot;

            if (leftHandSide)
            {
                // If we're tagging the LHS of a diff, then the snapshot will be the base commit
                // (as you'd expect) but that means that the diff will be empty, so get the RHS
                // snapshot from the view for the comparison.
                var projection = view.TextSnapshot as IProjectionSnapshot;
                snapshot = projection?.SourceSnapshots.Count == 2 ? projection.SourceSnapshots[1] : null;
            }

            if (snapshot == null)
            {
                return;
            }

            var repository      = gitService.GetRepository(session.LocalRepository.LocalPath);
            var isContentSource = !leftHandSide && !(buffer is IProjectionBuffer);

            file = await session.GetFile(relativePath, isContentSource?this : null);

            if (file == null)
            {
                return;
            }

            sessionSubscription = file.WhenAnyValue(x => x.InlineCommentThreads)
                                  .Subscribe(_ => NotifyTagsChanged());

            NotifyTagsChanged();
        }
        async Task SessionChanged(IPullRequestSession session)
        {
            this.session = session;
            fileSubscription?.Dispose();

            if (session == null)
            {
                Thread = null;
                threadSubscription?.Dispose();
                return;
            }

            var relativePath = session.GetRelativePath(fullPath);

            file = await session.GetFile(relativePath);

            fileSubscription = file.WhenAnyValue(x => x.InlineCommentThreads).Subscribe(_ => UpdateThread().Forget());
        }