Skip to content

Instantly share code, notes, and snippets.

@rlemon
Forked from kendfrey/darkchat.css
Last active August 29, 2015 14:15
Show Gist options
  • Save rlemon/43b86547898853efc068 to your computer and use it in GitHub Desktop.
Save rlemon/43b86547898853efc068 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name SO Dark Chat + JS
// @author Robert Lemon
// @version 0.1.1
// @namespace
// @description adds colors to users messages and a whole bunch of other crap.
// @include http://chat.stackoverflow.com/rooms/*
// @include http://chat.stackexchange.com/rooms/*
// ==/UserScript==
(function () {
"use strict";
var chat = document.getElementById('chat');
var userColorSheet = document.createElement('style');
var users = {
lookup: function(name) {
return name in this.data;
},
store: function(name, key, value) {
console.log('storing ' + name + ' as ' + value);
this.data[name] = {
key: key,
value: value
};
this.writeToSheet(key, value);
return value;
},
load: function() {
var data;
try {
data = JSON.parse(localStorage.getItem('so_colour_users'));
} catch (err) {
console.error(err, 'malformed json in localStorage. clearing localStorage object.');
localStorage.setItem('so_colour_users', '{}');
}
if (!data) return;
Object.keys(data).forEach(function(user) {
this.data[user] = {
key: data[user].key,
value: data[user].value
};
this.writeToSheet(data[user].key, data[user].value);
}.bind(this));
},
save: function() {
var dataString = JSON.stringify(this.data);
if (dataString) {
localStorage.setItem('so_colour_users', dataString);
} else {
console.error('could not save');
}
},
writeToSheet: function(key, value) {
userColorSheet.textContent += '.' + key + ' .messages { border-top: solid .25em ' + value + ' !important; } ';
},
data: {}
};
document.head.appendChild(userColorSheet);
users.load();
function hashCode(str) {
var hash = 0;
str += '!';
for (var i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
return -hash;
}
function colorCode(i) {
return '#' + (Math.min((i >> 24) & 0xFF, 175).toString(16) +
Math.min((i >> 16) & 0xFF, 175).toString(16) +
Math.min((i >> 8) & 0xFF, 175).toString(16) +
Math.min(i & 0xFF, 175).toString(16)).slice(0, 6);
}
function colorUsers(node) {
if (node.classList && node.classList.contains('user-container')) {
var user = node.querySelector('a .username').textContent,
existing = users.lookup(user);
if (!existing && node.className) {
var keys = node.className.match(/user-[0-9]+/g);
if (keys) {
users.store(user, keys[0], colorCode(hashCode(user + keys[0] + user)));
}
}
}
}
function visualHexColors(node) {
if (node.classList && node.classList.contains('message') && !node.classList.contains('pending') && !node.querySelector('.ob-post')) {
[].forEach.call(node.childNodes, function(child) {
if (/#(?:[0-9a-f]{3}){1,2}/ig.test(child.textContent)) {
child.innerHTML = child.innerHTML.replace(/#(?:[0-9a-f]{3}){1,2}/ig, function(match) {
return '<span style="width:12px;height:12px;border:1px solid #222;background-color:' + match + ';display:inline-block;"></span>' + match;
});
}
});
}
}
function parseNode(node) {
colorUsers(node);
visualHexColors(node);
}
/* experimental colour chooser
this entire codeblock is sloppy
*/
function randomColor() {
return '#' + Math.random().toString(16).slice(-6);
}
chat.addEventListener('click', function(e) {
if (!e.target.classList.contains('messages')) return;
if (e.offsetY <= 2) { // px size of the bar
var name = e.target.parentNode.querySelector('a .username').textContent;
var newValue = prompt('please enter a new hex value for this user. type `reset` to revert to the original value, `random` for a random value.', name in users.data ? users.data[name].value : '');
if (newValue) {
if (newValue === 'reset') {
delete users.data[name];
} else if( newValue === 'random' ) {
users.data[name].value = randomColor();
} else {
users.data[name].value = newValue;
}
users.save();
userColorSheet.textContent = '';
users.load();
if (newValue === 'reset') {
[].forEach.call(chat.querySelectorAll('.user-container'), parseNode);
}
}
}
})
setTimeout(function() {
[].forEach.call(chat.querySelectorAll('.user-container'), colorUsers);
[].forEach.call(chat.querySelectorAll('.user-container .message'), visualHexColors);
users.save();
}, 1000); // some users are never parsed. this solves that.
new MutationObserver(function(records) {
records.forEach(function(record) {
[].forEach.call(record.addedNodes, parseNode);
});
}).observe(chat, {
childList: true,
subtree: true
});
}());
body,
#loading,
#loading #loading-message {
background-color : #000 !important;
background-image : url("http://i.stack.imgur.com/SxaRm.png") !important;
color : #ddd !important;
}
#loading,
#loading #loading-message {
box-shadow : none !important;
}
.messages {
background-color : #222 !important;
border : none !important;
color : #ddd !important;
}
.system-message-container .system-message {
color : #aaa !important;
}
.mine .messages {
background-color : #362C22 !important;
border : none !important;
color : #ddd !important;
}
.message.pending {
color : #fb7 !important;
}
.message.posted {
color : #fdb !important;
}
.message.neworedit {
color : #fdb !important;
}
.message.highlight {
background-color : #005 !important;
}
.msg-small, #sidebar {
color : #ddd !important;
}
/* Begin Bottom Area */
#input-area {
background-color : #333 !important;
background-image : url("http://i.stack.imgur.com/JfVoA.png") !important;
}
#tabcomplete li {
background-color : #000 !important;
color : #ccc !important;
border-color : #888 !important;
}
#tabcomplete li.chosen {
background-color : #005 !important;
}
#input {
background-color : #000 !important;
color : #ddd !important;
}
/* End Bottom Area */
div.message.reply-parent, div.message.reply-child {
background-color : #333 !important;
border : 1px solid #fff !important;
}
div.message .meta,
.timestamp {
background-color : #333 !important;
color : #ddd !important;
}
.mention {
background-color : #24A !important;
}
.monologue .signature a,
a.signature {
color : #ddd !important;
}
.flair {
color : #ddd !important;
}
/* Begin OneBoxing */
.ob-tweet,
.ob-twitteruser,
.ob-wikipedia,
.ob-amazon,
.ob-gist,
.ob-message,
.ob-lpadbug,
.ob-manpage,
.ob-blog,
.ob-exception,
.ob-post,
.ob-user,
.ob-job {
background-color : #333 !important;
color : #ddd !important;
}
.ob-post-title a,
.ob-tweet .ob-status-text,
.ob-wikipedia-title a,
.ob-amazon-title a,
.ob-lpadbug-title a,
.ob-manpage-title a,
.ob-blog-title a {
color : #ddd !important;
}
/* End OneBoxing */
/* Begin Notifications */
.notification, #feed-ticker {
background : rgba(0, 0, 0, 0.95) !important;
-moz-box-shadow : 0 1px 10px #545454 !important;
-webkit-box-shadow : 0 1px 10px #545454 !important;
box-shadow : 0 1px 10px #545454 !important;
}
.ticker-item a {
color : #509FD8 !important;
}
/* End Notifications */
/* Begin Sidebar */
#searchbox {
background-color : #000 !important;
color : #ddd !important;
}
#sidebar #info #roomtitle {
text-shadow : 0px 1px 0px #000 !important;
}
#sidebar #info #sidebar-menu,
#present-users,
ul#my-rooms,
div#starred-posts > div > ul > li {
border-bottom : 1px dotted #222 !important;
}
.room-info > .last-message {
margin-left : 10px !important;
}
ul#my-rooms> li.activity-0 {
color : #fff !important;
}
ul#my-rooms> li.activity-1 {
color : #ddd !important;
}
ul#my-rooms> li.activity-2 {
color : #bbb !important;
}
ul#my-rooms> li.activity-3 {
color : #999 !important;
}
ul#my-rooms> li.activity-4 {
color : #888 !important;
}
ul#my-rooms> li.activity-5 {
color : #777 !important;
}
ul#my-rooms> li.activity-6 {
color : #666 !important;
}
ul#my-rooms> li:hover {
background-color : #333 !important;
}
ul#my-rooms> li:hover a,
ul#my-rooms> li:hover div.last-message {
color : #fff !important;
}
ul#my-rooms .quickleave {
float : right !important;
opacity : 0.3 !important;
}
ul#my-rooms .quickleave:hover {
opacity : 1.0 !important;
}
ul#my-rooms .quickswitch,
ul#my-rooms .quickleave,
.vote-count-container.stars .img {
background-image : url("http://i.stack.imgur.com/Da7jC.png") !important;
}
#starred-posts ul li:hover {
background-color : #333 !important;
}
/* End Sidebar */
.vote-count-container.stars.owner-star .img,
.vote-count-container.stars.user-star .img,
.vote-count-container.stars.owner-star.user-star .img,
.sprite {
background-image : url("http://i.stack.imgur.com/Da7jC.png") !important;
}
div.message:hover .action-link,
.timestamp:hover + div.message .action-link {
color : #eee !important;
background-color : #333 !important;
}
/* Upload popup */
.wmd-prompt-dialog {
border : none !important;
background-color : #000 !important;
background-image : url("http://i.stack.imgur.com/SxaRm.png") !important;
color : #ddd !important;
}
/* Search page */
body.outside #container,
.general-room-access>form>div {
color : #ddd !important;
}
/* Popups */
.popup,
#main.message-admin-mode .message-controls,
#conversation-sel {
border-color : #111 !important;
color : #ddd !important;
background-color : rgba(51, 51, 51, 0.95) !important;
box-shadow : 0 1px 15px #000 !important;
}
.popup .btn-close,
#conversation-sel .btn-close
{
color : #454545 !important;
background-color : #111 !important;
}
/* Info Page */
.usercard-xxl,
.roomcard-xxl,
.roomcard,
.usercard,
.room-mini,
.conversation-info {
background-color : #222 !important;
border-color : #000 !important;
color : #ddd !important;
box-shadow : 0px 1px 3px #111 !important;
}
.roomcard,
.usercard {
background-color : #161616 !important;
border : none !important;
}
.subheader #tabs a.youarehere {
background : Transparent !important;
color : #eee !important;
}
.monologue.catchup-marker {
border-top-color : rgba(155, 155, 155, 0.5) !important;
}
/* Tags */
.tag,
.ob-post-tag {
color : #454545 !important;
background-color : #ddd !important;
border-bottom-color: #999 !important;
border-right-color : #ddd !important;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment