Skip to content

Instantly share code, notes, and snippets.

@stevenhao
Last active April 5, 2019 01:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevenhao/9040488c49760a43abd8753e3eda251d to your computer and use it in GitHub Desktop.
Save stevenhao/9040488c49760a43abd8753e3eda251d to your computer and use it in GitHub Desktop.
slack channel groups
// ==UserScript==
// @name Slack Channel Grouping
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://scaleapi.slack.com/*
// @grant none
// ==/UserScript==
// ========================
// EDIT TO CUSTOMIZE
const GROUPS = {
'eng': ['eng-internal', 'eng-standup', 'eng-frontend', 'engineering'],
'lidar': ['lidar-team', 'lidar', 'lidar-semseg-team', 'lidar-qa', 'lidart'],
'bugs': ['bugs-conversation', 'bugs-frontend', 'bugs', 'oncall'],
'stevens': ['Steven Salka', 'steven'],
'important': ['overheard', 'hungry', 'eng-offtopic', 'random', 'crosswords', 'steven', 'klubhaus'],
'conspiracies': ['conspiracies'],
};
// =========================
const stylesheet = document.createElement('style');
stylesheet.innerHTML = '.group-container > * { padding-left: 0px; } .group-container { display: block; position: relative; height: unset; position: relative; } .group { padding-top: 5px; position: relative; } .group > a { padding-left: 0px; } .group > span > button { color: #ddd; } .group > a { padding-left: 8px; } .group.collapsed > a { display: none; }';
document.head.appendChild(stylesheet);
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
// ... whatever else you want to do
// maybe call onhashchange e.handler
return pushState.apply(history, arguments);
};
})(window.history);
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
// ... whatever else you want to do
// maybe call onhashchange e.handler
return pushState.apply(history, arguments);
};
})(window.history);
const INVERSE_GROUPS = {};
Object.keys(GROUPS).forEach(key => {
GROUPS[key].forEach(val => {
INVERSE_GROUPS[val] = [...(INVERSE_GROUPS[val] || []), key];
});
});
const makeGroup = (name) => {
const div = document.createElement('div');
const button = document.createElement('button');
const label = document.createElement('span');
const classNames = ["ts_icon ts_icon_chevron_down team_name_caret btn_unstyle", "ts_icon ts_icon_chevron_right team_name_caret btn_unstyle"];
button.className = classNames[0];
button.setAttribute('aria-label', "Team Menu");
button.setAttribute('aria-haspopup', "true");
label.style.cursor = 'pointer';
label.textContent = name;
label.insertBefore(button, label.firstChild);
div.appendChild(label);
let x = 0;
label.addEventListener('click', () => {
x += 1;
button.className = classNames[x % 2];
div.classList.toggle('collapsed');
});
div.className = 'group';
return div;
};
const makeGroupContainer = () => {
const div = document.createElement('div');
div.textContent = 'Groups';
div.className = 'group-container p-channel_sidebar__section_heading';
return div;
};
const $ = x => document.querySelector(x);
const $$ = x => Array.from(document.querySelectorAll(x));
const run = (function() {
'use strict';
const starredAnchor = $('.p-channel_sidebar__section_heading').parentElement;
const container = $('.p-channel_sidebar__static_list');
if (!(starredAnchor && container)) return;
const groupContainer = makeGroupContainer();
container.insertBefore(groupContainer, starredAnchor);
const refresh = () => {
const links = $$('.c-link.p-channel_sidebar__channel');
$$('.group').forEach(x => x.remove());
const groupedLinks = {};
for (const link of links) {
if (link.hasAttribute('cloned')) continue;
const name = link.textContent;
if (name in INVERSE_GROUPS) {
const groupNames = INVERSE_GROUPS[name];
for (const groupName of groupNames) {
if (!(groupName in groupedLinks)) {
groupedLinks[groupName] = makeGroup(groupName);
groupContainer.appendChild(groupedLinks[groupName]);
}
const newLink = jQuery(link).clone(false)[0];
newLink.setAttribute('cloned', "true");
groupedLinks[groupName].appendChild(newLink);
newLink.addEventListener('click', (e) => {
e.preventDefault();
link.click();
});
}
//link.remove();
}
}
console.log('refreshed', groupedLinks);
};
refresh();
setTimeout(refresh, 1500);
window.refresh = refresh;
history.onpushstate = () => { setTimeout(() => {requestAnimationFrame(refresh);}); };
return true;
});
const i = setInterval(() => {
if (run()) {
clearInterval(i);
}
}, 500);
/* this file is optional; the stylesheet is already packaged in the js */
/* This css source is provided for developers */
.group-container > * {
padding-left: 0px;
}
.group-container {
display: block;
position: relative;
height: unset;
position: relative;
}
.group {
padding-top: 5px;
position: relative;
}
.group > a {
padding-left: 0px;
}
.group > span > button {
color: #ddd;
}
.group > a {
padding-left: 8px;
}
.group.collapsed > a {
display: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment