diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py +++ b/rhodecode/controllers/changeset.py @@ -198,6 +198,10 @@ class ChangesetController(BaseRepoContro c.lines_added = 0 c.lines_deleted = 0 + # auto collapse if we have more than limit + collapse_limit = diffs.DiffProcessor._collapse_commits_over + c.collapse_all_commits = len(c.commit_ranges) > collapse_limit + c.commit_statuses = ChangesetStatus.STATUSES c.inline_comments = [] c.files = [] diff --git a/rhodecode/controllers/compare.py b/rhodecode/controllers/compare.py --- a/rhodecode/controllers/compare.py +++ b/rhodecode/controllers/compare.py @@ -79,6 +79,7 @@ class CompareController(BaseRepoControll def index(self, repo_name): c.compare_home = True c.commit_ranges = [] + c.collapse_all_commits = False c.diffset = None c.limited_diff = False source_repo = c.rhodecode_db_repo.repo_name @@ -209,6 +210,10 @@ class CompareController(BaseRepoControll c.statuses = c.rhodecode_db_repo.statuses( [x.raw_id for x in c.commit_ranges]) + # auto collapse if we have more than limit + collapse_limit = diffs.DiffProcessor._collapse_commits_over + c.collapse_all_commits = len(c.commit_ranges) > collapse_limit + if partial: # for PR ajax commits loader if not c.ancestor: return '' # cannot merge if there is no ancestor diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py --- a/rhodecode/controllers/pullrequests.py +++ b/rhodecode/controllers/pullrequests.py @@ -26,7 +26,7 @@ import types import peppercorn import formencode import logging - +import collections from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest from pylons import request, tmpl_context as c, url @@ -45,7 +45,6 @@ from rhodecode.lib.auth import ( LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, HasAcceptedRepoType, XHRRequired) from rhodecode.lib.channelstream import channelstream_request -from rhodecode.lib.compat import OrderedDict from rhodecode.lib.utils import jsonify from rhodecode.lib.utils2 import ( safe_int, safe_str, str2bool, safe_unicode) @@ -70,7 +69,7 @@ class PullrequestsController(BaseRepoCon def __before__(self): super(PullrequestsController, self).__before__() - def _load_compare_data(self, pull_request, inline_comments, enable_comments=True): + def _load_compare_data(self, pull_request, inline_comments): """ Load context data needed for generating compare diff @@ -123,6 +122,10 @@ class PullrequestsController(BaseRepoCon except RepositoryRequirementError: c.missing_requirements = True + # auto collapse if we have more than limit + collapse_limit = diffs.DiffProcessor._collapse_commits_over + c.collapse_all_commits = len(c.commit_ranges) > collapse_limit + c.changes = {} c.missing_commits = False if (c.missing_requirements or @@ -135,13 +138,24 @@ class PullrequestsController(BaseRepoCon diff_processor = diffs.DiffProcessor( vcs_diff, format='newdiff', diff_limit=diff_limit, file_limit=file_limit, show_full_diff=c.fulldiff) - _parsed = diff_processor.prepare() - commit_changes = OrderedDict() _parsed = diff_processor.prepare() c.limited_diff = isinstance(_parsed, diffs.LimitedDiffContainer) - _parsed = diff_processor.prepare() + included_files = {} + for f in _parsed: + included_files[f['filename']] = f['stats'] + + c.deleted_files = [fname for fname in inline_comments if + fname not in included_files] + + c.deleted_files_comments = collections.defaultdict(dict) + for fname, per_line_comments in inline_comments.items(): + if fname in c.deleted_files: + c.deleted_files_comments[fname]['stats'] = 0 + c.deleted_files_comments[fname]['comments'] = list() + for lno, comments in per_line_comments.items(): + c.deleted_files_comments[fname]['comments'].extend(comments) def _node_getter(commit): def get_node(fname): @@ -159,14 +173,6 @@ class PullrequestsController(BaseRepoCon comments=inline_comments ).render_patchset(_parsed, target_commit.raw_id, source_commit.raw_id) - c.included_files = [] - c.deleted_files = [] - - for f in _parsed: - st = f['stats'] - fid = h.FID('', f['filename']) - c.included_files.append(f['filename']) - def _extract_ordering(self, request): column_index = safe_int(request.GET.get('order[0][column]')) order_dir = request.GET.get('order[0][dir]', 'desc') @@ -802,36 +808,47 @@ class PullrequestsController(BaseRepoCon c.pr_merge_status = False # inline comments - c.inline_comments = cc_model.get_inline_comments( - c.rhodecode_db_repo.repo_id, - pull_request=pull_request_id) + inline_comments = cc_model.get_inline_comments( + c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) + + _inline_cnt, c.inline_versions = cc_model.get_inline_comments_count( + inline_comments, version=at_version, include_aggregates=True) + + c.at_version_num = at_version if at_version and at_version != 'latest' else None + is_outdated = lambda co: \ + not c.at_version_num \ + or co.pull_request_version_id <= c.at_version_num - c.inline_cnt = cc_model.get_inline_comments_count( - c.inline_comments, version=at_version) - - # load compare data into template context - enable_comments = not pr_closed - self._load_compare_data( - pull_request_at_ver, - c.inline_comments, enable_comments=enable_comments) + # inline_comments_until_version + if c.at_version_num: + # if we use version, then do not show later comments + # than current version + paths = collections.defaultdict(lambda: collections.defaultdict(list)) + for fname, per_line_comments in inline_comments.iteritems(): + for lno, comments in per_line_comments.iteritems(): + for co in comments: + if co.pull_request_version_id and is_outdated(co): + paths[co.f_path][co.line_no].append(co) + inline_comments = paths # outdated comments - c.outdated_comments = {} c.outdated_cnt = 0 - if ChangesetCommentsModel.use_outdated_comments(pull_request_latest): - c.outdated_comments = cc_model.get_outdated_comments( + outdated_comments = cc_model.get_outdated_comments( c.rhodecode_db_repo.repo_id, pull_request=pull_request_at_ver) # Count outdated comments and check for deleted files - for file_name, lines in c.outdated_comments.iteritems(): + is_outdated = lambda co: \ + not c.at_version_num \ + or co.pull_request_version_id < c.at_version_num + for file_name, lines in outdated_comments.iteritems(): for comments in lines.values(): - comments = [comm for comm in comments - if comm.outdated_at_version(at_version)] + comments = [comm for comm in comments if is_outdated(comm)] c.outdated_cnt += len(comments) - if file_name not in c.included_files: - c.deleted_files.append(file_name) + + # load compare data into template context + self._load_compare_data(pull_request_at_ver, inline_comments) # this is a hack to properly display links, when creating PR, the # compare view and others uses different notation, and @@ -839,9 +856,9 @@ class PullrequestsController(BaseRepoCon # We need to swap that here to generate it properly on the html side c.target_repo = c.source_repo - # comments - c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id, - pull_request=pull_request_id) + # general comments + c.comments = cc_model.get_comments( + c.rhodecode_db_repo.repo_id, pull_request=pull_request_id) if c.allowed_to_update: force_close = ('forced_closed', _('Close Pull Request')) @@ -859,7 +876,7 @@ class PullrequestsController(BaseRepoCon c.changes = None c.file_changes = None - c.show_version_changes = 1 + c.show_version_changes = 1 # control flag, not used yet if at_version and c.show_version_changes: c.changes, c.file_changes = self._get_pr_version_changes( diff --git a/rhodecode/lib/diffs.py b/rhodecode/lib/diffs.py --- a/rhodecode/lib/diffs.py +++ b/rhodecode/lib/diffs.py @@ -203,6 +203,9 @@ class DiffProcessor(object): # used for inline highlighter word split _token_re = re.compile(r'()(>|<|&|\W+?)') + # collapse ranges of commits over given number + _collapse_commits_over = 5 + def __init__(self, diff, format='gitdiff', diff_limit=None, file_limit=None, show_full_diff=True): """ diff --git a/rhodecode/model/comment.py b/rhodecode/model/comment.py --- a/rhodecode/model/comment.py +++ b/rhodecode/model/comment.py @@ -355,13 +355,18 @@ class ChangesetCommentsModel(BaseModel): return self._group_comments_by_path_and_line_number(q) def get_inline_comments_count(self, inline_comments, skip_outdated=True, - version=None): + version=None, include_aggregates=False): + version_aggregates = collections.defaultdict(list) inline_cnt = 0 for fname, per_line_comments in inline_comments.iteritems(): for lno, comments in per_line_comments.iteritems(): - inline_cnt += len( - [comm for comm in comments - if (not comm.outdated_at_version(version) and skip_outdated)]) + for comm in comments: + version_aggregates[comm.pull_request_version_id].append(comm) + if not comm.outdated_at_version(version) and skip_outdated: + inline_cnt += 1 + + if include_aggregates: + return inline_cnt, version_aggregates return inline_cnt def get_outdated_comments(self, repo_id, pull_request): diff --git a/rhodecode/public/css/code-block.less b/rhodecode/public/css/code-block.less --- a/rhodecode/public/css/code-block.less +++ b/rhodecode/public/css/code-block.less @@ -658,24 +658,30 @@ input.filediff-collapse-state { display: none } .filediff-collapse-indicator { - border-width: 9px 0 9px 15.6px; - border-color: transparent transparent transparent #ccc; + width: 0; + height: 0; + border-style: solid; + border-width: 6.5px 0 6.5px 11.3px; + border-color: transparent transparent transparent #ccc; } .filediff-menu { display: none; } - margin: -1px 0 0 0; + margin: 10px 0 0 0; } &+ .filediff { /* file diff is expanded */ .filediff-collapse-indicator { - border-width: 15.6px 9px 0 9px; + width: 0; + height: 0; + border-style: solid; + border-width: 11.3px 6.5px 0 6.5px; border-color: #ccc transparent transparent transparent; } .filediff-menu { display: block; } - margin: 20px 0; + margin: 10px 0; &:nth-child(2) { margin: 0; } @@ -775,11 +781,9 @@ input.filediff-collapse-state { } .filediff-collapse-indicator { - width: 0; - height: 0; border-style: solid; float: left; - margin: 2px 2px 0 0; + margin: 4px 0px 0 0; cursor: pointer; } @@ -800,11 +804,12 @@ input.filediff-collapse-state { .filediff-menu { float: right; + text-align: right; + padding: 5px 5px 5px 0px; - &> a, &> span { - padding: 5px; - display: block; - float: left + &> a, + &> span { + padding: 1px; } } @@ -962,6 +967,13 @@ input.filediff-collapse-state { } +.filediff-outdated { + padding: 8px 0; + + .filediff-heading { + opacity: .5; + } +} table.cb { width: 100%; @@ -1068,8 +1080,8 @@ table.cb { &> button.cb-comment-box-opener { - padding: 2px 5px 1px 5px; - margin-left: 0px; + padding: 2px 2px 1px 3px; + margin-left: -6px; margin-top: -1px; border-radius: @border-radius; diff --git a/rhodecode/public/css/main.less b/rhodecode/public/css/main.less --- a/rhodecode/public/css/main.less +++ b/rhodecode/public/css/main.less @@ -110,7 +110,7 @@ ul.simple-list{ } .wide-mode-wrapper { - max-width:2400px !important; + max-width:4000px !important; } .wrapper { @@ -1623,6 +1623,12 @@ BIN_FILENODE = 7 .pull-request-merge span { margin-right: 10px; } + +.pr-versions { + position: relative; + top: 6px; +} + #close_pull_request { margin-right: 0px; } diff --git a/rhodecode/public/css/tables.less b/rhodecode/public/css/tables.less --- a/rhodecode/public/css/tables.less +++ b/rhodecode/public/css/tables.less @@ -445,6 +445,15 @@ table.compare_view_commits { padding-left: .5em; } + // special case to not show hover actions on hidden indicator + tr.compare_select_hidden:hover { + cursor: inherit; + + td { + background-color: inherit; + } + } + tr:hover { cursor: pointer; @@ -452,6 +461,8 @@ table.compare_view_commits { background-color: lighten(@alert4,25%); } } + + } .file_history { diff --git a/rhodecode/public/js/src/rhodecode/comments.js b/rhodecode/public/js/src/rhodecode/comments.js --- a/rhodecode/public/js/src/rhodecode/comments.js +++ b/rhodecode/public/js/src/rhodecode/comments.js @@ -411,23 +411,26 @@ var CommentsController = function() { /* return $node.closest('td').attr('data-line-number'); }; - this.scrollToComment = function(node, offset) { + this.scrollToComment = function(node, offset, outdated) { + var outdated = outdated || false; + var klass = outdated ? 'div.comment-outdated' : 'div.comment-current'; + if (!node) { node = $('.comment-selected'); if (!node.length) { node = $('comment-current') } } - $comment = $(node).closest('.comment-current'); - $comments = $('.comment-current'); + $comment = $(node).closest(klass); + $comments = $(klass); $('.comment-selected').removeClass('comment-selected'); - var nextIdx = $('.comment-current').index($comment) + offset; + var nextIdx = $(klass).index($comment) + offset; if (nextIdx >= $comments.length) { nextIdx = 0; } - var $next = $('.comment-current').eq(nextIdx); + var $next = $(klass).eq(nextIdx); var $cb = $next.closest('.cb'); $cb.removeClass('cb-collapsed'); @@ -446,6 +449,14 @@ var CommentsController = function() { /* return self.scrollToComment(node, -1); }; + this.nextOutdatedComment = function(node) { + return self.scrollToComment(node, 1, true); + }; + + this.prevOutdatedComment = function(node) { + return self.scrollToComment(node, -1, true); + }; + this.deleteComment = function(node) { if (!confirm(_gettext('Delete this comment?'))) { return false; diff --git a/rhodecode/templates/changelog/changelog.html b/rhodecode/templates/changelog/changelog.html --- a/rhodecode/templates/changelog/changelog.html +++ b/rhodecode/templates/changelog/changelog.html @@ -139,7 +139,7 @@
${len(c.inline_versions[None])}
% endif${c.pull_request_latest.source_ref_parts.commit_id[:6]}
${len(c.inline_versions[ver_pr])}
% endifversion ${ver.pull_request_version_id}
version ${ver_pr}
+${ver.source_ref_parts.commit_id[:6]}