Skip to content

Instantly share code, notes, and snippets.

@jareware
Last active August 29, 2015 13:56
Show Gist options
  • Save jareware/8850586 to your computer and use it in GitHub Desktop.
Save jareware/8850586 to your computer and use it in GitHub Desktop.
Userscript for maintaining a trackbar below your last seen message in a Flowdock chat, similar to what trackbar.pl does for irssi. Runnable both as a userscript (e.g. http://tampermonkey.net/) and bookmarklet (e.g. http://en.wikipedia.org/wiki/Bookmarklet). To enjoy automatic updates with Tampermonkey, put in https://gist.github.com/jareware/885…
// ==UserScript==
// @name Flowdock Trackbar
// @namespace https://gist.github.com/jareware/8850586
// @version 0.3
// @description Userscript for maintaining a trackbar below your last seen message in a Flowdock chat
// @match https://www.flowdock.com/*
// @copyright Jarno Rantanen <[email protected]>
// ==/UserScript==
(function(window) {
"use strict";
var NAMESPACE = 'flowdock-trackbar';
var TRACKBAR_CSS = {
cursor: 'pointer',
borderTop: '3px solid gray', // or "#BAE8F2"
padding: '40px 30px',
textAlign: 'center',
color: 'gray', // or "#3586B2"
background: '#D8EDF8' // or "white"
};
var $;
if ($ = window.jQuery) { // probably running as bookmarklet
initialize();
} else { // probably running as userscript
window.document.addEventListener('load', function() {
if ($ = window.jQuery) {
initialize();
}
});
}
return;
function initialize() {
log('Initializing');
// Whenever the user clicks, a new flow has potentially been brought up:
$(window.document).off('.' + NAMESPACE).on('click.' + NAMESPACE, onUserInteraction);
// Every once in a while, check that a spontaneous re-render hasn't removed us:
window.clearInterval(window[NAMESPACE + '-int']);
window[NAMESPACE + '-int'] = window.setInterval(checkForMissingTrackbar, 30 * 1000);
// Make sure we're also present immediately after starting the userscript:
onUserInteraction();
}
function onUserInteraction() {
[ 10, 100, 500, 1000, 2000, 5000 ].forEach(function(timeout) {
window.setTimeout(checkForMissingTrackbar, timeout);
});
}
function checkForMissingTrackbar() {
var $flow = $('.flow');
var trackbarPositioned = !!$flow.find('.' + NAMESPACE + '-determined').length;
var messagesPresent = !!$flow.find('.chat-message-list li').length;
if (messagesPresent && !trackbarPositioned) {
var flowID = $flow.attr('id');
var messageID = loadSeenMessageID(flowID);
positionTrackbar($flow, messageID);
}
}
function positionTrackbar($flow, messageID) {
log('Positioning trackbar for', $flow[0], 'at', messageID);
$flow.find('.' + NAMESPACE).remove();
var $targetComment = $flow.find('.chat-message-list li a.timestamp-link[href="' + messageID + '"]').parents('li');
if ($targetComment.length) {
$targetComment.after(createTrackbarEl($flow, true));
} else {
$flow.find('.chat-message-list li:last').after(createTrackbarEl($flow, false));
}
}
function createTrackbarEl($flow, determined) {
return $('<div>')
.addClass(NAMESPACE)
.toggleClass(NAMESPACE + '-determined', !!determined)
.css(TRACKBAR_CSS)
.text(determined
? '⬇ New messages are below this line; click to update ⬇'
: '⬆ Your last seen message is somewhere up there; click to update ⬆'
)
.on('click', function() {
var flowID = $flow.attr('id');
var messageID = getLatestMessageID($flow);
log('Marking messages as seen in', flowID);
saveSeenMessageID(flowID, messageID);
positionTrackbar($flow, messageID);
});
}
function getLatestMessageID($flow) {
return $flow.find('.chat-message-list li:last a.timestamp-link').attr('href');
}
function loadSeenMessageID(flowID) {
return JSON.parse(window.localStorage[NAMESPACE] || '{}')[flowID];
}
function saveSeenMessageID(flowID, messageID) {
log('Saving seen messageID for', flowID, '==', messageID);
if (messageID) {
var store = JSON.parse(window.localStorage[NAMESPACE] || '{}');
store[flowID] = messageID;
window.localStorage[NAMESPACE] = JSON.stringify(store, undefined, 4);
return messageID;
}
}
function log() {
var args = [ '[' + NAMESPACE + ']' ].concat(Array.prototype.slice.call(arguments));
window.console.log.apply(window.console, args);
}
})((function() {
try {
return unsafeWindow; // running as userscript
} catch (e) {
return window; // running as bookmarklet
}
})());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment