Permalink
Browse files

From week 11, completed user profiles.

  • Loading branch information...
roncli committed Jun 20, 2017
1 parent 807c613 commit 4a1e0116d9b569da529d502229e3f8fdde57be23
Showing with 169 additions and 80 deletions.
  1. +4 −4 app/package.json
  2. +36 −0 app/site/css/profile.css
  3. +24 −48 app/site/js/index.js
  4. +19 −2 app/site/js/profile.js
  5. +40 −0 app/site/js/utilities.js
  6. +43 −23 app/site/profile.htm
  7. +3 −3 package.json
@@ -20,15 +20,15 @@
"dependencies": {
"bootstrap": "3.3.7",
"bootstrap-colorpicker": "2.5.1",
"express": "4.15.2",
"iconv-lite": "0.4.17",
"express": "4.15.3",
"iconv-lite": "0.4.18",
"jquery": "3.2.1",
"node-fonts": "1.0.0",
"tinycolor2": "1.4.1",
"tmi.js": "1.1.2",
"tmi.js": "1.2.1",
"twitch-api": "0.4.6"
},
"engines": {
"node": ">=7.0.0"
"node": ">=8.0.0"
}
}
@@ -0,0 +1,36 @@
.panel {
margin-bottom: 0;
}

h3 {
margin: 0;
}

.buttons {
padding-bottom: 5px;
}

.buttons-bottom {
padding-top: 5px;
}

#timeout-time {
display: inline-block; width: auto;
}

#user-chat {
height: 252px;
overflow-x: hidden;
overflow-y: auto;
user-select: text;
}

a.userlink, a.userlink:hover, a.userlink:visited {
text-decoration: none;
color: inherit;
cursor: text;
}

.btn.btn-compact {
padding: 3px 6px;
}
@@ -1,47 +1,19 @@
const electron = require("electron"),
tinycolor = require("tinycolor2"),
const path = require("path"),
electron = require("electron"),
remote = electron.remote,
app = remote.app,
win = remote.getCurrentWindow(),
path = require("path"),
tinycolor = require("tinycolor2"),
Twitch = require("./modules/chat/twitch"), // TODO: Load modules
File = require("./modules/datastore/file"),
settings = require("./js/apiSettings"),
client = new Twitch(settings),
File = require("./modules/datastore/file");
Utilities = require("./js/utilities");

var channels = {},
profileWin;

class Index {
// # ##
// # # #
// ## ### ### ### ### ## # ### ###
// # # # # # # # # # # ## # ## ##
// # # # # ## # # ## ## # # ## ##
// ## # # # # # # # ## ## ### ###
// ###
// Based on http://stackoverflow.com/a/19826393/214137
static changeCss(cssName, cssValue) {
var cssMainContainer = $("#css-modifier-container"),
classContainer = cssMainContainer.find(`div[data-class="${cssName}"]`);

// Create hidden css main container if it doesn't exist.
if (cssMainContainer.length === 0) {
cssMainContainer = $("<div></div>").attr({id: "css-modifier-container"});
cssMainContainer.hide();
cssMainContainer.appendTo($("body"));
}

// Create div for the css if it doesn't exist.
if (classContainer.length === 0) {
classContainer = $("<div></div>").attr({"data-class": cssName});
classContainer.appendTo(cssMainContainer);
}

// Replace style in the css div.
classContainer.html(`<style>${cssName}{${cssValue}}</style>`);
}

// # ### ##
// # # # #
// ### ## ### # # ### ### ## #
@@ -115,15 +87,14 @@ class Index {
// ### ## ## ## ### # # # ### ## # # # # # # # ## ###
// ### ###
static settingsChanged() {
this.changeCss("#display", `font-family: "${win.data.appSettings.data.chat.font.face}"; font-size: ${win.data.appSettings.data.chat.font.size}px;`); // TODO: Potentially have a max size for title, input bo
this.changeCss("#display div.chat", `color: ${win.data.appSettings.data.chat.colors.chat.foreground}; background-color: ${win.data.appSettings.data.chat.colors.chat.background};`);
//changeCss("#display div.chat .text", `font-size: ${win.data.appSettings.data.chat.font.size}px;`);
this.changeCss("#display div.chat .info", `color: ${win.data.appSettings.data.chat.colors.chat.info};`);
this.changeCss("#display div.chat .join", `color: ${win.data.appSettings.data.chat.colors.chat.join};`);
this.changeCss("#display div.chat .part", `color: ${win.data.appSettings.data.chat.colors.chat.part};`);
this.changeCss("#display div.chat .highlight", `color: ${win.data.appSettings.data.chat.colors.chat.highlight};`);
this.changeCss("#inputbox", `color: ${win.data.appSettings.data.chat.colors.input.foreground}; background-color: ${win.data.appSettings.data.chat.colors.input.background}; font-family: "${win.data.appSettings.data.chat.font.face}"; font-size: ${win.data.appSettings.data.chat.font.size}px;`);
this.changeCss("#display div.users", `color: ${win.data.appSettings.data.chat.colors.userList.foreground}; background-color: ${win.data.appSettings.data.chat.colors.userList.background};`);
Utilities.changeCss("#display", `font-family: "${win.data.appSettings.data.chat.font.face}"; font-size: ${win.data.appSettings.data.chat.font.size}px;`, $); // TODO: Potentially have a max size for title, input box
Utilities.changeCss("#display div.chat", `color: ${win.data.appSettings.data.chat.colors.chat.foreground}; background-color: ${win.data.appSettings.data.chat.colors.chat.background};`, $);
Utilities.changeCss("#display div.chat .info", `color: ${win.data.appSettings.data.chat.colors.chat.info};`, $);
Utilities.changeCss("#display div.chat .join", `color: ${win.data.appSettings.data.chat.colors.chat.join};`, $);
Utilities.changeCss("#display div.chat .part", `color: ${win.data.appSettings.data.chat.colors.chat.part};`, $);
Utilities.changeCss("#display div.chat .highlight", `color: ${win.data.appSettings.data.chat.colors.chat.highlight};`, $);
Utilities.changeCss("#inputbox", `color: ${win.data.appSettings.data.chat.colors.input.foreground}; background-color: ${win.data.appSettings.data.chat.colors.input.background}; font-family: "${win.data.appSettings.data.chat.font.face}"; font-size: ${win.data.appSettings.data.chat.font.size}px;`, $);
Utilities.changeCss("#display div.users", `color: ${win.data.appSettings.data.chat.colors.userList.foreground}; background-color: ${win.data.appSettings.data.chat.colors.userList.background};`, $);
this.setSize($("#inputbox"));
}

@@ -198,7 +169,7 @@ class Index {
// # # ## ## # # # # # # #
// ### ### ## # #### ### # # # #
static userLink(channel, username, displayname) {
return `<a class="userlink" data-username="${username}", data-channel="${channel}">${displayname || username}</a>`;
return `<a class="userlink" data-username="${username}" data-displayname="${displayname}" data-channel="${channel}">${displayname || username}</a>`;
}
}

@@ -207,6 +178,7 @@ if (!win.data) {
}
win.data.userSettings = new File(path.join(app.getPath("userData"), "userSettings.js")),
win.data.appSettings = new File(path.join(app.getPath("userData"), "appSettings.js")),

// TODO: Figure out how to do timeouts, bans, purges
// ## # # # # # # # #
// # # # # # # # #
@@ -228,9 +200,9 @@ client.on("message", (channel, username, usercolor, displayname, html, text) =>
}

if (text.indexOf(win.data.userSettings.data.twitch.username) === -1) {
$(`#channel-${channelName} .text`).append(`${Index.timestamp()}<b style="color: ${usercolor}">${Index.userLink(channel, username, displayname)}</b>: ${html}<br />`);
$(`#channel-${channelName} .text`).append(`<span class="user-${username}">${Index.timestamp()}<b style="color: ${usercolor}">${Index.userLink(channel, username, displayname)}</b>: ${html}<br /></span>`);
} else {
$(`#channel-${channelName} .text`).append(`${Index.timestamp()}<b style="color: ${usercolor}">${Index.userLink(channel, username, displayname)}</b>: <span class="highlight">${html}</span><br />`);
$(`#channel-${channelName} .text`).append(`<span class="user-${username}">${Index.timestamp()}<b style="color: ${usercolor}">${Index.userLink(channel, username, displayname)}</b>: <span class="highlight">${html}</span><br /></span>`);
}
});

@@ -393,6 +365,9 @@ win.data.appSettings.load().then(() => {
// # # ### ### ## ## ## ## ### # # # ### ## # # ### # # # ## ###
// # # ###
win.data.appSettings.on("saved", () => {
if (profileWin) {
profileWin.emit("chat-settings", win.data.appSettings.data.chat);
}
Index.settingsChanged();
});

@@ -517,12 +492,13 @@ $(document).ready(() => {
var data = $(ev.target).data();

if (profileWin) {
profileWin.emit("profile-set", data.channel, data.username);
profileWin.emit("profile-set", data.channel, data.username, $(`#display .text .user-${data.username}`).map((index, el) => $(el).html()).toArray().join("")); // TODO: Consolidate user data, possibly into the channel user array.
} else {
profileWin = new electron.remote.BrowserWindow({width: 800, height: 600, title: `Hyperdrive Toolkit - Profile - ${data.username} on ${data.channel}`});
profileWin = new electron.remote.BrowserWindow({width: 640, height: 480, resizable: false, title: `Hyperdrive Toolkit - Profile - ${data.username} on ${data.channel}`});

profileWin.on("profile-get", () => {
profileWin.emit("profile-set", data.channel, data.username);
profileWin.emit("profile-set", data.channel, data.username, $(`#display .text .user-${data.username}`).map((index, el) => $(el).html()).toArray().join("")); // TODO: Consolidate user data, possibly into the channel user array.
profileWin.emit("chat-settings", win.data.appSettings.data.chat);
});

profileWin.loadURL(`file://${__dirname}/profile.htm`, {
@@ -1,5 +1,6 @@
const electron = require("electron"),
win = electron.remote.getCurrentWindow();
win = electron.remote.getCurrentWindow(),
Utilities = require("./js/utilities");

// # # # ## #
// # # # #
@@ -8,14 +9,30 @@ const electron = require("electron"),
// #### # # # # # # # # # # # # # # # ## ## ## #
// #### ### # # ## # # ### # ## # ### ### ## ### ## ##
// #
win.on("profile-set", (channel, username) => {
win.on("profile-set", (channel, username, userChat) => {
win.channel = channel;
win.username = username;
$("#user-chat").html(userChat);

document.title = `Hyperdrive Toolkit - Profile - ${username} on ${channel}`;
$(".username").text(username);
});

// # # # # # #
// # # # #
// # # ## ### ## ### ## ### ### ### ### ## ### ### ## ### ### ###
// # # # # # # # # # # # # # # # #### ## # ## # # # # # # # ##
// #### # # # # # # # # # # # ## # ## ## # # # # # ## ##
// #### ### # # ## # # ## # # # # ## ### ## ## ## ### # # # ###
// ###
win.on("chat-settings", (settings) => {
Utilities.changeCss("#user-chat", `font-family: "${settings.font.face}"; font-size: ${settings.font.size}px; color: ${settings.colors.chat.foreground}; background-color: ${settings.colors.chat.background};`, $);
Utilities.changeCss("#user-chat .info", `color: ${settings.colors.chat.info};`, $);
Utilities.changeCss("#user-chat .join", `color: ${settings.colors.chat.join};`, $);
Utilities.changeCss("#user-chat .part", `color: ${settings.colors.chat.part};`, $);
Utilities.changeCss("#user-chat .highlight", `color: ${settings.colors.chat.highlight};`, $);
});

// # # # # #
// ### # # # # #
// # # # ### ## ## # # # # ## ### ### # ### ## ### ### # #
@@ -0,0 +1,40 @@
// # # # # ## # # #
// # # # # #
// # # #### ## # ## #### ## ### ###
// # # # # # # # # # # #
// # # # # # # # # ##### ###
// # # # # # # # # # # # #
// ### ## ### ### ### ## ### ### ####
class Utilities {
// # ##
// # # #
// ## ### ### ### ### ## # ### ###
// # # # # # # # # # # ## # ## ##
// # # # # ## # # ## ## # # ## ##
// ## # # # # # # # ## ## ### ###
// ###
// Based on http://stackoverflow.com/a/19826393/214137
static changeCss(cssName, cssValue, $) {
var cssMainContainer = $("#css-modifier-container"),
classContainer = cssMainContainer.find(`div[data-class="${cssName}"]`);

// Create hidden css main container if it doesn't exist.
if (cssMainContainer.length === 0) {
cssMainContainer = $("<div></div>").attr({id: "css-modifier-container"});
cssMainContainer.hide();
cssMainContainer.appendTo($("body"));
}

// Create div for the css if it doesn't exist.
if (classContainer.length === 0) {
classContainer = $("<div></div>").attr({"data-class": cssName});
classContainer.appendTo(cssMainContainer);
}

// Replace style in the css div.
classContainer.html(`<style>${cssName}{${cssValue}}</style>`);
}

}

module.exports = Utilities;
@@ -2,30 +2,50 @@
<head>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script>$ = jQuery = require("jquery")</script>
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="../node_modules/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js"></script>
<script src="js/profile.js"></script>
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"></link>
<link href="../node_modules/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet"></link>
<link href="../node_modules/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css" rel="stylesheet"></link>
<link href="css/profile.css" rel="stylesheet"></link>
</head>
<body>
<button id="ban">Ban</button>
<button id="unban">Unban</button>
Timeout:
<select id="timeout-time">
<option value="1">Purge</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
<option value="900">15 minutes</option>
<option value="1800">30 minutes</option>
</select>
<button id="timeout">Timeout</button>
<br />
Ban Reason: <input type="text" id="ban-reason" />
<br /><br />
<button id="mod">Mod</button>
<button id="unmod">Unmod</button>
<br /><br />
<button id="twitch">twitch.tv/<span class="username"></span></button>
<button id="join">Join #<span class="username"></span></button>
<br /><br />
<button id="follow">Follow</button>
<button id="unfollow">Unfollow</button>
<body style="user-select: none;">
<div class="panel panel-default">
<div class="panel-heading"><h3>Profile for <span class="username"></span></h3></div>
<div class="panel-body" style="text-align: center;">
<div class="buttons">
Ban Reason: <input type="text" id="ban-reason" />
<button id="ban" class="btn btn-compact btn-default">Ban</button>
<button id="unban" class="btn btn-compact btn-default">Unban</button>
</div>
<div class="buttons">
<span>Timeout:</span>
<select id="timeout-time" class="form-control">
<option value="1">Purge</option>
<option value="60">1 minute</option>
<option value="300">5 minutes</option>
<option value="900">15 minutes</option>
<option value="1800">30 minutes</option>
</select>
<button id="timeout" class="btn btn-compact btn-default">Timeout</button>
</div>
<div class="row buttons buttons-bottom">
<div class="col-xs-3">
<button id="mod" class="btn btn-compact btn-default">Mod</button>
<button id="unmod" class="btn btn-compact btn-default">Unmod</button>
</div>
<div class="col-xs-4">
<button id="follow" class="btn btn-compact btn-default">Follow</button>
<button id="unfollow" class="btn btn-compact btn-default">Unfollow</button>
</div>
<div class="col-xs-5">
<button id="twitch" class="btn btn-compact btn-default">Open Stream</span></button>
<button id="join" class="btn btn-compact btn-default">Join Channel</span></button>
</div>
</div>
</div>
</div>
<div id="user-chat"></div>
</body>
</html>
@@ -18,11 +18,11 @@
"url": "https://github.com/roncli/HyperdriveToolkit.git"
},
"devDependencies": {
"electron-builder": "15.6.2",
"electron": "1.6.2"
"electron": "1.6.11",
"electron-builder": "19.5.1"
},
"engines": {
"node": ">=7.0.0"
"node": ">=8.0.0"
},
"productName": "HyperdriveToolkit",
"build": {

0 comments on commit 4a1e011

Please sign in to comment.