// ==UserScript== // @name Github Notifications Dropdown // @namespace joeytwiddle // @author joeytwiddle // @contributors SkyzohKey, Marti, darkred // @copyright 2014-2022, Paul "Joey" Clark (http://neuralyte.org/~joey) // @version 1.3.1 // @license MIT // @description When clicking the notifications icon, displays notifications in a dropdown pane, without leaving the current page. // @include https://github.com/* // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js // @grant GM_addStyle // @downloadURL none // ==/UserScript== /* eslint-env jquery */ // bug: If the notifications list is longer than the page, scroll down to the bottom and then try to click on the white space below the Github document's content. The event does not fire there! // When using @grant none then we should also avoid messing with the page's jQuery (if it has one) this.$ = this.jQuery = jQuery.noConflict(true); // ==Options== var makeBlocksCollapsableOnNotificationsPage = true; // Disabled by default because it was conflicting with other scripts (https://github.com/joeytwiddle/code/issues/2) var makeAllFileAndDiffBlocksCollapsable = false; // If you want to change the colour of the blue notification dot, uncomment one of the following var notificationDotStyle = ''; // Github's blue dot (2017) //var notificationDotStyle = 'linear-gradient(hsl(212, 100%, 66%), hsl(212, 100%, 46%))'; // Github's blue dot (2016) //var notificationDotStyle = 'linear-gradient(hsl(214, 50%, 65%), hsl(214, 50%, 50%))'; // Strong red dot //var notificationDotStyle = 'linear-gradient(hsla(0, 80%, 75%, 1), hsla(0, 80%, 50%, 1))'; // Calm amber dot //var notificationDotStyle = 'linear-gradient(hsla(35, 90%, 65%, 1), hsla(35, 90%, 40%, 1))'; // Gentle green dot //var notificationDotStyle = 'linear-gradient(hsla(120, 50%, 65%, 1), hsla(120, 50%, 40%, 1))'; var hideQuodAIWarning = true; // ==/Options== var mainNotificationsPath = '/notifications'; var notificationButtonLink = $('header a.notification-indicator[href]'); // In v1, the click listener was on the containing
  • so we had to listen there //var notificationButtonContainer = notificationButtonLink.closest("li"); // In v2, the listener needs to go on the link var notificationButtonContainer = notificationButtonLink; var closeClickTargets = $('body, header a.notification-indicator[href]'); var notificationsDropdown = null; var tabArrow = null; function listenForNotificationClick() { notificationButtonContainer.on('click', onNotificationButtonClicked); } function onNotificationButtonClicked(evt) { // Act normally (do nothing) if a modifier key is pressed, or if it was a right or middle click. if (evt.ctrlKey || evt.shiftKey || evt.metaKey || evt.which !== 1) { return; } evt.preventDefault(); notificationButtonContainer.off('click', onNotificationButtonClicked); // For GM 4.0 we must use an absolute path, so we use .prop() instead of .attr(). "This is an issue with Firefox and content scripts" var targetPage = notificationButtonLink.prop('href'); fetchNotifications(targetPage); } function fetchNotifications(targetPage) { notificationButtonContainer.css({ opacity: '0.3', outline: 'none', }); $.ajax({ url: targetPage, dataType: 'html', }).then(receiveNotificationsPage.bind(null, targetPage)).fail(receiveNotificationsPage); } function receiveNotificationsPage(targetPage, data, textStatus, jqXHR) { notificationButtonContainer.css('opacity', ''); notificationsDropdown = $('
    ').addClass('notifications-dropdown'); var title = 'Notifications'; if (targetPage !== mainNotificationsPath) { title += ' for ' + targetPage.replace(/^\/+|\/notifications$/g, ''); } var titleElem = $('

    ').text(title); if (targetPage !== mainNotificationsPath) { var buttonToSeeAll = $('').text('See all'); buttonToSeeAll.on('click', function(evt) { evt.preventDefault(); closeNotificationsDropdown(); fetchNotifications(mainNotificationsPath); }); titleElem.append(textNode(' ('), buttonToSeeAll, textNode(')')); } //notificationsDropdown.append( $("").append(titleElem) ); var notificationPage = $('
    ').append($.parseHTML(data)); var notificationsList = notificationPage.find('.notifications-list'); // Provide hover text for all links, so if the text is too long to display, it can at least be seen on hover. notificationsList.find('a').each(function() { $(this).attr('title', $(this).text().trim()); }); var minWidth = Math.min(700, window.innerWidth - 48); if (notificationsList.children().length === 0) { notificationsDropdown.append('No new notifications'); minWidth = 200; } notificationsDropdown.append(notificationsList); var linkToPage = mainNotificationsPath; //var linkToPage = targetPage; var seeAll = $('See all the notifications'); notificationsList.append(seeAll); var arrowSize = 10; // In v2, this appears on the notifications page, but not other pages. // It is needed to activate some of the CSS for the notifications list. document.body.classList.add('notifications-v2'); $('