diff options
author | Kohei Yoshino <kohei.yoshino@gmail.com> | 2018-06-26 22:50:45 +0200 |
---|---|---|
committer | Dylan William Hardison <dylan@hardison.net> | 2018-06-26 22:50:45 +0200 |
commit | a685e15218fbe7d26015a579c96caf7de783732d (patch) | |
tree | ac5f9157392181648ef995c182efbee3c0d2fe28 /extensions/BugModal/web | |
parent | 02e46829b2ddd0f6109c7d81cf40c1865b01a122 (diff) | |
download | bugzilla-a685e15218fbe7d26015a579c96caf7de783732d.tar.gz bugzilla-a685e15218fbe7d26015a579c96caf7de783732d.tar.xz |
Bug 1469023 - Show "new changes since (datetime)" indicator that links to unread changes/comments
Diffstat (limited to 'extensions/BugModal/web')
-rw-r--r-- | extensions/BugModal/web/bug_modal.css | 37 | ||||
-rw-r--r-- | extensions/BugModal/web/bug_modal.js | 87 |
2 files changed, 124 insertions, 0 deletions
diff --git a/extensions/BugModal/web/bug_modal.css b/extensions/BugModal/web/bug_modal.css index eeba78d74..9a3978b14 100644 --- a/extensions/BugModal/web/bug_modal.css +++ b/extensions/BugModal/web/bug_modal.css @@ -532,6 +532,43 @@ td.flag-requestee { text-align: right; } +.new-changes-link { + margin: 8px 0; + border-radius: 4px; + padding: 4px; + font-size: 12px; + text-align: center; + color: #FFF; + background: #277AC1; + cursor: pointer; +} + +.new-changes-separator { + position: relative; + margin: 16px -8px; + height: 0; + border-top: 1px solid #C00; + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; +} + +.new-changes-separator span { + display: inline-block; + position: absolute; + top: -10px; + right: 16px; + border: 1px solid #CCC; + border-radius: 4px; + padding: 0 4px; + height: 16px; + font-size: 10px; + line-height: 16px; + text-transform: uppercase; + color: #C00; + background-color: #FFF; +} + .change-set { clear: both; -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); diff --git a/extensions/BugModal/web/bug_modal.js b/extensions/BugModal/web/bug_modal.js index 300ebd3ae..ef015d3f9 100644 --- a/extensions/BugModal/web/bug_modal.js +++ b/extensions/BugModal/web/bug_modal.js @@ -1346,6 +1346,93 @@ function confirmUnsafeURL(url) { 'The full URL is:\n\n' + url + '\n\nContinue?'); } +function show_new_changes_indicator() { + const url = `rest/bug_user_last_visit/${BUGZILLA.bug_id}`; + + // Get the last visited timestamp + bugzilla_ajax({ url }, data => { + // Save the current timestamp + bugzilla_ajax({ url, type: 'POST' }); + + if (!data[0] || !data[0].last_visit_ts) { + return; + } + + const last_visit_ts = new Date(data[0].last_visit_ts); + const new_changes = [...document.querySelectorAll('main .change-set')].filter($change => { + // Exclude hidden CC changes + return $change.clientHeight > 0 && + new Date($change.querySelector('[data-time]').getAttribute('data-time') * 1000) > last_visit_ts; + }); + + if (new_changes.length === 0) { + return; + } + + const now = new Date(); + const date_locale = document.querySelector('html').lang; + const date_options = { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + hour12: false, + timeZone: BUGZILLA.user.timezone, + timeZoneName: 'short', + }; + + if (last_visit_ts.getFullYear() === now.getFullYear()) { + delete date_options.year; + + if (last_visit_ts.getMonth() === now.getMonth() && last_visit_ts.getDate() === now.getDate()) { + delete date_options.month; + delete date_options.day; + } + } + + const $link = document.createElement('div'); + const $separator = document.createElement('div'); + const comments_count = new_changes.filter($change => !!$change.querySelector('.comment')).length; + const changes_count = new_changes.length - comments_count; + const date_attr = last_visit_ts.toISOString(); + const date_label = last_visit_ts.toLocaleString(date_locale, date_options); + + // Insert a link + $link.className = 'new-changes-link'; + $link.innerHTML = + (c => c === 0 ? '' : (c === 1 ? `${c} new comment` : `${c} new comments`))(comments_count) + + (comments_count > 0 && changes_count > 0 ? ', ' : '') + + (c => c === 0 ? '' : (c === 1 ? `${c} new change` : `${c} new changes`))(changes_count) + + ` since <time datetime="${date_attr}">${date_label}</time>`; + $link.addEventListener('click', () => { + $link.remove(); + scroll_element_into_view($separator); + }, { once: true }); + document.querySelector('#changeform').insertAdjacentElement('beforebegin', $link); + + // Insert a separator + $separator.className = 'new-changes-separator'; + $separator.innerHTML = '<span>New</span>'; + new_changes[0].insertAdjacentElement('beforebegin', $separator); + + // Remove the link once the separator goes into the viewport + if ('IntersectionObserver' in window) { + const observer = new IntersectionObserver(entries => entries.forEach(entry => { + if (entry.intersectionRatio > 0) { + observer.unobserve($separator); + $link.remove(); + } + }), { root: $separator.offsetParent }); + + observer.observe($separator); + } + + // TODO: Enable auto-scroll once the modal page layout is optimized + // scroll_element_into_view($separator); + }); +} + // fix url after bug creation/update if (history && history.replaceState) { let bug_id = BUGZILLA.bug_id; |