mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-09 07:40:53 +00:00
3.5.271 to 3.5.284. As usual, I only remember to commit when someone mentions it.
This commit is contained in:
parent
9592dc1c2c
commit
8db999a8a8
29 changed files with 1388 additions and 317 deletions
|
@ -1,3 +1,86 @@
|
||||||
|
<div class="list-header">3.5.284</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Inject FFZ emotes into the BetterTTV tab completion list.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.283</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Support for moderation logging. When possible, messages are combined to avoid filling chat with nonsense.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.282</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: Height of classic player theme controls when in theater mode.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.281</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Option to hide whispers on embedded chat.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.280</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Use new display name formatting logic in more places.</li>
|
||||||
|
<li>Fixed: Aliases now appear for moderation cards again.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.279</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: Dark CSS tweaks for non-Ember pages.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.278</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Darken Clips.</li>
|
||||||
|
<li>Fixed: Classic Player's CSS was broken because of a malformed comment.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.277</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: More tab completion tweaks for users with display names that don't match their username.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.276</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: Highlight a user's display name if it's different than their username. (Well, more of an addition with how it works...)</li>
|
||||||
|
<li>Changed: Make FFZ's tab completion work nicer for users with non-matching usernames and display names.</li>
|
||||||
|
<li>Changed: CSS tweaks for mod cards when user information is displayed alongside a user's username.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.275</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Option to control the appearance of usernames in chat when the user's name and display name do not match.</li>
|
||||||
|
<li>Changed: Darken the Closed Captioning settings dialog.</li>
|
||||||
|
<li>Fixed: CSS tweaks for mod cards.</li>
|
||||||
|
<li>Fixed: User information was not being added to mod cards properly.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.274</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Changed: Use the new badges code for conversation window header badges.</li>
|
||||||
|
<li>Fixed: Dark CSS tweaks for the modified conversation windows.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.273</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Support the Discover directory with stream uptime and channel logos.</li>
|
||||||
|
<li>Changed: Dark theme CSS tweaks for the Discover directory.</li>
|
||||||
|
<li>Fixed: Chat status labels were breaking stuff on navigation thanks to an undefined variable.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.272</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Ember error handlers to hopefully catch more useful logs in the future when there are issues.</li>
|
||||||
|
<li>Fixed: Bug in an API wrapper that would cause the Ember app to fail to navigate in certain conditions.</li>
|
||||||
|
<li>Fixed: CSS tweaks.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.271</div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: FFZ menu icon would appear at an incorrect position with the Bits dialog open.</li>
|
||||||
|
<li>Changed: Properly darken the bits dialog and adjust its colors when no-blue is enabled.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="list-header">3.5.270</div>
|
<div class="list-header">3.5.270</div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Changed: Remove client-side permissions check from <code>/ffz following</code>.</li>
|
<li>Changed: Remove client-side permissions check from <code>/ffz following</code>.</li>
|
||||||
|
|
83
dark.css
83
dark.css
|
@ -197,7 +197,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: rgb(16,16,16);
|
background-color: rgb(16,16,16);
|
||||||
color: rgb(195,195,195); /*#acacbf;*/
|
color: rgb(195,195,195); /*#acacbf;*/
|
||||||
border-color: #32323e;
|
border-color: #32323e;
|
||||||
box-shadow: rgba(255,255,255,0.2) 0 0 0 1px inset;
|
box-shadow: rgba(255,255,255,0.2) 0 0 0 1px inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark #flyout .content,
|
.ffz-dark #flyout .content,
|
||||||
|
@ -315,6 +315,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark .st-autocomplete-small .list ul .result:not(.active) p,
|
.ffz-dark .st-autocomplete-small .list ul .result:not(.active) p,
|
||||||
.ffz-dark .manager .videos-grid .video:hover .meta .actions li a,
|
.ffz-dark .manager .videos-grid .video:hover .meta .actions li a,
|
||||||
.ffz-dark .ember-chat .chat-room-list .room:not(:hover) p.room-title,
|
.ffz-dark .ember-chat .chat-room-list .room:not(:hover) p.room-title,
|
||||||
|
.ffz-dark .dropmenu_action:not(:hover),
|
||||||
.ffz-dark .dropmenu_action:not(:hover) span,
|
.ffz-dark .dropmenu_action:not(:hover) span,
|
||||||
.ffz-dark a {
|
.ffz-dark a {
|
||||||
/*.ffz-dark a:not(.profile-card__content):not(.filter-item):not(.ui-state-focus):not(.button):not(.switch):not(.follow):not(.fb_button):not(.what) {*/
|
/*.ffz-dark a:not(.profile-card__content):not(.filter-item):not(.ui-state-focus):not(.button):not(.switch):not(.follow):not(.fb_button):not(.what) {*/
|
||||||
|
@ -522,6 +523,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .card__boxpin,
|
||||||
.ffz-dark .streams .stream .content .thumb .boxart,
|
.ffz-dark .streams .stream .content .thumb .boxart,
|
||||||
.ffz-dark .videos .video .content .thumb .boxart {
|
.ffz-dark .videos .video .content .thumb .boxart {
|
||||||
border-color: rgb(16,16,16);
|
border-color: rgb(16,16,16);
|
||||||
|
@ -532,6 +534,8 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: rgb(16,16,16);
|
background-color: rgb(16,16,16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .card .card__title a,
|
||||||
|
.ffz-dark .card .card__info a,
|
||||||
.ffz-dark .items-grid .meta .title,
|
.ffz-dark .items-grid .meta .title,
|
||||||
.ffz-dark .items-grid .meta p a {
|
.ffz-dark .items-grid .meta p a {
|
||||||
color: #9c9c9c !important;
|
color: #9c9c9c !important;
|
||||||
|
@ -541,18 +545,21 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
color: #6c6c6c;
|
color: #6c6c6c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .mininav li > a,
|
||||||
.ffz-dark ul.tabs li > a,
|
.ffz-dark ul.tabs li > a,
|
||||||
.ffz-dark .directory_header .nav li > a,
|
.ffz-dark .directory_header .nav li > a,
|
||||||
.ffz-dark ul.tabs_fake li > a {
|
.ffz-dark ul.tabs_fake li > a {
|
||||||
color: #a68ed2;
|
color: #a68ed2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .mininav,
|
||||||
.ffz-dark ul.tabs:before,
|
.ffz-dark ul.tabs:before,
|
||||||
.ffz-dark .direcotry_header .nav:before,
|
.ffz-dark .direcotry_header .nav:before,
|
||||||
.ffz-dark ul.tabs_fake:before {
|
.ffz-dark ul.tabs_fake:before {
|
||||||
border-color: #32323e;
|
border-color: #32323e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .mininav li > a:hover,
|
||||||
.ffz-dark ul.mininav li.active,
|
.ffz-dark ul.mininav li.active,
|
||||||
.ffz-dark ul.tabs li.selected a,
|
.ffz-dark ul.tabs li.selected a,
|
||||||
.ffz-dark .directory_header .nav li.selected a,
|
.ffz-dark .directory_header .nav li.selected a,
|
||||||
|
@ -793,13 +800,34 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
|
|
||||||
/* Dashboard */
|
/* Dashboard */
|
||||||
|
|
||||||
|
.ffz-dark .carousel__button {
|
||||||
|
background-color: #101010;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .carousel__arrow:before {
|
||||||
|
border-color: #a68ed2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .carousel__button:hover .carousel__arrow:before {
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .carousel__button:hover {
|
||||||
|
background-color: #191919;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-dark .brick {
|
.ffz-dark .brick {
|
||||||
background-color: #121212;
|
background-color: #121212;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .brick--marked.brick--theme-white,
|
||||||
|
.ffz-dark .brick--marked.brick--theme-grey {
|
||||||
|
box-shadow: 3px 0 0 #9a7fcc inset,0 0 0 1px rgba(255,255,255,0.2) inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .brick--faint,
|
.ffz-dark .brick--faint,
|
||||||
.ffz-dark .brick--block {
|
.ffz-dark .brick--block {
|
||||||
background-color: rgb(25,25,25);
|
background-color: rgb(25,25,25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .brick,
|
.ffz-dark .brick,
|
||||||
|
@ -807,7 +835,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark .brick--block,
|
.ffz-dark .brick--block,
|
||||||
.ffz-dark #action_feed .action,
|
.ffz-dark #action_feed .action,
|
||||||
.ffz-dark .revHeader__item {
|
.ffz-dark .revHeader__item {
|
||||||
border-color: rgba(255,255,255,0.2);
|
border-color: rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark #mantle_skin .what { background-color: #6441a5; }
|
.ffz-dark #mantle_skin .what { background-color: #6441a5; }
|
||||||
|
@ -955,7 +983,23 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark #mantle_skin div[style^=" display:background:#ffffff"],
|
||||||
|
.ffz-dark #mantle_skin .social_links img {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark #mantle_skin div[style^=" display:background:#ffffff"] .extraspace { color: #333 }
|
||||||
|
|
||||||
.ffz-dark #mantle_skin ul.vtabs li .not_linked,
|
.ffz-dark #mantle_skin ul.vtabs li .not_linked,
|
||||||
|
.ffz-dark #mantle_skin ul.vtabs li a {
|
||||||
|
color: #acacbf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark #partner_application .partner_reqs {
|
||||||
|
background-color: #191919;
|
||||||
|
border-color: #404040;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-dark #mantle_skin ul.vtabs li.selected a,
|
.ffz-dark #mantle_skin ul.vtabs li.selected a,
|
||||||
.ffz-dark #mantle_skin ul.submenu li a:hover,
|
.ffz-dark #mantle_skin ul.submenu li a:hover,
|
||||||
.ffz-dark .sort-contain .sort-options li a:hover,
|
.ffz-dark .sort-contain .sort-options li a:hover,
|
||||||
|
@ -998,6 +1042,15 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
-webkit-filter: invert(100%);
|
-webkit-filter: invert(100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .new-header-search input {
|
||||||
|
color: #fff;
|
||||||
|
box-shadow: rgba(255,255,255,0.2) 0 0 0 1px inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .new-header-search input:focus {
|
||||||
|
box-shadow: rgba(255,255,255,0.4) 0 0 0 1px inset;
|
||||||
|
}
|
||||||
|
|
||||||
/* Playlist */
|
/* Playlist */
|
||||||
|
|
||||||
.ffz-dark .ember-chat .chat-header {
|
.ffz-dark .ember-chat .chat-header {
|
||||||
|
@ -1088,7 +1141,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversations-list .search-divider,
|
.ffz-dark .conversations-list .search-divider,
|
||||||
.ffz-dark .conversation-header {
|
.ffz-dark .convoHeader {
|
||||||
background-color: #121217;
|
background-color: #121217;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
@ -1099,11 +1152,11 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
background-color: #444;
|
background-color: #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversation-window.has-focus .conversation-header {
|
.ffz-dark .conversation-window.has-focus .convoHeader {
|
||||||
background-color: #121217;
|
background-color: #121217;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversation-window.has-focus .conversation-header-name {
|
.ffz-dark .conversation-window.has-focus .convoHeader .username {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,7 +1222,7 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .conversation-window:not(.collapsed) .conversation-header {
|
.ffz-dark .conversation-window:not(.collapsed) .convoHeader {
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1329,6 +1382,11 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
color: #C3C3C3;
|
color: #C3C3C3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-dark .searchPanel--fly:before,
|
||||||
|
.ffz-dark .searchPanel--fly:after {
|
||||||
|
border-bottom-color: #404040;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-dark .titleBar {
|
.ffz-dark .titleBar {
|
||||||
background-color: #090909;
|
background-color: #090909;
|
||||||
}
|
}
|
||||||
|
@ -1344,6 +1402,15 @@ body.ffz-dark:not([data-page="teams#show"]),
|
||||||
.ffz-dark .titleBar__back:hover,
|
.ffz-dark .titleBar__back:hover,
|
||||||
.ffz-dark .resultView__titlesep.isActive { background-color: #222 }
|
.ffz-dark .resultView__titlesep.isActive { background-color: #222 }
|
||||||
|
|
||||||
|
.ffz-dark .searchPanel .card__body--overlay .card__title {
|
||||||
|
text-shadow: 1px 1px #000, -1px 1px #000, -1px -1px #000, 1px -1px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-dark .card__title a:hover,
|
||||||
|
.ffz-dark .card__info a:hover {
|
||||||
|
color: #ccd;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-dark .resultView__item .card__info span,
|
.ffz-dark .resultView__item .card__info span,
|
||||||
.ffz-dark .resultView__item .card__title,
|
.ffz-dark .resultView__item .card__title,
|
||||||
.ffz-dark .resultView__titlesep.isActive .resultView__titleMore { color: #a68ed2 }
|
.ffz-dark .resultView__titlesep.isActive .resultView__titleMore { color: #a68ed2 }
|
||||||
|
|
62
gulpfile.js
62
gulpfile.js
|
@ -14,7 +14,7 @@ var fs = require('fs'),
|
||||||
var jsEscape = require('gulp-js-escape'),
|
var jsEscape = require('gulp-js-escape'),
|
||||||
wrap = require('gulp-wrap'),
|
wrap = require('gulp-wrap'),
|
||||||
declare = require('gulp-declare'),
|
declare = require('gulp-declare'),
|
||||||
minifyCss = require('gulp-minify-css');
|
cleanCSS = require('gulp-clean-css');
|
||||||
|
|
||||||
|
|
||||||
// LESS
|
// LESS
|
||||||
|
@ -30,7 +30,7 @@ var ftp = require('vinyl-ftp'),
|
||||||
// Server Dependencies
|
// Server Dependencies
|
||||||
var http = require("http"),
|
var http = require("http"),
|
||||||
https = require("https"),
|
https = require("https"),
|
||||||
net = require('net'),
|
net = require('net'),
|
||||||
path = require("path"),
|
path = require("path"),
|
||||||
request = require("request"),
|
request = require("request"),
|
||||||
url = require("url");
|
url = require("url");
|
||||||
|
@ -69,8 +69,8 @@ gulp.task('prepare', ['clean'], function() {
|
||||||
//});
|
//});
|
||||||
|
|
||||||
gulp.task('styles', ['prepare'], function() {
|
gulp.task('styles', ['prepare'], function() {
|
||||||
return;
|
//return;
|
||||||
return gulp.src(['build/less/*.less'])
|
return gulp.src(['build/less/*.less', '!build/less/style.less'])
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(less())
|
.pipe(less())
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
|
@ -81,7 +81,7 @@ gulp.task('styles', ['prepare'], function() {
|
||||||
|
|
||||||
gulp.task('embedded_styles', ['prepare'], function() {
|
gulp.task('embedded_styles', ['prepare'], function() {
|
||||||
return gulp.src(['build/styles/**/*.css'])
|
return gulp.src(['build/styles/**/*.css'])
|
||||||
.pipe(minifyCss())
|
.pipe(cleanCSS())
|
||||||
.pipe(jsEscape())
|
.pipe(jsEscape())
|
||||||
.pipe(declare({
|
.pipe(declare({
|
||||||
root: 'exports',
|
root: 'exports',
|
||||||
|
@ -126,8 +126,8 @@ gulp.task('minify_script', ['scripts'], function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('minify_style', function() {
|
gulp.task('minify_style', function() {
|
||||||
return gulp.src(['style.css', 'dark.css'])
|
return gulp.src(['style.css', 'style-clips.css', 'dark.css', 'dark-clips.css'])
|
||||||
.pipe(minifyCss())
|
.pipe(cleanCSS())
|
||||||
.pipe(rename(function(path) {
|
.pipe(rename(function(path) {
|
||||||
path.basename += '.min';
|
path.basename += '.min';
|
||||||
}))
|
}))
|
||||||
|
@ -258,33 +258,33 @@ gulp.task('server', function() {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( fs.existsSync("dev_key.pem") ) {
|
if ( fs.existsSync("dev_key.pem") ) {
|
||||||
var https_options = {
|
var https_options = {
|
||||||
key: fs.readFileSync("dev_key.pem"),
|
key: fs.readFileSync("dev_key.pem"),
|
||||||
cert: fs.readFileSync("dev_cert.pem")
|
cert: fs.readFileSync("dev_cert.pem")
|
||||||
};
|
};
|
||||||
|
|
||||||
http.createServer(handle_req).listen(8001, "localhost");
|
http.createServer(handle_req).listen(8001, "localhost");
|
||||||
https.createServer(https_options, handle_req).listen(8002, "localhost");
|
https.createServer(https_options, handle_req).listen(8002, "localhost");
|
||||||
|
|
||||||
net.createServer(function(conn) {
|
net.createServer(function(conn) {
|
||||||
conn.on('error', function(e) {
|
conn.on('error', function(e) {
|
||||||
util.log("[" + util.colors.cyan("HTTP") + "] Connection Error: " + util.colors.magenta('' + e));
|
util.log("[" + util.colors.cyan("HTTP") + "] Connection Error: " + util.colors.magenta('' + e));
|
||||||
});
|
});
|
||||||
|
|
||||||
conn.once('data', function(buf) {
|
conn.once('data', function(buf) {
|
||||||
var address = (buf[0] === 22) ? 8002 : 8001;
|
var address = (buf[0] === 22) ? 8002 : 8001;
|
||||||
var proxy = net.createConnection(address, function() {
|
var proxy = net.createConnection(address, function() {
|
||||||
proxy.write(buf);
|
proxy.write(buf);
|
||||||
conn.pipe(proxy).pipe(conn);
|
conn.pipe(proxy).pipe(conn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).listen(8000);
|
}).listen(8000);
|
||||||
|
|
||||||
util.log("[" + util.colors.cyan("HTTPS") + "] Listening on Port: " + util.colors.magenta("8000"));
|
util.log("[" + util.colors.cyan("HTTPS") + "] Listening on Port: " + util.colors.magenta("8000"));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
http.createServer(handle_req).listen(8000, "localhost");
|
http.createServer(handle_req).listen(8000, "localhost");
|
||||||
util.log("[" + util.colors.cyan("HTTP") + "] Listening on Port: " + util.colors.magenta("8000"));
|
util.log("[" + util.colors.cyan("HTTP") + "] Listening on Port: " + util.colors.magenta("8000"));
|
||||||
}
|
}
|
||||||
});
|
});
|
24
package.json
24
package.json
|
@ -5,25 +5,25 @@
|
||||||
"description": "FrankerFaceZ gives Twitch users custom emoticons.",
|
"description": "FrankerFaceZ gives Twitch users custom emoticons.",
|
||||||
"main": "script.js",
|
"main": "script.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "^3.8.10",
|
"gulp": "^3.9.1",
|
||||||
"gulp-browserify": "^0.5.1",
|
"gulp-browserify": "^0.5.1",
|
||||||
"gulp-changed": "^1.1.0",
|
"gulp-changed": "^1.3.2",
|
||||||
"gulp-clean": "^0.3.1",
|
"gulp-clean": "^0.3.2",
|
||||||
"gulp-concat": "^2.4.3",
|
"gulp-clean-css": "^2.0.12",
|
||||||
|
"gulp-concat": "^2.6.0",
|
||||||
"gulp-declare": "^0.3.0",
|
"gulp-declare": "^0.3.0",
|
||||||
"gulp-filesize": "0.0.6",
|
"gulp-filesize": "0.0.6",
|
||||||
"gulp-footer": "^1.0.5",
|
"gulp-footer": "^1.0.5",
|
||||||
"gulp-header": "^1.2.2",
|
"gulp-header": "^1.8.8",
|
||||||
"gulp-js-escape": "^1.0.1",
|
"gulp-js-escape": "^1.0.1",
|
||||||
"gulp-less": "^3.1.0",
|
"gulp-less": "^3.1.0",
|
||||||
"gulp-minify-css": "^1.2.1",
|
"gulp-rename": "^1.2.2",
|
||||||
"gulp-rename": "^1.2.0",
|
|
||||||
"gulp-sourcemaps": "^1.6.0",
|
"gulp-sourcemaps": "^1.6.0",
|
||||||
"gulp-uglify": "^1.0.2",
|
"gulp-uglify": "^2.0.0",
|
||||||
"gulp-util": "^3.0.2",
|
"gulp-util": "^3.0.7",
|
||||||
"gulp-wrap": "^0.11.0",
|
"gulp-wrap": "^0.13.0",
|
||||||
"request": "^2.65.0",
|
"request": "^2.74.0",
|
||||||
"vinyl-ftp": "^0.4.5"
|
"vinyl-ftp": "^0.5.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -340,15 +340,25 @@ FFZ.prototype.get_badges = function(user, room_id, badges, msg) {
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.get_line_badges = function(msg) {
|
FFZ.prototype.get_line_badges = function(msg) {
|
||||||
|
var room = msg.get && msg.get('room') || msg.room,
|
||||||
|
from = msg.get && msg.get('from') || msg.from,
|
||||||
|
tags = msg.get && msg.get('tags') || msg.tags || {},
|
||||||
|
badge_tag = tags.badges || {};
|
||||||
|
|
||||||
|
// Twitch Badges
|
||||||
|
var badges = this.get_twitch_badges(badge_tag);
|
||||||
|
|
||||||
|
// FFZ Badges
|
||||||
|
return this.get_badges(from, room, badges, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype.get_twitch_badges = function(badge_tag) {
|
||||||
var badges = {},
|
var badges = {},
|
||||||
hidden_badges = this.settings.hidden_badges,
|
hidden_badges = this.settings.hidden_badges,
|
||||||
|
|
||||||
last_id = -1,
|
last_id = -1,
|
||||||
had_last = false,
|
had_last = false,
|
||||||
room = msg.get && msg.get('room') || msg.room,
|
|
||||||
from = msg.get && msg.get('from') || msg.from,
|
|
||||||
tags = msg.get && msg.get('tags') || msg.tags || {},
|
|
||||||
badge_tag = tags.badges || {},
|
|
||||||
|
|
||||||
service = utils.ember_lookup('service:badges'),
|
service = utils.ember_lookup('service:badges'),
|
||||||
badgeCollection = service && service.badgeCollection,
|
badgeCollection = service && service.badgeCollection,
|
||||||
|
@ -410,12 +420,11 @@ FFZ.prototype.get_line_badges = function(msg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FFZ Badges
|
return badges;
|
||||||
return this.get_badges(from, room, badges, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.get_other_badges = function(user_id, room_id, user_type, has_sub, has_turbo) {
|
/*FFZ.prototype.get_other_badges = function(user_id, room_id, user_type, has_sub, has_turbo) {
|
||||||
var badges = {};
|
var badges = {};
|
||||||
|
|
||||||
if ( room_id && user_id === room_id )
|
if ( room_id && user_id === room_id )
|
||||||
|
@ -435,7 +444,7 @@ FFZ.prototype.get_other_badges = function(user_id, room_id, user_type, has_sub,
|
||||||
badges[15] = {klass: 'turbo', title: 'Turbo'}
|
badges[15] = {klass: 'turbo', title: 'Turbo'}
|
||||||
|
|
||||||
return this.get_badges(user_id, room_id, badges, null);
|
return this.get_badges(user_id, room_id, badges, null);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -175,6 +175,46 @@ FFZ.ffz_commands.massmod = function(room, args) {
|
||||||
FFZ.ffz_commands.massmod.help = "Usage: /ffz massmod <list, of, users>\nBroadcaster only. Mod all the users in the provided list.";
|
FFZ.ffz_commands.massmod.help = "Usage: /ffz massmod <list, of, users>\nBroadcaster only. Mod all the users in the provided list.";
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Mass Unbanning
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
FFZ.prototype.get_banned_users = function() {
|
||||||
|
var f = this;
|
||||||
|
return new Promise(function(succeed, fail) {
|
||||||
|
var user = f.get_user();
|
||||||
|
if ( ! user )
|
||||||
|
return fail();
|
||||||
|
|
||||||
|
jQuery.get("/settings/channel").done(function(data) {
|
||||||
|
try {
|
||||||
|
var dom = new DOMParser().parseFromString(data, 'text/html'),
|
||||||
|
users = _.pluck(dom.querySelectorAll('.ban .obj'), 'textContent');
|
||||||
|
|
||||||
|
succeed(_.map(users, function(x) { return x.trim() }));
|
||||||
|
|
||||||
|
} catch(err) {
|
||||||
|
f.error("Failed to parse banned users", err);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(function(err) {
|
||||||
|
f.error("Failed to load banned users", err);
|
||||||
|
fail();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*FFZ.ffz_commands.massunban = function(room, args) {
|
||||||
|
var user = this.get_user();
|
||||||
|
if ( ! user || (user.login !== room.id && ! user.is_admin && ! user.is_staff) )
|
||||||
|
return "You must be the broadcaster to use massunban.";
|
||||||
|
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
/*FFZ.ffz_commands.massunban = function(room, args) {
|
/*FFZ.ffz_commands.massunban = function(room, args) {
|
||||||
args = args.join(" ").trim();
|
args = args.join(" ").trim();
|
||||||
|
|
||||||
|
|
|
@ -312,7 +312,7 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
|
|
||||||
// Let the browser's paste be do as it do if there weren't any emoji.
|
// Let the browser's paste be do as it do if there weren't any emoji.
|
||||||
if ( output.length === text.length )
|
if ( output.length === text.length )
|
||||||
return f.log("No emoji in paste");
|
return;
|
||||||
|
|
||||||
// Can we get the selection in our input box?
|
// Can we get the selection in our input box?
|
||||||
var input = this.get('chatTextArea'),
|
var input = this.get('chatTextArea'),
|
||||||
|
@ -321,7 +321,7 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
s_end = input && input.selectionEnd;
|
s_end = input && input.selectionEnd;
|
||||||
|
|
||||||
if ( ! input || typeof s_start !== "number" || typeof s_end !== "number" )
|
if ( ! input || typeof s_start !== "number" || typeof s_end !== "number" )
|
||||||
return f.log("Can't get input");
|
return;
|
||||||
|
|
||||||
// Still here? We're clear to inject this ourselves then.
|
// Still here? We're clear to inject this ourselves then.
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -717,6 +717,8 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
for(var i=0; i < suggestions.length; i++) {
|
for(var i=0; i < suggestions.length; i++) {
|
||||||
var suggestion = suggestions[i],
|
var suggestion = suggestions[i],
|
||||||
name = suggestion.id,
|
name = suggestion.id,
|
||||||
|
display_name = suggestion.displayName || (name && name.capitalize()),
|
||||||
|
username_match = display_name.trim().toLowerCase() === name,
|
||||||
alias = f.aliases[name];
|
alias = f.aliases[name];
|
||||||
|
|
||||||
if ( user_output[name] && ! user_output[name].is_alias ) {
|
if ( user_output[name] && ! user_output[name].is_alias ) {
|
||||||
|
@ -724,22 +726,43 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
token.whispered |= suggestion.whispered;
|
token.whispered |= suggestion.whispered;
|
||||||
if ( suggestion.timestamp > token.timestamp )
|
if ( suggestion.timestamp > token.timestamp )
|
||||||
token.timestamp = suggestion.timestamp;
|
token.timestamp = suggestion.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( user_output[display_name] && ! user_output[display_name].is_alias ) {
|
||||||
|
var token = user_output[display_name];
|
||||||
|
token.whispered |= suggestion.whispered;
|
||||||
|
if ( suggestion.timestamp > token.timestamp )
|
||||||
|
token.timestamp = suggestion.timestamp;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ( alias_setting !== 2 )
|
if ( alias_setting !== 2 ) {
|
||||||
output.push(user_output[name] = {
|
output.push(user_output[display_name] = {
|
||||||
type: "user",
|
type: "user",
|
||||||
command_content: name,
|
command_content: name,
|
||||||
label: FFZ.get_capitalization(name),
|
label: display_name,
|
||||||
|
alternate_match: username_match ? null : name,
|
||||||
whispered: suggestion.whispered,
|
whispered: suggestion.whispered,
|
||||||
timestamp: suggestion.timestamp || new Date(0),
|
timestamp: suggestion.timestamp || new Date(0),
|
||||||
info: 'User',
|
info: 'User' + (username_match ? '' : ' (' + name + ')'),
|
||||||
|
is_display_name: ! username_match,
|
||||||
is_alias: false
|
is_alias: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if ( ! username_match )
|
||||||
|
output.push(user_output[name] = {
|
||||||
|
type: "user",
|
||||||
|
label: name,
|
||||||
|
alternate_match: display_name,
|
||||||
|
whispered: suggestion.whispered,
|
||||||
|
timestamp: suggestion.timestamp || new Date(0),
|
||||||
|
info: 'User (' + display_name + ')',
|
||||||
|
is_alias: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if ( alias && alias_setting ) {
|
if ( alias && alias_setting ) {
|
||||||
if ( user_output[alias] && user_output[alias].is_alias ) {
|
if ( user_output[alias] && user_output[alias].is_alias ) {
|
||||||
var token = user_output[name];
|
var token = user_output[alias];
|
||||||
token.whispered |= suggestion.whispered;
|
token.whispered |= suggestion.whispered;
|
||||||
token.timestamp = Math.max(token.timestamp, suggestion.timestamp);
|
token.timestamp = Math.max(token.timestamp, suggestion.timestamp);
|
||||||
|
|
||||||
|
@ -750,7 +773,7 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
label: alias,
|
label: alias,
|
||||||
whispered: suggestion.whispered,
|
whispered: suggestion.whispered,
|
||||||
timestamp: suggestion.timestamp || new Date(0),
|
timestamp: suggestion.timestamp || new Date(0),
|
||||||
info: 'User Alias',
|
info: 'User Alias (' + name + ')',
|
||||||
is_alias: true
|
is_alias: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -779,7 +802,10 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
// Names are case insensitive, and we have to ignore the leading @ of our
|
// Names are case insensitive, and we have to ignore the leading @ of our
|
||||||
// partial word when matching.
|
// partial word when matching.
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
return char === '@' ? name.indexOf(part2.toLowerCase()) === 0 : name.indexOf(partial.toLowerCase()) === 0;
|
var part = (char === '@' ? part2 : partial).toLowerCase(),
|
||||||
|
alt_name = item.alternate_match;
|
||||||
|
|
||||||
|
return name.indexOf(part) === 0 || (alt_name && alt_name.indexOf(part) === 0);
|
||||||
|
|
||||||
} else if ( type === 'emoji' || ! f.settings.input_emoticons_case_sensitive ) {
|
} else if ( type === 'emoji' || ! f.settings.input_emoticons_case_sensitive ) {
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
|
@ -794,7 +820,9 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
ffz_sorted_suggestions: Ember.computed("ffz_filtered_suggestions.[]", function() {
|
ffz_sorted_suggestions: Ember.computed("ffz_filtered_suggestions.[]", function() {
|
||||||
var text = this.get('textareaValue'),
|
var text = this.get('textareaValue'),
|
||||||
now = Date.now(),
|
now = Date.now(),
|
||||||
is_whisper = text.substr(0,3) === '/w ';
|
char = text.charAt(0),
|
||||||
|
is_command = char === '/' || char === '.',
|
||||||
|
is_whisper = is_command && text.substr(1, 2) === 'w ';
|
||||||
|
|
||||||
return this.get('ffz_filtered_suggestions').sort(function(a, b) {
|
return this.get('ffz_filtered_suggestions').sort(function(a, b) {
|
||||||
// First off, sort users ahead of everything else.
|
// First off, sort users ahead of everything else.
|
||||||
|
@ -809,6 +837,11 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( a.is_display_name && ! b.is_display_name )
|
||||||
|
return -1;
|
||||||
|
else if ( ! a.is_display_name && b.is_display_name )
|
||||||
|
return 1;
|
||||||
|
|
||||||
if ( a.timestamp > b.timestamp ) return -1;
|
if ( a.timestamp > b.timestamp ) return -1;
|
||||||
else if ( a.timestamp < b.timestamp ) return 1;
|
else if ( a.timestamp < b.timestamp ) return 1;
|
||||||
|
|
||||||
|
|
|
@ -622,7 +622,7 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
if ( room && room._ffz_tab ) {
|
if ( room && room._ffz_tab ) {
|
||||||
room._ffz_tab.classList.remove('tab-mentioned');
|
room._ffz_tab.classList.remove('tab-mentioned');
|
||||||
room._ffz_tab.classList.add('active');
|
room._ffz_tab.classList.add('active');
|
||||||
var sp = room._ffz_tab.querySelector('span');
|
var sp = room._ffz_tab.querySelector('span:not(.intl-login)');
|
||||||
if ( sp )
|
if ( sp )
|
||||||
sp.innerHTML = '';
|
sp.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
@ -630,7 +630,7 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
if ( room && room._ffz_row ) {
|
if ( room && room._ffz_row ) {
|
||||||
room._ffz_row.classList.remove('row-mentioned');
|
room._ffz_row.classList.remove('row-mentioned');
|
||||||
room._ffz_row.classList.add('active');
|
room._ffz_row.classList.add('active');
|
||||||
var sp = room._ffz_row.querySelector('span');
|
var sp = room._ffz_row.querySelector('span:not(.intl-login)');
|
||||||
if ( sp )
|
if ( sp )
|
||||||
sp.innerHTML = '';
|
sp.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( row ) {
|
if ( row ) {
|
||||||
var sp = row.querySelector('span');
|
var sp = row.querySelector('span:not(.intl-login)');
|
||||||
if ( sp )
|
if ( sp )
|
||||||
sp.innerHTML = unread;
|
sp.innerHTML = unread;
|
||||||
}
|
}
|
||||||
|
@ -748,7 +748,7 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
if ( tab ) {
|
if ( tab ) {
|
||||||
var was_hidden = tab.classList.contains('hidden'),
|
var was_hidden = tab.classList.contains('hidden'),
|
||||||
is_hidden = ! this.ffzTabVisible(room_id),
|
is_hidden = ! this.ffzTabVisible(room_id),
|
||||||
sp = tab.querySelector('span');
|
sp = tab.querySelector('span:not(.intl-login)');
|
||||||
|
|
||||||
if ( was_hidden !== is_hidden ) {
|
if ( was_hidden !== is_hidden ) {
|
||||||
tab.classList.toggle('hidden', is_hidden);
|
tab.classList.toggle('hidden', is_hidden);
|
||||||
|
@ -909,10 +909,13 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
active_channel = room === this.get('controller.currentRoom'),
|
active_channel = room === this.get('controller.currentRoom'),
|
||||||
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount')),
|
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount')),
|
||||||
|
|
||||||
name = room.get('tmiRoom.displayName') || (group ? room.get('tmiRoom.name') : FFZ.get_capitalization(room_id, function(name) {
|
name = room.get('channel.display_name') || room.get('tmiRoom.displayName') || (group ? room.get('tmiRoom.name') : FFZ.get_capitalization(room_id, function(name) {
|
||||||
var active_channel = room === view.get('controller.currentRoom');
|
var active_channel = room === view.get('controller.currentRoom');
|
||||||
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
||||||
name_el.innerHTML = utils.sanitize(name) + ' <span>' + unread + '</span>';
|
var results = group ? [name, undefined] : f.format_display_name(name, room_id, true);
|
||||||
|
name_el.innerHTML = results[0] + ' <span>' + unread + '</span>';
|
||||||
|
if ( results[1] )
|
||||||
|
row.title += '<br>' + results[1];
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
@ -936,7 +939,11 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
name_el.className = 'ffz-room';
|
name_el.className = 'ffz-room';
|
||||||
name_el.innerHTML = utils.sanitize(name) + ' <span>' + unread + '</span>';
|
|
||||||
|
var results = group ? [name, undefined] : f.format_display_name(name, room_id, true);
|
||||||
|
name_el.innerHTML = results[0] + ' <span>' + unread + '</span>';
|
||||||
|
if ( results[1] )
|
||||||
|
row.title += '<br>' + results[1];
|
||||||
|
|
||||||
row.appendChild(icon);
|
row.appendChild(icon);
|
||||||
row.appendChild(name_el);
|
row.appendChild(name_el);
|
||||||
|
@ -1044,7 +1051,7 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
link.title = "Chat Room Management";
|
link.title = "Chat Room Management";
|
||||||
link.innerHTML = '<figure class="icon">' + constants.ROOMS + '</figure><span class="notifications"></span>';
|
link.innerHTML = '<figure class="icon">' + constants.ROOMS + '</figure><span class="notifications"></span>';
|
||||||
|
|
||||||
jQuery(link).tipsy({gravity: "n", offset: 5});
|
jQuery(link).tipsy({gravity: "n", offset: 10});
|
||||||
|
|
||||||
link.addEventListener('click', function() {
|
link.addEventListener('click', function() {
|
||||||
var controller = view.get('controller');
|
var controller = view.get('controller');
|
||||||
|
@ -1129,10 +1136,13 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
|
|
||||||
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
||||||
|
|
||||||
name = room.get('tmiRoom.displayName') || (group ? room.get('tmiRoom.name') : FFZ.get_capitalization(room_id, function(name) {
|
name = room.get('channel.display_name') || room.get('tmiRoom.displayName') || (group ? room.get('tmiRoom.name') : FFZ.get_capitalization(room_id, function(name) {
|
||||||
var active_channel = room === view.get('controller.currentRoom');
|
var active_channel = room === view.get('controller.currentRoom');
|
||||||
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
unread = utils.format_unread(active_channel ? 0 : room.get('unreadCount'));
|
||||||
tab.innerHTML = icon + utils.sanitize(name) + '<span>' + unread + '</span>';
|
var results = group ? [name, undefined] : f.format_display_name(name, room_id, true, true);
|
||||||
|
tab.innerHTML = icon + results[0] + '<span>' + unread + '</span>';
|
||||||
|
if ( results[1] )
|
||||||
|
tab.title += '<br>' + results[1];
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if ( current_channel ) {
|
if ( current_channel ) {
|
||||||
|
@ -1146,7 +1156,10 @@ FFZ.prototype.modify_chat_view = function(view) {
|
||||||
else
|
else
|
||||||
tab.title = "Pinned Channel";
|
tab.title = "Pinned Channel";
|
||||||
|
|
||||||
tab.innerHTML = icon + utils.sanitize(name) + '<span>' + unread + '</span>';
|
var results = group ? [name, undefined] : f.format_display_name(name, room_id, true, true);
|
||||||
|
tab.innerHTML = icon + results[0] + '<span>' + unread + '</span>';
|
||||||
|
if ( results[1] )
|
||||||
|
tab.title += '<br>' + results[1];
|
||||||
|
|
||||||
tab.addEventListener('click', function() {
|
tab.addEventListener('click', function() {
|
||||||
var controller = view.get('controller');
|
var controller = view.get('controller');
|
||||||
|
@ -1336,6 +1349,8 @@ FFZ.chat_commands.join = function(room, args) {
|
||||||
return "You have already joined " + room_id + ". Please use \"/part " + room_id + "\" to leave it.";
|
return "You have already joined " + room_id + ". Please use \"/part " + room_id + "\" to leave it.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.join.no_bttv = true;
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.part = function(room, args) {
|
FFZ.chat_commands.part = function(room, args) {
|
||||||
if ( this.has_bttv )
|
if ( this.has_bttv )
|
||||||
|
@ -1354,4 +1369,6 @@ FFZ.chat_commands.part = function(room, args) {
|
||||||
return "You do not have " + room_id + " pinned and you cannot leave the current channel or hosted channels via /part.";
|
return "You do not have " + room_id + " pinned and you cannot leave the current channel or hosted channels via /part.";
|
||||||
else
|
else
|
||||||
return "You are not in " + room_id + ".";
|
return "You are not in " + room_id + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.part.no_bttv = true;
|
|
@ -20,6 +20,7 @@ FFZ.settings_info.conv_focus_on_click = {
|
||||||
help: "Focus on a conversation's input box when you click it."
|
help: "Focus on a conversation's input box when you click it."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.top_conversations = {
|
FFZ.settings_info.top_conversations = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
@ -34,6 +35,37 @@ FFZ.settings_info.top_conversations = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.hide_whispers_in_embedded_chat = {
|
||||||
|
type: "boolean",
|
||||||
|
value: false,
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
category: "Whispers",
|
||||||
|
name: "Hide Whispers in Embedded Chat",
|
||||||
|
help: "Do not display whispers on the dashboard, in pop-out chat, or in chat embedded into other websites.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
if ( ! val || this.has_bttv )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(var room_id in this.rooms) {
|
||||||
|
var room = this.rooms[room_id].room;
|
||||||
|
if ( ! room )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var messages = room.get('messages'),
|
||||||
|
length = messages && messages.length || 0,
|
||||||
|
i = length;
|
||||||
|
|
||||||
|
while(--i >= 0) {
|
||||||
|
if ( messages[i] && messages[i].style === 'whisper' )
|
||||||
|
messages.removeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.hide_conversations_in_theatre = {
|
FFZ.settings_info.hide_conversations_in_theatre = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: false,
|
value: false,
|
||||||
|
@ -117,7 +149,7 @@ FFZ.prototype.modify_conversation_window = function(component) {
|
||||||
|
|
||||||
ffzHeaderBadges: Ember.computed("thread.participants", "currentUsername", function() {
|
ffzHeaderBadges: Ember.computed("thread.participants", "currentUsername", function() {
|
||||||
var e = this.get("otherUser");
|
var e = this.get("otherUser");
|
||||||
return f.get_other_badges(e.get('username'), null, e.get('userType'), false, e.get('hasTurbo'));
|
return f.get_badges(e.get('username'), null, f.get_twitch_badges(e.get('badges')), null);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
ffzReplaceBadges: function() {
|
ffzReplaceBadges: function() {
|
||||||
|
@ -125,13 +157,25 @@ FFZ.prototype.modify_conversation_window = function(component) {
|
||||||
badge_el = el && el.querySelector('.badges'),
|
badge_el = el && el.querySelector('.badges'),
|
||||||
badges = this.get('ffzHeaderBadges');
|
badges = this.get('ffzHeaderBadges');
|
||||||
|
|
||||||
|
if ( ! el )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( ! badge_el ) {
|
||||||
|
badge_el = createElement('span', 'badges');
|
||||||
|
var header = el && el.querySelector('.convoHeader .username');
|
||||||
|
if ( ! header )
|
||||||
|
return;
|
||||||
|
|
||||||
|
header.insertBefore(badge_el, header.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
badge_el.innerHTML = f.render_badges(badges);
|
badge_el.innerHTML = f.render_badges(badges);
|
||||||
}.observes('ffzHeaderBadges'),
|
}.observes('ffzHeaderBadges'),
|
||||||
|
|
||||||
ffz_init: function() {
|
ffz_init: function() {
|
||||||
var el = this.get('element'),
|
var el = this.get('element'),
|
||||||
header = el && el.querySelector('.conversation-header'),
|
header = el && el.querySelector('.convoHeader'),
|
||||||
header_name = header && header.querySelector('.conversation-header-name'),
|
header_name = header && header.querySelector('.username'),
|
||||||
|
|
||||||
raw_color = this.get('otherUser.color'),
|
raw_color = this.get('otherUser.color'),
|
||||||
colors = raw_color && f._handle_color(raw_color),
|
colors = raw_color && f._handle_color(raw_color),
|
||||||
|
|
|
@ -225,6 +225,7 @@ FFZ.prototype.setup_directory = function() {
|
||||||
this.update_views('component:stream-preview', function(x) { this.modify_directory_live(x, false) }, true);
|
this.update_views('component:stream-preview', function(x) { this.modify_directory_live(x, false) }, true);
|
||||||
this.update_views('component:creative-preview', function(x) { this.modify_directory_live(x, false) }, true);
|
this.update_views('component:creative-preview', function(x) { this.modify_directory_live(x, false) }, true);
|
||||||
this.update_views('component:csgo-channel-preview', function(x) { this.modify_directory_live(x, true) }, true);
|
this.update_views('component:csgo-channel-preview', function(x) { this.modify_directory_live(x, true) }, true);
|
||||||
|
this.update_views('component:twitch-carousel/stream-item', function(x) { this.modify_directory_live(x, false, true) }, true);
|
||||||
this.update_views('component:host-preview', this.modify_directory_host, true, true);
|
this.update_views('component:host-preview', this.modify_directory_host, true, true);
|
||||||
this.update_views('component:video-preview', this.modify_video_preview, true);
|
this.update_views('component:video-preview', this.modify_video_preview, true);
|
||||||
|
|
||||||
|
@ -418,16 +419,22 @@ FFZ.prototype.modify_game_follow_button = function(component) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.modify_directory_live = function(component, is_csgo) {
|
FFZ.prototype.modify_directory_live = function(component, is_csgo, is_card) {
|
||||||
var f = this,
|
var f = this,
|
||||||
pref = is_csgo ? 'channel.' : 'stream.';
|
pref = is_csgo ? 'channel.' : 'stream.',
|
||||||
|
|
||||||
|
meta_selector = is_card ? '.card__body' : '.meta',
|
||||||
|
thumb_selector = is_card ? '.card__img' : '.thumb',
|
||||||
|
cap_selector = is_card ? 'a:not(.card__boxpin)' : '.cap';
|
||||||
|
|
||||||
|
|
||||||
utils.ember_reopen_view(component, {
|
utils.ember_reopen_view(component, {
|
||||||
ffz_init: function() {
|
ffz_init: function() {
|
||||||
var el = this.get('element'),
|
var el = this.get('element'),
|
||||||
meta = el && el.querySelector('.meta'),
|
meta = el && el.querySelector(meta_selector),
|
||||||
thumb = el && el.querySelector('.thumb'),
|
thumb = el && el.querySelector(thumb_selector),
|
||||||
cap = thumb && thumb.querySelector('.cap'),
|
cap = thumb && thumb.querySelector(cap_selector),
|
||||||
|
uptime_parent = is_card ? thumb : cap,
|
||||||
channel_id = this.get(pref + 'channel.name'),
|
channel_id = this.get(pref + 'channel.name'),
|
||||||
game = this.get(pref + 'game');
|
game = this.get(pref + 'game');
|
||||||
|
|
||||||
|
@ -438,13 +445,13 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
|
||||||
el.classList.toggle('ffz-game-banned', f.settings.banned_games.indexOf(game && game.toLowerCase()) !== -1);
|
el.classList.toggle('ffz-game-banned', f.settings.banned_games.indexOf(game && game.toLowerCase()) !== -1);
|
||||||
el.classList.toggle('ffz-game-spoilered', f.settings.spoiler_games.indexOf(game && game.toLowerCase()) !== -1);
|
el.classList.toggle('ffz-game-spoilered', f.settings.spoiler_games.indexOf(game && game.toLowerCase()) !== -1);
|
||||||
|
|
||||||
if (f.settings.stream_uptime && f.settings.stream_uptime < 3 && cap ) {
|
if (f.settings.stream_uptime && f.settings.stream_uptime < 3 && uptime_parent ) {
|
||||||
var t_el = this._ffz_uptime = document.createElement('div');
|
var t_el = this._ffz_uptime = document.createElement('div');
|
||||||
t_el.className = 'overlay_info length live';
|
t_el.className = 'overlay_info length live';
|
||||||
|
|
||||||
jQuery(t_el).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')});
|
jQuery(t_el).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')});
|
||||||
|
|
||||||
cap.appendChild(t_el);
|
uptime_parent.appendChild(t_el);
|
||||||
this._ffz_uptime_timer = setInterval(this.ffzUpdateUptime.bind(this), 1000);
|
this._ffz_uptime_timer = setInterval(this.ffzUpdateUptime.bind(this), 1000);
|
||||||
this.ffzUpdateUptime();
|
this.ffzUpdateUptime();
|
||||||
}
|
}
|
||||||
|
@ -463,7 +470,7 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
|
||||||
logo.classList.toggle('is-csgo', is_csgo);
|
logo.classList.toggle('is-csgo', is_csgo);
|
||||||
|
|
||||||
logo.src = this.get(pref + 'channel.logo') || NO_LOGO;
|
logo.src = this.get(pref + 'channel.logo') || NO_LOGO;
|
||||||
logo.alt = this.get(pref + 'channel.display_name');
|
logo.alt = f.format_display_name(this.get(pref + 'channel.display_name'), channel_id, true, true)[0];
|
||||||
|
|
||||||
link.href = '/' + channel_id;
|
link.href = '/' + channel_id;
|
||||||
link.addEventListener('click', function(e) {
|
link.addEventListener('click', function(e) {
|
||||||
|
@ -510,9 +517,16 @@ FFZ.prototype.modify_directory_live = function(component, is_csgo) {
|
||||||
},
|
},
|
||||||
|
|
||||||
ffzUpdateUptime: function() {
|
ffzUpdateUptime: function() {
|
||||||
var raw_created = this.get(pref + 'created_at'),
|
var up_since;
|
||||||
up_since = raw_created && utils.parse_date(raw_created),
|
|
||||||
now = Date.now() - (f._ws_server_offset || 0),
|
if ( is_card )
|
||||||
|
up_since = this.get(pref + 'createdAt');
|
||||||
|
else {
|
||||||
|
var raw_created = this.get(pref + 'created_at');
|
||||||
|
up_since = raw_created && utils.parse_date(raw_created);
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = Date.now() - (f._ws_server_offset || 0),
|
||||||
uptime = up_since && Math.floor((now - up_since.getTime()) / 1000) || 0;
|
uptime = up_since && Math.floor((now - up_since.getTime()) / 1000) || 0;
|
||||||
|
|
||||||
if ( uptime > 0 ) {
|
if ( uptime > 0 ) {
|
||||||
|
@ -620,11 +634,13 @@ FFZ.prototype.modify_directory_host = function(component) {
|
||||||
|
|
||||||
var menu = document.createElement('div'), hdr,
|
var menu = document.createElement('div'), hdr,
|
||||||
make_link = function(target) {
|
make_link = function(target) {
|
||||||
var link = document.createElement('a');
|
var link = document.createElement('a'),
|
||||||
|
results = f.format_display_name(target.display_name, target.name, true);
|
||||||
|
|
||||||
link.className = 'dropmenu_action';
|
link.className = 'dropmenu_action';
|
||||||
link.setAttribute('data-channel', target.name);
|
link.setAttribute('data-channel', target.name);
|
||||||
link.href = '/' + target.name;
|
link.href = '/' + target.name;
|
||||||
link.innerHTML = '<img class="image" src="' + utils.sanitize(target.logo || NO_LOGO) + '"><span class="title">' + utils.sanitize(target.display_name) + '</span>';
|
link.innerHTML = '<img class="image" src="' + utils.sanitize(target.logo || NO_LOGO) + '"><span class="title' + (results[1] ? ' html-tooltip" title="' + utils.quote_attr(results[1]) : '') + '">' + results[0] + '</span>';
|
||||||
link.addEventListener('click', t.ffzVisitChannel.bind(t, target.name));
|
link.addEventListener('click', t.ffzVisitChannel.bind(t, target.name));
|
||||||
menu.appendChild(link);
|
menu.appendChild(link);
|
||||||
return link;
|
return link;
|
||||||
|
@ -709,7 +725,7 @@ FFZ.prototype.modify_directory_host = function(component) {
|
||||||
|
|
||||||
logo.className = 'profile-photo';
|
logo.className = 'profile-photo';
|
||||||
logo.src = this.get('stream.target.channel.logo') || NO_LOGO;
|
logo.src = this.get('stream.target.channel.logo') || NO_LOGO;
|
||||||
logo.alt = this.get('stream.target.channel.display_name');
|
logo.alt = f.format_display_name(target.display_name, target.name, true, true)[0];
|
||||||
|
|
||||||
link.href = '/' + target.name;
|
link.href = '/' + target.name;
|
||||||
link.addEventListener('click', this.ffzVisitChannel.bind(this, target.name));
|
link.addEventListener('click', this.ffzVisitChannel.bind(this, target.name));
|
||||||
|
|
|
@ -85,8 +85,9 @@ FFZ.prototype.setup_profile_following = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
success(result);
|
success(result);
|
||||||
|
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
fail(result);
|
fail(err);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -131,15 +132,14 @@ FFZ.prototype.modify_display_followed_item = function(component) {
|
||||||
|
|
||||||
el.classList.add('ffz-processed');
|
el.classList.add('ffz-processed');
|
||||||
|
|
||||||
// TODO: REMOVE
|
jQuery('.aspect', el).tipsy();
|
||||||
window._d = this;
|
|
||||||
|
|
||||||
if ( ! data )
|
if ( ! data )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var now = Date.now() - (f._ws_server_offset || 0),
|
var now = Date.now() - (f._ws_server_offset || 0),
|
||||||
age = data[0] ? Math.floor((now - data[0].getTime()) / 1000) : 0,
|
age = data[0] ? Math.floor((now - data[0].getTime()) / 1000) : 0,
|
||||||
t_el = createElement('div', 'overlay_info length'),
|
t_el = createElement('div', 'overlay_info length html-tooltip'),
|
||||||
|
|
||||||
update_time = function() {
|
update_time = function() {
|
||||||
var now = Date.now() - (f._ws_server_offset || 0),
|
var now = Date.now() - (f._ws_server_offset || 0),
|
||||||
|
@ -154,7 +154,6 @@ FFZ.prototype.modify_display_followed_item = function(component) {
|
||||||
};
|
};
|
||||||
|
|
||||||
update_time();
|
update_time();
|
||||||
jQuery(t_el).tipsy({html:true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')});
|
|
||||||
el.appendChild(t_el);
|
el.appendChild(t_el);
|
||||||
|
|
||||||
if ( ! mine || ! is_following )
|
if ( ! mine || ! is_following )
|
||||||
|
@ -162,7 +161,7 @@ FFZ.prototype.modify_display_followed_item = function(component) {
|
||||||
|
|
||||||
var actions = createElement('div', 'actions'),
|
var actions = createElement('div', 'actions'),
|
||||||
follow = createElement('button', 'button ffz-no-bg follow'),
|
follow = createElement('button', 'button ffz-no-bg follow'),
|
||||||
notif = createElement('button', 'button ffz-no-bg notifications'),
|
notif = createElement('button', 'button ffz-no-bg notifications html-tooltip'),
|
||||||
|
|
||||||
update_follow = function() {
|
update_follow = function() {
|
||||||
data = user_cache[user_id];
|
data = user_cache[user_id];
|
||||||
|
@ -173,7 +172,9 @@ FFZ.prototype.modify_display_followed_item = function(component) {
|
||||||
update_notif = function() {
|
update_notif = function() {
|
||||||
data = user_cache[user_id];
|
data = user_cache[user_id];
|
||||||
notif.classList.toggle('notifications-on', data && data[1]);
|
notif.classList.toggle('notifications-on', data && data[1]);
|
||||||
notif.textContent = 'Notification ' + (data && data[1] ? 'On' : 'Off');
|
notif.textContent = 'Notifications'; // ' + (data && data[1] ? 'On' : 'Off');
|
||||||
|
notif.setAttribute('original-title', 'Email Notifications: ' + (data && data[1] ? 'En' : 'Dis') + 'abled');
|
||||||
|
jQuery(notif).trigger('mouseout');
|
||||||
};
|
};
|
||||||
|
|
||||||
update_follow();
|
update_follow();
|
||||||
|
|
|
@ -22,6 +22,50 @@ FFZ.settings_info.alias_italics = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FFZ.settings_info.username_display = {
|
||||||
|
type: "select",
|
||||||
|
options: {
|
||||||
|
0: "Username Only",
|
||||||
|
1: "Capitalization Only",
|
||||||
|
2: "Display Name Only",
|
||||||
|
3: "Username in Parenthesis",
|
||||||
|
4: "Username in Tooltip"
|
||||||
|
},
|
||||||
|
|
||||||
|
category: "Chat Appearance",
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
name: "Username Display",
|
||||||
|
help: "How a user's name should be rendered when their display name differs from the username.",
|
||||||
|
|
||||||
|
value: 3,
|
||||||
|
|
||||||
|
process_value: function(val) {
|
||||||
|
if ( typeof val === "string" ) {
|
||||||
|
val = parseInt(val);
|
||||||
|
if ( isNaN(val) || ! isFinite(val) )
|
||||||
|
val = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
var CL = utils.ember_resolve('component:chat/chat-line'),
|
||||||
|
views = CL ? utils.ember_views() : [];
|
||||||
|
|
||||||
|
for(var vid in views) {
|
||||||
|
var view = views[vid];
|
||||||
|
if ( view instanceof CL && view.buildFromHTML ) {
|
||||||
|
view.$('.from').replaceWith(view.buildFromHTML());
|
||||||
|
if ( view.get('msgObject.to') )
|
||||||
|
view.$('.to').replaceWith(view.buildFromHTML(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.room_status = {
|
FFZ.settings_info.room_status = {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: true,
|
value: true,
|
||||||
|
@ -768,27 +812,27 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
return output + '</span>';
|
return output + '</span>';
|
||||||
},
|
},
|
||||||
|
|
||||||
buildSenderHTML: function() {
|
buildFromHTML: function(is_recipient) {
|
||||||
var user = this.get('msgObject.from'),
|
var username = this.get(is_recipient ? 'msgObject.to' : 'msgObject.from'),
|
||||||
room_id = this.get('msgObject.room'),
|
raw_display = this.get(is_recipient ? 'msgObject.tags.recipient-display-name' : 'msgObject.tags.display-name'),
|
||||||
room = f.rooms && f.rooms[room_id],
|
alias = f.aliases[username],
|
||||||
|
|
||||||
deleted = this.get('msgObject.deleted'),
|
raw_color = this.get(is_recipient ? 'msgObject.toColor' : 'msgObject.color'),
|
||||||
r = this,
|
|
||||||
|
|
||||||
recipient = this.get('msgObject.to'),
|
|
||||||
is_whisper = recipient && recipient.length,
|
|
||||||
is_replay = this.get('ffz_is_replay'),
|
|
||||||
|
|
||||||
this_ul = this.get('ffzUserLevel'),
|
|
||||||
other_ul = room && room.room && room.room.get('ffzUserLevel') || 0,
|
|
||||||
|
|
||||||
raw_color = this.get('msgObject.color'),
|
|
||||||
colors = raw_color && f._handle_color(raw_color),
|
|
||||||
|
|
||||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (is_replay ? f.settings.dark_twitch : (Settings && Settings.get('settings.darkMode'))),
|
is_dark = (Layout && Layout.get('isTheatreMode')) || (is_replay ? f.settings.dark_twitch : (Settings && Settings.get('settings.darkMode'))),
|
||||||
|
is_replay = this.get('ffz_is_replay'),
|
||||||
|
|
||||||
system_msg = this.get('systemMsg'),
|
colors = raw_color && f._handle_color(raw_color),
|
||||||
|
style = colors ? 'color:' + (is_dark ? colors[1] : colors[0]) : '',
|
||||||
|
colored = colors ? ' has-color' + (is_replay ? ' replay-color' : '') : '',
|
||||||
|
|
||||||
|
results = f.format_display_name(raw_display, username);
|
||||||
|
|
||||||
|
return '<span class="' + (is_recipient ? 'to' : 'from') + (alias ? ' ffz-alias' : '') + (results[1] ? ' html-tooltip' : '') + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + (results[1] ? '" title="' + utils.quote_attr(results[1]) : '') + '">' + results[0] + '</span>';
|
||||||
|
},
|
||||||
|
|
||||||
|
buildSenderHTML: function() {
|
||||||
|
var system_msg = this.get('systemMsg'),
|
||||||
output = '';
|
output = '';
|
||||||
|
|
||||||
output = '<div class="indicator"></div>';
|
output = '<div class="indicator"></div>';
|
||||||
|
@ -809,41 +853,15 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
// Badges
|
// Badges
|
||||||
output += '<span class="badges">' + f.render_badges(f.get_line_badges(this.get('msgObject'))) + '</span>';
|
output += '<span class="badges">' + f.render_badges(f.get_line_badges(this.get('msgObject'))) + '</span>';
|
||||||
|
|
||||||
// Alias Support
|
// From!
|
||||||
var alias = f.aliases[user],
|
output += this.buildFromHTML();
|
||||||
name = this.get('msgObject.tags.display-name') || (user && user.capitalize()) || "unknown user",
|
|
||||||
style = colors && 'color:' + (is_dark ? colors[1] : colors[0]) || '',
|
|
||||||
colored = style ? ' has-color' + (is_replay ? ' replay-color' : '') : '';
|
|
||||||
|
|
||||||
output += '<span class="from' + (alias ? ' ffz-alias html-tooltip' : '') + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '');
|
if ( this.get('msgObject.to') ) {
|
||||||
|
output += "<svg class='svg-whisper-arrow' height='10px' version='1.1' width='16px'><polyline points='6 2, 10 6, 6 10, 6 2' /></svg>";
|
||||||
if ( alias )
|
output += this.buildFromHTML(true);
|
||||||
output += '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias);
|
|
||||||
else
|
|
||||||
output += '">' + utils.sanitize(name);
|
|
||||||
|
|
||||||
|
|
||||||
// Whisper Legacy Sucks
|
|
||||||
if ( is_whisper ) {
|
|
||||||
var to_alias = f.aliases[recipient],
|
|
||||||
to_name = this.get('msgObject.tags.recipient-display-name') || (recipient && recipient.capitalize()) || "unknown user",
|
|
||||||
|
|
||||||
to_color = this.get('msgObject.toColor'),
|
|
||||||
to_colors = to_color && f._handle_color(to_color),
|
|
||||||
|
|
||||||
to_style = to_color ? 'color:' + (is_dark ? to_colors[1] : to_colors[0]) : '',
|
|
||||||
to_colored = to_style ? ' has-color' : '';
|
|
||||||
|
|
||||||
output += "</span><svg class='svg-whisper-arrow' height='10px' version='1.1' width='16px'><polyline points='6 2, 10 6, 6 10, 6 2' /></svg>";
|
|
||||||
output += '<span class="to' + (to_alias ? ' ffz-alias html-tooltip' : '') + to_colored + '" style="' + to_style + (to_colors ? '" data=color="' + to_color : '');
|
|
||||||
|
|
||||||
if ( to_alias )
|
|
||||||
output += '" title="' + utils.quote_san(to_name) + '">' + utils.sanitize(to_alias);
|
|
||||||
else
|
|
||||||
output += '">' + utils.sanitize(to_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output + '</span><span class="colon">:</span> ';
|
return output + '<span class="colon">:</span> ';
|
||||||
},
|
},
|
||||||
|
|
||||||
buildDeletedMessageHTML: function() {
|
buildDeletedMessageHTML: function() {
|
||||||
|
@ -917,7 +935,7 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
||||||
this._modify_chat_line(component);
|
this._modify_chat_line(component);
|
||||||
|
|
||||||
component.reopen({
|
component.reopen({
|
||||||
classNameBindings: ["msgObject.style", "msgObject.ffz_has_mention:ffz-mentioned", "ffzWasDeleted:ffz-deleted", "ffzHasOldMessages:clearfix", "ffzHasOldMessages:ffz-has-deleted"],
|
classNameBindings: ["msgObject.style", "msgObject.isModerationMessage:moderation-message", "msgObject.ffz_has_mention:ffz-mentioned", "ffzWasDeleted:ffz-deleted", "ffzHasOldMessages:clearfix", "ffzHasOldMessages:ffz-has-deleted"],
|
||||||
attributeBindings: ["msgObject.tags.id:data-id", "msgObject.room:data-room", "msgObject.from:data-sender", "msgObject.deleted:data-deleted"],
|
attributeBindings: ["msgObject.tags.id:data-id", "msgObject.room:data-room", "msgObject.from:data-sender", "msgObject.deleted:data-deleted"],
|
||||||
|
|
||||||
didInsertElement: function() {
|
didInsertElement: function() {
|
||||||
|
@ -989,7 +1007,7 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
||||||
} else if ( f._click_emote(e.target, e) )
|
} else if ( f._click_emote(e.target, e) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
else if ( e.target.classList.contains('from') ) {
|
else if ( e.target.classList.contains('from') || e.target.parentElement.classList.contains('from') ) {
|
||||||
var n = this.get('element'),
|
var n = this.get('element'),
|
||||||
bounds = n && n.getBoundingClientRect() || document.body.getBoundingClientRect(),
|
bounds = n && n.getBoundingClientRect() || document.body.getBoundingClientRect(),
|
||||||
x = 0, right;
|
x = 0, right;
|
||||||
|
@ -1005,6 +1023,22 @@ FFZ.prototype._modify_chat_subline = function(component) {
|
||||||
sender: from
|
sender: from
|
||||||
});
|
});
|
||||||
|
|
||||||
|
} else if ( e.target.classList.contains('to') || e.target.parentElement.classList.contains('to') ) {
|
||||||
|
var n = this.get('element'),
|
||||||
|
bounds = n && n.getBoundingClientRect() || document.body.getBoundingClientRect(),
|
||||||
|
x = 0, right;
|
||||||
|
|
||||||
|
if ( bounds.left > 400 )
|
||||||
|
right = bounds.left - 40;
|
||||||
|
|
||||||
|
this.sendAction("showModOverlay", {
|
||||||
|
left: bounds.left,
|
||||||
|
right: right,
|
||||||
|
top: bounds.top + bounds.height,
|
||||||
|
real_top: bounds.top,
|
||||||
|
sender: this.get('msgObject.to')
|
||||||
|
});
|
||||||
|
|
||||||
} else if ( e.target.classList.contains('undelete') ) {
|
} else if ( e.target.classList.contains('undelete') ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.set("msgObject.deleted", false);
|
this.set("msgObject.deleted", false);
|
||||||
|
|
|
@ -661,13 +661,6 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
||||||
info.innerHTML = out;
|
info.innerHTML = out;
|
||||||
}.observes("cardInfo.user.views"),
|
}.observes("cardInfo.user.views"),
|
||||||
|
|
||||||
userName: Ember.computed("cardInfo.user.id", "cardInfo.user.display_name", function() {
|
|
||||||
var user_id = this.get("cardInfo.user.id"),
|
|
||||||
alias = f.aliases[user_id];
|
|
||||||
|
|
||||||
return alias || this.get("cardInfo.user.display_name") || user_id.capitalize();
|
|
||||||
}),
|
|
||||||
|
|
||||||
ffz_destroy: function() {
|
ffz_destroy: function() {
|
||||||
if ( f._mod_card === this )
|
if ( f._mod_card === this )
|
||||||
f._mod_card = undefined;
|
f._mod_card = undefined;
|
||||||
|
@ -724,15 +717,15 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
||||||
|
|
||||||
// Alias Display
|
// Alias Display
|
||||||
if ( alias ) {
|
if ( alias ) {
|
||||||
var name = el.querySelector('h3.name'),
|
var name = el.querySelector('h4.name a');
|
||||||
link = name && name.querySelector('a');
|
|
||||||
|
|
||||||
if ( link )
|
|
||||||
name = link;
|
|
||||||
if ( name ) {
|
if ( name ) {
|
||||||
name.classList.add('ffz-alias');
|
name.classList.add('ffz-alias');
|
||||||
name.title = utils.sanitize(controller.get('cardInfo.user.display_name') || user_id.capitalize());
|
var results = f.format_display_name(controller.get('cardInfo.user.display_name'), user_id);
|
||||||
jQuery(name).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
|
||||||
|
name.innerHTML = results[0];
|
||||||
|
name.title = results[1] || '';
|
||||||
|
if ( results[1] )
|
||||||
|
jQuery(name).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,7 +735,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
||||||
// Info-tize it!
|
// Info-tize it!
|
||||||
if ( f.settings.mod_card_info ) {
|
if ( f.settings.mod_card_info ) {
|
||||||
var info = utils.createElement('div', 'info channel-stats'),
|
var info = utils.createElement('div', 'info channel-stats'),
|
||||||
after = el.querySelector('h3.name');
|
after = el.querySelector('h4.name');
|
||||||
if ( after ) {
|
if ( after ) {
|
||||||
el.classList.add('ffz-has-info');
|
el.classList.add('ffz-has-info');
|
||||||
after.parentElement.insertBefore(info, after.nextSibling);
|
after.parentElement.insertBefore(info, after.nextSibling);
|
||||||
|
@ -995,10 +988,11 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
||||||
|
|
||||||
alias_btn.addEventListener('click', function() {
|
alias_btn.addEventListener('click', function() {
|
||||||
var user = controller.get('cardInfo.user.id'),
|
var user = controller.get('cardInfo.user.id'),
|
||||||
alias = f.aliases[user];
|
alias = f.aliases[user],
|
||||||
|
results = f.format_display_name(controller.get('cardInfo.user.display_name'), user, true);
|
||||||
|
|
||||||
utils.prompt(
|
utils.prompt(
|
||||||
"Alias for <b>" + utils.sanitize(controller.get('cardInfo.user.display_name') || user) + "</b>",
|
"Alias for <b" + (results[1] ? ' class="html-tooltip" title="' + utils.quote_attr(results[1]) + '">' : '>') + results[0] + "</b>",
|
||||||
"Please enter an alias for the user. Leave it blank to remove the alias.",
|
"Please enter an alias for the user. Leave it blank to remove the alias.",
|
||||||
alias,
|
alias,
|
||||||
function(new_val) {
|
function(new_val) {
|
||||||
|
@ -1015,10 +1009,16 @@ FFZ.prototype.modify_moderation_card = function(component) {
|
||||||
// Update UI
|
// Update UI
|
||||||
f._update_alias(user);
|
f._update_alias(user);
|
||||||
|
|
||||||
Ember.propertyDidChange(controller, 'cardInfo.user.display_name');
|
var name = el.querySelector('h4.name');
|
||||||
var name = el.querySelector('h3.name');
|
if ( name ) {
|
||||||
if ( name )
|
|
||||||
name.classList.toggle('ffz-alias', new_val);
|
name.classList.toggle('ffz-alias', new_val);
|
||||||
|
var results = f.format_display_name(controller.get('cardInfo.user.display_name'), user_id);
|
||||||
|
|
||||||
|
name.innerHTML = results[0];
|
||||||
|
name.title = results[1] || '';
|
||||||
|
if ( results[1] )
|
||||||
|
jQuery(name).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1256,11 +1256,10 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
||||||
if ( helpers && helpers.getTime )
|
if ( helpers && helpers.getTime )
|
||||||
out.push('<span class="timestamp">' + helpers.getTime(msg.date) + '</span>');
|
out.push('<span class="timestamp">' + helpers.getTime(msg.date) + '</span>');
|
||||||
|
|
||||||
|
|
||||||
var alias = this.aliases[msg.from],
|
|
||||||
name = (msg.tags && msg.tags['display-name']) || (msg.from && msg.from.capitalize()) || "unknown user";
|
|
||||||
|
|
||||||
if ( show_from ) {
|
if ( show_from ) {
|
||||||
|
var alias = this.aliases[msg.from],
|
||||||
|
results = this.format_display_name(msg.tags && msg.tags['display-name'], msg.from);
|
||||||
|
|
||||||
// Badges
|
// Badges
|
||||||
out.push('<span class="badges">');
|
out.push('<span class="badges">');
|
||||||
out.push(this.render_badges(this.get_line_badges(msg, false)));
|
out.push(this.render_badges(this.get_line_badges(msg, false)));
|
||||||
|
@ -1277,15 +1276,18 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
||||||
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
is_dark = (Layout && Layout.get('isTheatreMode')) || (Settings && Settings.get('settings.darkMode'));
|
||||||
|
|
||||||
|
|
||||||
// Aliases and Styling
|
// Styling
|
||||||
var style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
var style = colors && 'color:' + (is_dark ? colors[1] : colors[0]),
|
||||||
colored = style ? ' has-color' : '';
|
colored = style ? ' has-color' : '';
|
||||||
|
|
||||||
|
out.push('<span class="from' +
|
||||||
if ( alias )
|
(alias ? ' ffz-alias' : '') +
|
||||||
out.push('<span class="from ffz-alias html-tooltip' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '" title="' + utils.quote_san(name) + '">' + utils.sanitize(alias) + '</span>');
|
(results[1] ? ' html-tooltip' : '') +
|
||||||
else
|
(style ? ' has-color' : '') +
|
||||||
out.push('<span class="from' + colored + '" style="' + style + (colors ? '" data-color="' + raw_color : '') + '">' + utils.sanitize(name) + '</span>');
|
'" style="' + style + '"' +
|
||||||
|
(colors ? ' data-color="' + raw_color + '"' : '') +
|
||||||
|
(results[1] ? ' title="' + utils.quote_attr(results[1]) + '"' : '') + '>'
|
||||||
|
+ results[0] + '</span>');
|
||||||
|
|
||||||
out.push('<span class="colon">:</span> ');
|
out.push('<span class="colon">:</span> ');
|
||||||
}
|
}
|
||||||
|
@ -1367,8 +1369,8 @@ FFZ.prototype._build_mod_card_history = function(msg, modcard, show_from) {
|
||||||
|
|
||||||
FFZ.prototype._update_alias = function(user) {
|
FFZ.prototype._update_alias = function(user) {
|
||||||
var alias = this.aliases && this.aliases[user],
|
var alias = this.aliases && this.aliases[user],
|
||||||
cap_name = FFZ.get_capitalization(user),
|
results = this.format_display_name(FFZ.get_capitalization(user), user),
|
||||||
display_name = alias || cap_name,
|
|
||||||
el = this._roomv && this._roomv.get('element'),
|
el = this._roomv && this._roomv.get('element'),
|
||||||
lines = el && el.querySelectorAll('.chat-line[data-sender="' + user + '"]');
|
lines = el && el.querySelectorAll('.chat-line[data-sender="' + user + '"]');
|
||||||
|
|
||||||
|
@ -1383,8 +1385,9 @@ FFZ.prototype._update_alias = function(user) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
el_from.classList.toggle('ffz-alias', alias);
|
el_from.classList.toggle('ffz-alias', alias);
|
||||||
el_from.textContent = display_name;
|
el_from.classList.toggle('html-tooltip', results[1] || false);
|
||||||
el_from.title = alias ? cap_name : '';
|
el_from.innerHTML = results[0];
|
||||||
|
el_from.title = results[1] || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1402,16 +1405,12 @@ FFZ.prototype._update_alias = function(user) {
|
||||||
|
|
||||||
FFZ.chat_commands.purge = function(room, args) {
|
FFZ.chat_commands.purge = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
return "Purge Usage: /p username [more usernames separated by spaces]";
|
return "Purge Usage: /p username [ban reason]";
|
||||||
|
|
||||||
if ( args.length > 10 )
|
var name = args.shift(),
|
||||||
return "Please only purge up to 10 users at once.";
|
reason = args.length ? args.join(" ") : "";
|
||||||
|
|
||||||
for(var i=0; i < args.length; i++) {
|
room.room.send("/timeout " + name + " 1 " + reason, true);
|
||||||
var name = args[i];
|
|
||||||
if ( name )
|
|
||||||
room.room.send("/timeout " + name + " 1", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.p = function(room, args) {
|
FFZ.chat_commands.p = function(room, args) {
|
||||||
|
@ -1423,7 +1422,7 @@ FFZ.chat_commands.p.enabled = function() { return this.settings.short_commands;
|
||||||
|
|
||||||
FFZ.chat_commands.t = function(room, args) {
|
FFZ.chat_commands.t = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
return "Timeout Usage: /t username [duration]";
|
return "Timeout Usage: /t username [duration] [ban reason]";
|
||||||
room.room.send("/timeout " + args.join(" "), true);
|
room.room.send("/timeout " + args.join(" "), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1432,16 +1431,12 @@ FFZ.chat_commands.t.enabled = function() { return this.settings.short_commands;
|
||||||
|
|
||||||
FFZ.chat_commands.b = function(room, args) {
|
FFZ.chat_commands.b = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
return "Ban Usage: /b username [more usernames separated by spaces]";
|
return "Ban Usage: /b username [ban reason]";
|
||||||
|
|
||||||
if ( args.length > 10 )
|
var name = args.shift(),
|
||||||
return "Please only ban up to 10 users at once.";
|
reason = args.length ? args.join(" ") : "";
|
||||||
|
|
||||||
for(var i=0; i < args.length; i++) {
|
room.room.send("/ban " + name + " " + reason, true);
|
||||||
var name = args[i];
|
|
||||||
if ( name )
|
|
||||||
room.room.send("/ban " + name, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.b.enabled = function() { return this.settings.short_commands; }
|
FFZ.chat_commands.b.enabled = function() { return this.settings.short_commands; }
|
||||||
|
|
|
@ -165,6 +165,7 @@ FFZ.prototype.modify_twitch_player = function(player) {
|
||||||
this.$('#video-1').html('');
|
this.$('#video-1').html('');
|
||||||
Mousetrap.unbind(['alt+x', 'alt+t', 'esc']);
|
Mousetrap.unbind(['alt+x', 'alt+t', 'esc']);
|
||||||
this.set('player', null);
|
this.set('player', null);
|
||||||
|
this.set('ffz_post_player', false);
|
||||||
|
|
||||||
// Now, let Twitch create a new player as usual.
|
// Now, let Twitch create a new player as usual.
|
||||||
Ember.run.next(this.insertPlayer.bind(this, true));
|
Ember.run.next(this.insertPlayer.bind(this, true));
|
||||||
|
|
|
@ -4,13 +4,24 @@ var FFZ = window.FrankerFaceZ,
|
||||||
utils = require('../utils'),
|
utils = require('../utils'),
|
||||||
helpers,
|
helpers,
|
||||||
|
|
||||||
|
NOTICE_MAPPING = {
|
||||||
|
'slow': 'slow_on',
|
||||||
|
'slowoff': 'slow_off',
|
||||||
|
'r9kbeta': 'r9k_on',
|
||||||
|
'r9kbetaoff': 'r9k_off',
|
||||||
|
'subscribers': 'subs_on',
|
||||||
|
'subscribersoff': 'subs_off',
|
||||||
|
'emoteonly': 'emote_only_on',
|
||||||
|
'emoteonlyoff': 'emote_only_off'
|
||||||
|
},
|
||||||
|
|
||||||
STATUS_BADGES = [
|
STATUS_BADGES = [
|
||||||
["r9k", "r9k", "This room is in R9K-mode."],
|
["r9k", "r9k", "This room is in R9K-mode."],
|
||||||
["emote", "emoteOnly", "This room is in Twitch emoticons only mode. Emoticons added by extensions are not available in this mode."],
|
["emote", "emoteOnly", "This room is in Twitch emoticons only mode. Emoticons added by extensions are not available in this mode."],
|
||||||
["sub", "subsOnly", "This room is in subscribers-only mode."],
|
["sub", "subsOnly", "This room is in subscribers-only mode."],
|
||||||
["slow", "slow", function(room) { return "This room is in slow mode. You may send messages every " + utils.number_commas(room && room.get('slow') || 120) + " seconds." }],
|
["slow", "slow", function(room) { return "This room is in slow mode. You may send messages every " + utils.number_commas(room && room.get('slow') || 120) + " seconds." }],
|
||||||
["ban", "ffz_banned", "You have been banned from talking in this room."],
|
["ban", "ffz_banned", "You have been banned from talking in this room."],
|
||||||
["delay", function(room) { return room && room.get('ffz_chat_delay') !== 0 }, function(room) { return "Artificial chat delay is enabled. Messages are displayed after " + (room.get('ffz_chat_delay')/1000) + " seconds." }],
|
["delay", function(room) { return room && room.get('ffz_chat_delay') !== 0 }, function(room) { return "Artificial chat delay is enabled. Messages are displayed after " + (room ? room.get('ffz_chat_delay')/1000 : 0) + " seconds." }],
|
||||||
["batch", function() { return this.settings.chat_batching !== 0 }, function() { return "You have enabled chat message batching. Messages are displayed in " + (this.settings.chat_batching/1000) + " second increments." }]
|
["batch", function() { return this.settings.chat_batching !== 0 }, function() { return "You have enabled chat message batching. Messages are displayed in " + (this.settings.chat_batching/1000) + " second increments." }]
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -38,15 +49,24 @@ FFZ.prototype.setup_room = function() {
|
||||||
this.rooms = {};
|
this.rooms = {};
|
||||||
|
|
||||||
this.log("Creating room style element.");
|
this.log("Creating room style element.");
|
||||||
var s = this._room_style = document.createElement("style");
|
var f = this,
|
||||||
|
s = this._room_style = document.createElement("style");
|
||||||
|
|
||||||
s.id = "ffz-room-css";
|
s.id = "ffz-room-css";
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
|
|
||||||
|
this.log("Hooking the Ember Chat PubSub service.");
|
||||||
|
var PubSub = utils.ember_lookup('service:chat-pubsub');
|
||||||
|
|
||||||
|
if ( PubSub )
|
||||||
|
this._modify_chat_pubsub(PubSub);
|
||||||
|
else
|
||||||
|
this.error("Cannot locate the Chat PubSub service.");
|
||||||
|
|
||||||
this.log("Hooking the Ember Room controller.");
|
this.log("Hooking the Ember Room controller.");
|
||||||
|
|
||||||
// Responsive ban button.
|
// Responsive ban button.
|
||||||
var f = this,
|
var RC = utils.ember_lookup('controller:room');
|
||||||
RC = utils.ember_lookup('controller:room');
|
|
||||||
|
|
||||||
if ( RC ) {
|
if ( RC ) {
|
||||||
var orig_ban = RC._actions.banUser,
|
var orig_ban = RC._actions.banUser,
|
||||||
|
@ -119,6 +139,120 @@ FFZ.prototype.setup_room = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// PubSub is fucking awful
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
FFZ.prototype._modify_chat_pubsub = function(pubsub) {
|
||||||
|
var f = this;
|
||||||
|
pubsub.reopen({
|
||||||
|
setupService: function(room_id, t) {
|
||||||
|
var n = this;
|
||||||
|
this.get("session").withCurrentUser(function(user) {
|
||||||
|
if ( n.isDestroyed )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ps = n._pubsub(),
|
||||||
|
token = user.chat_oauth_token,
|
||||||
|
new_topics = [
|
||||||
|
"chat_message_updated." + room_id,
|
||||||
|
"chat_moderator_actions." + room_id];
|
||||||
|
|
||||||
|
for(var i=0; i < new_topics.length; i++)
|
||||||
|
ps.Listen({
|
||||||
|
topic: new_topics[i],
|
||||||
|
auth: token,
|
||||||
|
success: function() {},
|
||||||
|
failure: function() {},
|
||||||
|
message: Ember.run.bind(n, n._onPubsubMessage, new_topics[i])
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( n.chatTopics )
|
||||||
|
n.chatTopics = n.chatTopics.concat(new_topics);
|
||||||
|
else
|
||||||
|
n.chatTopics = new_topics;
|
||||||
|
|
||||||
|
ps.on("connected", Ember.run.bind(n, n._onPubsubConnect));
|
||||||
|
ps.on("disconnected", Ember.run.bind(n, n._onPubsubDisconnect));
|
||||||
|
t();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
tearDownService: function(room_id) {
|
||||||
|
if ( ! this.chatTopics )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ps = this._pubsub(),
|
||||||
|
old_topics;
|
||||||
|
|
||||||
|
if ( ! room_id )
|
||||||
|
room_id = this.get("ffz_teardown_target");
|
||||||
|
|
||||||
|
if ( room_id ) {
|
||||||
|
// Make sure it's a string.
|
||||||
|
room_id = '.' + room_id;
|
||||||
|
old_topics = this.chatTopics.filter(function(x) { return x.substr(-room_id.length) === room_id });
|
||||||
|
} else
|
||||||
|
old_topics = this.chatTopics;
|
||||||
|
|
||||||
|
for(var i=0; i < old_topics.length; i++) {
|
||||||
|
ps.Unlisten({
|
||||||
|
topic: old_topics[i],
|
||||||
|
success: function() {},
|
||||||
|
failure: function() {}
|
||||||
|
});
|
||||||
|
this.chatTopics.removeObject(old_topics[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! this.chatTopics.length )
|
||||||
|
this.chatTopics = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPubsubMessage: function(topic, e) {
|
||||||
|
if ( this.isDestroyed )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var msg = JSON.parse(e),
|
||||||
|
msg_data = msg.data,
|
||||||
|
msg_type = msg.type || msg_data.type;
|
||||||
|
|
||||||
|
if ( msg_data )
|
||||||
|
msg_data.topic = topic;
|
||||||
|
|
||||||
|
this.trigger(msg_type, msg_data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ( ! pubsub.chatTopics )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Now that we've modified that, we need to re-listen to everything.
|
||||||
|
pubsub.get("session").withCurrentUser(function(user) {
|
||||||
|
if ( pubsub.isDestroyed )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ps = pubsub._pubsub(),
|
||||||
|
token = user.chat_oauth_token;
|
||||||
|
|
||||||
|
for(var i=0; i < pubsub.chatTopics.length; i++) {
|
||||||
|
ps.Unlisten({
|
||||||
|
topic: pubsub.chatTopics[i],
|
||||||
|
success: function() {},
|
||||||
|
failure: function() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
ps.Listen({
|
||||||
|
topic: pubsub.chatTopics[i],
|
||||||
|
auth: token,
|
||||||
|
success: function() {},
|
||||||
|
failure: function() {},
|
||||||
|
message: Ember.run.bind(pubsub, pubsub._onPubsubMessage, pubsub.chatTopics[i])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
// View Customization
|
// View Customization
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -225,6 +359,7 @@ FFZ.prototype.modify_room_view = function(view) {
|
||||||
this.ffzDisableFreeze();
|
this.ffzDisableFreeze();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
ffzOnKey: function(event) {
|
ffzOnKey: function(event) {
|
||||||
this.ffz_ctrl = event.ctrlKey;
|
this.ffz_ctrl = event.ctrlKey;
|
||||||
this.ffz_alt = event.altKey;
|
this.ffz_alt = event.altKey;
|
||||||
|
@ -835,10 +970,17 @@ FFZ.prototype._insert_history = function(room_id, data, from_server) {
|
||||||
|
|
||||||
// Store the message ID for this message, of course.
|
// Store the message ID for this message, of course.
|
||||||
var msg_id = msg.tags && msg.tags.id,
|
var msg_id = msg.tags && msg.tags.id,
|
||||||
ids = r.ffz_ids = r.ffz_ids || {};
|
notice_type = msg.tags && msg.tags['msg-id'],
|
||||||
|
|
||||||
|
ids = r.ffz_ids = r.ffz_ids || {},
|
||||||
|
notices = r.ffz_last_notices = r.ffz_last_notices || {};
|
||||||
|
|
||||||
if ( msg_id && ! ids[msg_id] )
|
if ( msg_id && ! ids[msg_id] )
|
||||||
ids[msg_id] = msg;
|
ids[msg_id] = msg;
|
||||||
|
|
||||||
|
if ( notice_type && ! notices[notice_type] )
|
||||||
|
notices[notice_type] = msg;
|
||||||
|
|
||||||
messages.unshiftObject(msg);
|
messages.unshiftObject(msg);
|
||||||
inserted += 1;
|
inserted += 1;
|
||||||
|
|
||||||
|
@ -876,9 +1018,15 @@ FFZ.prototype._insert_history = function(room_id, data, from_server) {
|
||||||
messages.insertAt(inserted, msg);
|
messages.insertAt(inserted, msg);
|
||||||
while ( messages.length > buffer_size ) {
|
while ( messages.length > buffer_size ) {
|
||||||
// Remove this message from the ID tracker.
|
// Remove this message from the ID tracker.
|
||||||
var m = messages.get(0);
|
var m = messages.get(0),
|
||||||
if ( m.tags && m.tags.id && r.ffz_ids && r.ffz_ids[m.tags.id] )
|
msg_id = m.tags && m.tags.id,
|
||||||
delete r.ffz_ids[m.tags.id];
|
notice_type = m.tags && m.tags['msg-id'];
|
||||||
|
|
||||||
|
if ( msg_id && r.ffz_ids && r.ffz_ids[msg_id] )
|
||||||
|
delete r.ffz_ids[msg_id];
|
||||||
|
|
||||||
|
if ( notice_type && r.ffz_last_notices && r.ffz_last_notices[notice_type] === m )
|
||||||
|
delete r.ffz_last_notices[notice_type];
|
||||||
|
|
||||||
messages.removeAt(0);
|
messages.removeAt(0);
|
||||||
removed++;
|
removed++;
|
||||||
|
@ -1052,13 +1200,16 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
f.add_room(this.id, this);
|
f.add_room(this.id, this);
|
||||||
this.set("ffz_chatters", {});
|
this.set("ffz_chatters", {});
|
||||||
this.set("ffz_ids", this.get('ffz_ids') || {});
|
this.set("ffz_ids", this.get('ffz_ids') || {});
|
||||||
|
this.set("ffz_last_notices", this.get('ffz_last_notices') || {});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
f.error("add_room: " + err);
|
f.error("add_room: " + err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroy: function() {
|
willDestroy: function() {
|
||||||
|
this.get("pubsub").set("ffz_teardown_target", this.get('roomProperties._id'));
|
||||||
this._super();
|
this._super();
|
||||||
|
this.get("pubsub").set("ffz_teardown_target", null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
f.remove_room(this.id);
|
f.remove_room(this.id);
|
||||||
|
@ -1067,26 +1218,80 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearMessages: function(user, tags, disable_log) {
|
addChannelModerationMessage: function(event) {
|
||||||
|
// Throw out messages that are for other rooms.
|
||||||
|
var room_id = '.' + this.get("roomProperties._id");
|
||||||
|
if ( event.topic && event.topic.substr(-room_id.length) !== room_id || event.created_by === this.get("session.userData.login") )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var target_notice = NOTICE_MAPPING[event.moderation_action];
|
||||||
|
if ( target_notice ) {
|
||||||
|
var last_notice = this.ffz_last_notices && this.ffz_last_notices[target_notice];
|
||||||
|
|
||||||
|
if ( last_notice && ! last_notice.has_owner ) {
|
||||||
|
last_notice.message += ' (By: ' + event.created_by + ')';
|
||||||
|
last_notice.has_owner = true;
|
||||||
|
last_notice.cachedTokens = undefined;
|
||||||
|
if ( last_notice._line )
|
||||||
|
last_notice._line.ffzRender();
|
||||||
|
} else {
|
||||||
|
var waiting = this.ffz_waiting_notices = this.ffz_waiting_notices || {};
|
||||||
|
waiting[target_notice] = event.created_by;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ( f.settings.get_twitch('showModerationActions') )
|
||||||
|
this._super(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
addLoginModerationMessage: function(event) {
|
||||||
|
// Throw out messages that are for other rooms.
|
||||||
|
var room_id = '.' + this.get("roomProperties._id");
|
||||||
|
if ( event.topic && event.topic.substr(-room_id.length) !== room_id || event.created_by === this.get("session.userData.login") )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// In case we get unexpected input, do the other thing.
|
||||||
|
if ( ["ban", "unban", "timeout"].indexOf(event.moderation_action) === -1 )
|
||||||
|
return this._super(event);
|
||||||
|
|
||||||
|
var tags = {
|
||||||
|
'ban-duration': event.moderation_action === 'unban' ? -Infinity : event.args[1],
|
||||||
|
'ban-reason': event.args[2],
|
||||||
|
'ban-moderator': event.created_by
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clearMessages(event.args[0], tags, false, event.moderation_action !== 'unban');
|
||||||
|
},
|
||||||
|
|
||||||
|
clearMessages: function(user, tags, disable_log, report_only) {
|
||||||
var t = this;
|
var t = this;
|
||||||
|
|
||||||
if ( user ) {
|
if ( user ) {
|
||||||
var duration = Infinity,
|
var duration = Infinity,
|
||||||
reason = undefined,
|
reason = undefined,
|
||||||
|
moderator = undefined,
|
||||||
msg_id = undefined,
|
msg_id = undefined,
|
||||||
current_user = f.get_user(),
|
current_user = f.get_user(),
|
||||||
is_me = current_user && current_user.login === user;
|
is_me = current_user && current_user.login === user;
|
||||||
|
|
||||||
// Read the ban duration and reason from the message tags.
|
// Read the ban duration and reason from the message tags.
|
||||||
if ( tags && tags['ban-duration'] )
|
if ( tags && tags['ban-duration'] ) {
|
||||||
duration = parseInt(tags['ban-duration']);
|
duration = tags['ban-duration'];
|
||||||
|
if ( typeof duration === 'string' )
|
||||||
|
duration = parseInt(duration);
|
||||||
|
|
||||||
if ( isNaN(duration) )
|
if ( isNaN(duration) )
|
||||||
duration = Infinity;
|
duration = Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
if ( tags && tags['ban-reason'] && (is_me || t.get('isModeratorOrHigher')) )
|
if ( tags && tags['ban-reason'] && (is_me || t.get('isModeratorOrHigher')) )
|
||||||
reason = tags['ban-reason'];
|
reason = tags['ban-reason'];
|
||||||
|
|
||||||
|
if ( tags && tags['ban-moderator'] && (is_me || t.get('isModeratorOrHigher')) )
|
||||||
|
moderator = tags['ban-moderator'];
|
||||||
|
|
||||||
|
|
||||||
|
// Does anything really matter?
|
||||||
|
if ( ! report_only && duration !== -Infinity ) {
|
||||||
|
|
||||||
// Is there a UUID on the end of the ban reason?
|
// Is there a UUID on the end of the ban reason?
|
||||||
if ( reason ) {
|
if ( reason ) {
|
||||||
|
@ -1142,6 +1347,11 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
if ( msg.tags && msg.tags.id === msg_id ) {
|
if ( msg.tags && msg.tags.id === msg_id ) {
|
||||||
msgs.removeAt(i);
|
msgs.removeAt(i);
|
||||||
delete this.ffz_ids[msg_id];
|
delete this.ffz_ids[msg_id];
|
||||||
|
|
||||||
|
var notice_type = msg.tags && msg.tags['msg-id'];
|
||||||
|
if ( notice_type && this.ffz_last_notices && this.ffz_last_notices[notice_type] === msg )
|
||||||
|
delete this.ffz_last_notices[notice_type];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1170,8 +1380,14 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
if ( msg.from === user ) {
|
if ( msg.from === user ) {
|
||||||
if ( f.settings.remove_deleted ) {
|
if ( f.settings.remove_deleted ) {
|
||||||
// Remove this message from the ID tracker.
|
// Remove this message from the ID tracker.
|
||||||
if ( msg.tags && msg.tags.id && this.ffz_ids && this.ffz_ids[msg.tags.id] )
|
var msg_id = msg.tags && msg.tags.id,
|
||||||
delete this.ffz_ids[msg.tags.id];
|
notice_type = msg.tags && msg.tags['msg-id'];
|
||||||
|
|
||||||
|
if ( msg_id && this.ffz_ids && this.ffz_ids[msg_id] )
|
||||||
|
delete this.ffz_ids[msg_id];
|
||||||
|
|
||||||
|
if ( notice_type && this.ffz_last_notices && this.ffz_last_notices[notice_type] === msg )
|
||||||
|
delete this.ffz_last_notices[notice_type];
|
||||||
|
|
||||||
msgs.removeAt(i);
|
msgs.removeAt(i);
|
||||||
removed++;
|
removed++;
|
||||||
|
@ -1199,6 +1415,9 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End of report_only check.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Now we need to see about displaying a ban notice.
|
// Now we need to see about displaying a ban notice.
|
||||||
if ( ! disable_log ) {
|
if ( ! disable_log ) {
|
||||||
|
@ -1220,7 +1439,11 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display a notice in chat.
|
// Display a notice in chat.
|
||||||
var message = (is_me ? "You have" : FFZ.get_capitalization(user) + " has") + " been " + (isFinite(duration) ? "timed out for " + utils.duration_string(duration, true) : "banned");
|
var message = (is_me ?
|
||||||
|
"You have" : ffz.format_display_name(FFZ.get_capitalization(user), user, true, false, true)[0] + " has") +
|
||||||
|
" been " + (duration === -Infinity ? 'unbanned' :
|
||||||
|
(duration === 1 ? 'purged' :
|
||||||
|
(isFinite(duration) ? "timed out for " + utils.duration_string(duration, true) : "banned")));
|
||||||
|
|
||||||
if ( show_notice ) {
|
if ( show_notice ) {
|
||||||
if ( ! last_ban ) {
|
if ( ! last_ban ) {
|
||||||
|
@ -1229,11 +1452,12 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
date: now,
|
date: now,
|
||||||
ffz_ban_target: user,
|
ffz_ban_target: user,
|
||||||
reasons: reason ? [reason] : [],
|
reasons: reason ? [reason] : [],
|
||||||
|
moderators: moderator ? [moderator] : [],
|
||||||
msg_ids: msg_id ? [msg_id] : [],
|
msg_ids: msg_id ? [msg_id] : [],
|
||||||
durations: [duration],
|
durations: [duration],
|
||||||
end_time: end_time,
|
end_time: end_time,
|
||||||
timeouts: 1,
|
timeouts: report_only ? 0 : 1,
|
||||||
message: message + (show_reason && reason ? ' with reason: ' + reason : '.')
|
message: message + (show_reason && moderator ? ' by ' + moderator : '') + (show_reason && reason ? ' with reason: ' + reason : '.')
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( ban_history )
|
if ( ban_history )
|
||||||
|
@ -1248,13 +1472,21 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
if ( reason && last_ban.reasons.indexOf(reason) === -1 )
|
if ( reason && last_ban.reasons.indexOf(reason) === -1 )
|
||||||
last_ban.reasons.push(reason);
|
last_ban.reasons.push(reason);
|
||||||
|
|
||||||
|
if ( moderator && last_ban.moderators.indexOf(moderator) === -1 )
|
||||||
|
last_ban.moderators.push(moderator);
|
||||||
|
|
||||||
if ( last_ban.durations.indexOf(duration) === -1 )
|
if ( last_ban.durations.indexOf(duration) === -1 )
|
||||||
last_ban.durations.push(duration);
|
last_ban.durations.push(duration);
|
||||||
|
|
||||||
last_ban.end_time = end_time;
|
last_ban.end_time = end_time;
|
||||||
last_ban.timeouts++;
|
|
||||||
|
|
||||||
last_ban.message = message + ' (' + utils.number_commas(last_ban.timeouts) + ' times)' + (!show_reason || last_ban.reasons.length === 0 ? '.' : ' with reason' + utils.pluralize(last_ban.reasons.length) + ': ' + last_ban.reasons.join(', '));
|
if ( ! report_only )
|
||||||
|
last_ban.timeouts++;
|
||||||
|
|
||||||
|
last_ban.message = message +
|
||||||
|
(last_ban.timeouts > 1 ? ' (' + utils.number_commas(last_ban.timeouts) + ' times)' : '') +
|
||||||
|
(!show_reason || last_ban.moderators.length === 0 ? '' : ' by ' + last_ban.moderators.join(', ') ) +
|
||||||
|
(!show_reason || last_ban.reasons.length === 0 ? '.' : ' with reason' + utils.pluralize(last_ban.reasons.length) + ': ' + last_ban.reasons.join(', '));
|
||||||
last_ban.cachedTokens = [{type: "text", text: last_ban.message}];
|
last_ban.cachedTokens = [{type: "text", text: last_ban.message}];
|
||||||
|
|
||||||
// Now that we've reset the tokens, if there's a line for this,
|
// Now that we've reset the tokens, if there's a line for this,
|
||||||
|
@ -1333,9 +1565,15 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
var to_remove = len - limit;
|
var to_remove = len - limit;
|
||||||
for(var i = 0; i < to_remove; i++) {
|
for(var i = 0; i < to_remove; i++) {
|
||||||
// Remove this message from the ID tracker.
|
// Remove this message from the ID tracker.
|
||||||
var msg = messages.get(i);
|
var msg = messages.get(i),
|
||||||
if ( msg.tags && msg.tags.id && this.ffz_ids && this.ffz_ids[msg.tags.id] )
|
msg_id = msg.tags && msg.tags.id,
|
||||||
delete this.ffz_ids[msg.tags.id];
|
notice_type = msg.tags && msg.tags['msg-id'];
|
||||||
|
|
||||||
|
if ( msg_id && this.ffz_ids && this.ffz_ids[msg_id] )
|
||||||
|
delete this.ffz_ids[msg_id];
|
||||||
|
|
||||||
|
if ( notice_type && this.ffz_last_notices && this.ffz_last_notices[notice_type] === msg )
|
||||||
|
delete this.ffz_last_notices[notice_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.removeAt(0, to_remove);
|
messages.removeAt(0, to_remove);
|
||||||
|
@ -1423,9 +1661,15 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
var msg = this.ffzPending[i];
|
var msg = this.ffzPending[i];
|
||||||
if ( msg.removed ) {
|
if ( msg.removed ) {
|
||||||
// Don't keep this message ID around.
|
// Don't keep this message ID around.
|
||||||
var msg_id = msg && msg.tags && msg.tags.id;
|
var msg_id = msg && msg.tags && msg.tags.id,
|
||||||
|
notice_type = msg && msg.tags && msg.tags['msg-id'];
|
||||||
|
|
||||||
if ( msg_id && this.ffz_ids && this.ffz_ids[msg_id] )
|
if ( msg_id && this.ffz_ids && this.ffz_ids[msg_id] )
|
||||||
delete this.ffz_ids[msg_id];
|
delete this.ffz_ids[msg_id];
|
||||||
|
|
||||||
|
if ( notice_type && this.ffz_last_notices && this.ffz_last_notices[notice_type] === msg )
|
||||||
|
delete this.ffz_last_notices[notice_type];
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1470,7 +1714,24 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
if ( (msg.msgId === 'timeout_success' || msg.msgId === 'ban_success') && this.ffzShouldDisplayNotice() )
|
if ( (msg.msgId === 'timeout_success' || msg.msgId === 'ban_success') && this.ffzShouldDisplayNotice() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
return this._super(msg);
|
f.log("Notification", msg);
|
||||||
|
|
||||||
|
if ( ! msg.tags )
|
||||||
|
msg.tags = {};
|
||||||
|
|
||||||
|
if ( ! msg.tags['msg-id'] )
|
||||||
|
msg.tags['msg-id'] = msg.msgId;
|
||||||
|
|
||||||
|
if ( ! msg.style )
|
||||||
|
msg.style = 'admin';
|
||||||
|
|
||||||
|
if ( this.ffz_waiting_notices && this.ffz_waiting_notices[msg.msgId]) {
|
||||||
|
msg.has_owner = true;
|
||||||
|
msg.message += ' (By: ' + this.ffz_waiting_notices[msg.msgId] + ')';
|
||||||
|
delete this.ffz_waiting_notices[msg.msgId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.addMessage(msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1481,7 +1742,8 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
|
|
||||||
addMessage: function(msg) {
|
addMessage: function(msg) {
|
||||||
if ( msg ) {
|
if ( msg ) {
|
||||||
var is_resub = msg.tags && msg.tags['msg-id'] === 'resub',
|
var notice_type = msg.tags && msg.tags['msg-id'],
|
||||||
|
is_resub = notice_type === 'resub',
|
||||||
room_id = this.get('id'),
|
room_id = this.get('id'),
|
||||||
msg_id = msg.tags && msg.tags.id;
|
msg_id = msg.tags && msg.tags.id;
|
||||||
|
|
||||||
|
@ -1510,8 +1772,11 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
var is_whisper = msg.style === 'whisper';
|
var is_whisper = msg.style === 'whisper';
|
||||||
|
|
||||||
// Ignore whispers if conversations are enabled.
|
// Ignore whispers if conversations are enabled.
|
||||||
if ( is_whisper && utils.ember_lookup('controller:application').get('isConversationsEnabled') )
|
if ( is_whisper ) {
|
||||||
return;
|
var conv_enabled = utils.ember_lookup('controller:application').get('isConversationsEnabled');
|
||||||
|
if ( conv_enabled || (!conv_enabled && f.settings.hide_whispers_in_embedded_chat) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! is_whisper )
|
if ( ! is_whisper )
|
||||||
msg.room = room_id;
|
msg.room = room_id;
|
||||||
|
@ -1638,6 +1903,12 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
ids[msg_id] = msg;
|
ids[msg_id] = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a notice, store that this is the last of its type.
|
||||||
|
if ( notice_type ) {
|
||||||
|
var ids = this.ffz_last_notices = this.ffz_last_notices || {};
|
||||||
|
ids[notice_type] = msg;
|
||||||
|
}
|
||||||
|
|
||||||
// Report this message to the dashboard.
|
// Report this message to the dashboard.
|
||||||
if ( window !== window.parent && parent.postMessage && msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
|
if ( window !== window.parent && parent.postMessage && msg.from && msg.from !== "jtv" && msg.from !== "twitchnotify" )
|
||||||
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
|
parent.postMessage({from_ffz: true, command: 'chat_message', data: {from: msg.from, room: msg.room}}, "*"); //location.protocol + "//www.twitch.tv/");
|
||||||
|
|
|
@ -185,8 +185,8 @@ FFZ.prototype.setup_sidebar = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar Followed Games
|
// Sidebar Followed Games
|
||||||
var GamesFollowing = utils.ember_lookup('controller:games-following'),
|
var f = this,
|
||||||
f = this;
|
GamesFollowing = utils.ember_lookup('controller:games-following');
|
||||||
|
|
||||||
if ( GamesFollowing ) {
|
if ( GamesFollowing ) {
|
||||||
this.log("Hooking the Ember games-following controller.");
|
this.log("Hooking the Ember games-following controller.");
|
||||||
|
|
|
@ -86,7 +86,11 @@ FFZ.prototype.modify_viewer_list = function(component) {
|
||||||
first_user = false;
|
first_user = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewers.push({chatter: FFZ.get_capitalization(data[x])});
|
var display_name = FFZ.get_capitalization(data[x]);
|
||||||
|
if ( display_name.trim().toLowerCase() !== data[x] )
|
||||||
|
display_name = data[x];
|
||||||
|
|
||||||
|
viewers.push({chatter: display_name});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,43 @@ FFZ.prototype.setup_bttv = function(delay) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Tab Completion
|
||||||
|
var original_emotes = BC.emotes;
|
||||||
|
|
||||||
|
BC.emotes = function() {
|
||||||
|
var output = original_emotes(),
|
||||||
|
user = f.get_user(),
|
||||||
|
room_id = BetterTTV.getChannel(),
|
||||||
|
|
||||||
|
ffz_sets = f.getEmotes(user && user.login, room_id);
|
||||||
|
|
||||||
|
for(var i=0; i < ffz_sets.length; i++) {
|
||||||
|
var emote_set = f.emote_sets[ffz_sets[i]];
|
||||||
|
if ( ! emote_set )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var set_name = (emote_set.source || "FFZ") + " " + (emote_set.title || "Global") + " Emotes",
|
||||||
|
set_icon = emote_set.icon || (emote_set.hasOwnProperty('source_ext') && f._apis[emote_set.source_ext] && f._apis[emote_set.source_ext].icon) || '//cdn.frankerfacez.com/script/devicon.png';
|
||||||
|
|
||||||
|
for(var emote_id in emote_set.emoticons) {
|
||||||
|
var emote = emote_set.emoticons[emote_id];
|
||||||
|
if ( ! emote.hidden && emote.name ) {
|
||||||
|
output.push({
|
||||||
|
text: emote.name,
|
||||||
|
channel: set_name,
|
||||||
|
badge: set_icon,
|
||||||
|
url: emote.urls[1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.log("BTTV Emotes", output);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Emoji!
|
// Emoji!
|
||||||
var parse_emoji = function(token) {
|
var parse_emoji = function(token) {
|
||||||
var setting = f.settings.parse_emoji,
|
var setting = f.settings.parse_emoji,
|
||||||
|
|
240
src/less/dark-clips.less
Normal file
240
src/less/dark-clips.less
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
/* Colors */
|
||||||
|
@fg-color: #a49ab5;
|
||||||
|
@bg-color: #101010;
|
||||||
|
@link-color: #a68ed2;
|
||||||
|
@remove-link-color: #fc3636;
|
||||||
|
|
||||||
|
@hollow-button-color: darken(@link-color, 5%); //#9d8dba;
|
||||||
|
|
||||||
|
@bright-bg: lighten(@bg-color, 15%);
|
||||||
|
@bright-fg: lighten(@fg-color, 15%);
|
||||||
|
|
||||||
|
@nav-bg-color: #191919;
|
||||||
|
|
||||||
|
.ffz-dark {
|
||||||
|
html&, body {
|
||||||
|
background-color: @bg-color;
|
||||||
|
color: @fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: @link-color;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
color: lighten(@link-color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.sub-text { color: darken(@fg-color, 10%) }
|
||||||
|
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
.nav {
|
||||||
|
background-color: @nav-bg-color;
|
||||||
|
border-bottom-color: lighten(@nav-bg-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-logo_twitch, .clips-nav__logo { fill: white }
|
||||||
|
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
|
||||||
|
.button {
|
||||||
|
&, &:hover, &:focus {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure img, figure svg {
|
||||||
|
fill: @link-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--hollow {
|
||||||
|
box-shadow: inset 0 0 0 1px fade(@link-color, 50%);
|
||||||
|
color: @hollow-button-color;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background-color: fade(@link-color, 10%);
|
||||||
|
color: @hollow-button-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--hollow.button--dropmenu {
|
||||||
|
&:after {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Balloons
|
||||||
|
|
||||||
|
.balloon {
|
||||||
|
background-color: lighten(@bg-color, 10%);
|
||||||
|
color: #ccc;
|
||||||
|
box-shadow: 0 0 0 1px fade(white, 20%), 0 1px 1px fade(white, 5%);
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background-color: lighten(@bg-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--fancy {
|
||||||
|
color: lighten(@link-color, 5%);
|
||||||
|
box-shadow: 0 0 0 1px fade(white, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--left:after { box-shadow: 1px -1px 0 fade(white, 20%) }
|
||||||
|
&--right:after { box-shadow: -1px 1px 0 fade(white, 20%) }
|
||||||
|
&--up:after { box-shadow: 1px 1px 0 fade(white, 20%) }
|
||||||
|
&--down:after { box-shadow: -1px -1px 0 fade(white, 20%) }
|
||||||
|
|
||||||
|
&--cols .balloon__list ~ .balloon__list { box-shadow: -1px 0 0 #202021 }
|
||||||
|
|
||||||
|
&__stroke { border-bottom-color: fade(white, 10%) }
|
||||||
|
|
||||||
|
.balloon__link {
|
||||||
|
color: @link-color !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @link-color !important;
|
||||||
|
color: @bg-color !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.request-removal-link,
|
||||||
|
&.clip-remove-link {
|
||||||
|
color: @remove-link-color !important;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @remove-link-color !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Modal Content
|
||||||
|
.modal {
|
||||||
|
&__content {
|
||||||
|
background-color: @bg-color;
|
||||||
|
box-shadow: 0 1px 1px fade(white, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
color: @bright-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body-text {
|
||||||
|
color: @fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Table
|
||||||
|
.table {
|
||||||
|
background-color: @bg-color;
|
||||||
|
box-shadow: 0 2px 4px 0 fade(white, 20%);
|
||||||
|
|
||||||
|
&__row {
|
||||||
|
background-color: @bg-color;
|
||||||
|
color: @fg-color;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background-color: lighten(@bg-color, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: lighten(@bg-color, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--no-hover:hover { background-color: @bg-color }
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
background-color: lighten(@bg-color, 5%)
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cell {
|
||||||
|
border-top-color: @bright-bg;
|
||||||
|
border-bottom-color: @bright-bg;
|
||||||
|
color: @fg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cell--header {
|
||||||
|
border-bottom-color: @bright-bg;
|
||||||
|
color: @bright-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__zero-title {
|
||||||
|
color: @bright-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__zero-body {
|
||||||
|
color: @fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tabs
|
||||||
|
.tabs {
|
||||||
|
box-shadow: inset 0 -1px 0 #202021;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
box-shadow: inset 0 -1px 0 #202021;
|
||||||
|
|
||||||
|
& > a { color: @link-color }
|
||||||
|
|
||||||
|
&:hover, &--active {
|
||||||
|
box-shadow: inset 0 -1px 0 @link-color;
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
color: @bright-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
border-color: fade(white, 18%);
|
||||||
|
border-left-color: @bright-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-button__border,
|
||||||
|
.ldboard-head {
|
||||||
|
border-bottom-color: #3e3d40;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Previewer
|
||||||
|
.ld-previewer__iframe, .previewer__pane {
|
||||||
|
background-color: @bg-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previewer__close {
|
||||||
|
fill: @link-color;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
fill: lighten(@link-color, 10%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
.label {
|
||||||
|
color: @bright-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input
|
||||||
|
select,
|
||||||
|
.input--text {
|
||||||
|
background-color: @bg-color;
|
||||||
|
color: @bright-fg;
|
||||||
|
border-color: @bright-bg;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: lighten(@bright-bg, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
5
src/less/style-clips.less
Normal file
5
src/less/style-clips.less
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.ffz-darken-clips {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 10px;
|
||||||
|
}
|
68
src/main.js
68
src/main.js
|
@ -34,7 +34,7 @@ FFZ.msg_commands = {};
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
var VER = FFZ.version_info = {
|
var VER = FFZ.version_info = {
|
||||||
major: 3, minor: 5, revision: 270,
|
major: 3, minor: 5, revision: 283,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
@ -241,22 +241,20 @@ FFZ.prototype.initialize = function(increment, delay) {
|
||||||
return this.log("Found banned sub-domain. Not initializing.");
|
return this.log("Found banned sub-domain. Not initializing.");
|
||||||
|
|
||||||
// Check for the player
|
// Check for the player
|
||||||
if ( location.hostname === 'player.twitch.tv' ) {
|
if ( location.hostname === 'player.twitch.tv' )
|
||||||
this.init_player(delay);
|
return this.init_player(delay);
|
||||||
return;
|
|
||||||
}
|
// Clips~
|
||||||
|
if ( location.hostname === 'clips.twitch.tv' )
|
||||||
|
return this.init_clips(delay);
|
||||||
|
|
||||||
// Check for special non-ember pages.
|
// Check for special non-ember pages.
|
||||||
if ( /^\/(?:$|search$|team\/|user\/|p\/|settings|m\/|messages?\/)/.test(location.pathname) ) {
|
if ( /^\/(?:$|search$|team\/|user\/|p\/|settings|m\/|messages?\/)/.test(location.pathname) )
|
||||||
this.init_normal(delay);
|
return this.init_normal(delay);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for the dashboard.
|
// Check for the dashboard.
|
||||||
if ( /\/[^\/]+\/dashboard/.test(location.pathname) && !/bookmarks$/.test(location.pathname) ) {
|
if ( /\/[^\/]+\/dashboard/.test(location.pathname) && !/bookmarks$/.test(location.pathname) )
|
||||||
this.init_dashboard(delay);
|
return this.init_dashboard(delay);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var loaded = FFZ.utils.ember_resolve('model:room');
|
var loaded = FFZ.utils.ember_resolve('model:room');
|
||||||
if ( !loaded ) {
|
if ( !loaded ) {
|
||||||
|
@ -273,6 +271,32 @@ FFZ.prototype.initialize = function(increment, delay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype.init_clips = function(delay) {
|
||||||
|
var start = (window.performance && performance.now) ? performance.now() : Date.now();
|
||||||
|
this.log("Found Twitch Clips after " + (delay||0) + " ms at: " + location);
|
||||||
|
this.log("Initializing FrankerFaceZ version " + FFZ.version_info);
|
||||||
|
|
||||||
|
this.users = {};
|
||||||
|
this.is_dashboard = false;
|
||||||
|
this.embed_in_dash = false;
|
||||||
|
this.is_clips = true;
|
||||||
|
try {
|
||||||
|
this.embed_in_clips = window.top !== window && window.top.location.hostname === 'clips.twitch.tv';
|
||||||
|
} catch(err) { this.embed_in_clips = false; }
|
||||||
|
|
||||||
|
this.load_settings();
|
||||||
|
this.setup_dark();
|
||||||
|
this.setup_css();
|
||||||
|
|
||||||
|
this.add_clips_darken_button();
|
||||||
|
|
||||||
|
var end = (window.performance && performance.now) ? performance.now() : Date.now(),
|
||||||
|
duration = end - start;
|
||||||
|
|
||||||
|
this.log("Initialization complete in " + duration + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.init_player = function(delay) {
|
FFZ.prototype.init_player = function(delay) {
|
||||||
var start = (window.performance && performance.now) ? performance.now() : Date.now();
|
var start = (window.performance && performance.now) ? performance.now() : Date.now();
|
||||||
this.log("Found Twitch Player after " + (delay||0) + " ms at: " + location);
|
this.log("Found Twitch Player after " + (delay||0) + " ms at: " + location);
|
||||||
|
@ -415,8 +439,24 @@ FFZ.prototype.init_ember = function(delay) {
|
||||||
Settings.reopen({settings: Ember.computed.alias('model')});
|
Settings.reopen({settings: Ember.computed.alias('model')});
|
||||||
|
|
||||||
|
|
||||||
// Initialize all the modules.
|
// Settings are important.
|
||||||
this.load_settings();
|
this.load_settings();
|
||||||
|
|
||||||
|
// Is debug mode enabled? Scratch that, everyone gets error handlers!
|
||||||
|
if ( true ) { //this.settings.developer_mode ) {
|
||||||
|
// Set up an error listener for RSVP.
|
||||||
|
var f = this;
|
||||||
|
if ( Ember.RSVP && Ember.RSVP.on )
|
||||||
|
Ember.RSVP.on('error', function(error) {
|
||||||
|
f.error("There was an error within an Ember RSVP.", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ember.onerror = function(error) {
|
||||||
|
f.error("There was an unknown error within Ember.", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up all the everything.
|
||||||
this.setup_ember_wrapper();
|
this.setup_ember_wrapper();
|
||||||
|
|
||||||
// Start this early, for quick loading.
|
// Start this early, for quick loading.
|
||||||
|
|
|
@ -67,6 +67,9 @@ FFZ.prototype.load_settings = function() {
|
||||||
this.settings.del = this._setting_del.bind(this);
|
this.settings.del = this._setting_del.bind(this);
|
||||||
this.settings.load = this._setting_load.bind(this);
|
this.settings.load = this._setting_load.bind(this);
|
||||||
|
|
||||||
|
this.settings.get_twitch = this._setting_get_twitch.bind(this);
|
||||||
|
|
||||||
|
|
||||||
var found_settings = false;
|
var found_settings = false;
|
||||||
|
|
||||||
for(var key in FFZ.settings_info) {
|
for(var key in FFZ.settings_info) {
|
||||||
|
@ -811,6 +814,11 @@ FFZ.prototype._setting_get = function(key) {
|
||||||
return this.settings[key];
|
return this.settings[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.prototype._setting_get_twitch = function(key) {
|
||||||
|
var Settings = utils.ember_lookup('controller:settings');
|
||||||
|
return Settings && Settings.get('settings.' + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype._setting_set = function(key, val, suppress_log) {
|
FFZ.prototype._setting_set = function(key, val, suppress_log) {
|
||||||
var info = FFZ.settings_info[key],
|
var info = FFZ.settings_info[key],
|
||||||
|
|
|
@ -289,6 +289,46 @@ FFZ.prototype.setup_tokenization = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Display Name Formatting
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
FFZ.prototype.format_display_name = function(display_name, user_id, disable_alias, disable_intl, disable_html) {
|
||||||
|
var setting = this.settings.username_display,
|
||||||
|
alias = this.aliases[user_id],
|
||||||
|
|
||||||
|
name_matches = ! display_name || display_name.trim().toLowerCase() === user_id,
|
||||||
|
|
||||||
|
tooltip,
|
||||||
|
display_name;
|
||||||
|
|
||||||
|
if ( setting === 0 )
|
||||||
|
display_name = user_id;
|
||||||
|
|
||||||
|
else if ( setting === 1 )
|
||||||
|
display_name = name_matches ? (display_name || (user_id && user_id.capitalize())) : user_id;
|
||||||
|
|
||||||
|
else {
|
||||||
|
display_name = utils.sanitize(display_name || (user_id && user_id.capitalize()));
|
||||||
|
|
||||||
|
if ( ! disable_intl && setting === 3 && ! name_matches )
|
||||||
|
display_name += disable_html ? '(' + user_id + ')' : ' <span class="intl-login">(' + user_id + ')</span>';
|
||||||
|
|
||||||
|
else if ( ((disable_intl && setting === 3) || setting === 4) && ! name_matches )
|
||||||
|
tooltip = user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! disable_alias && alias ) {
|
||||||
|
if ( display_name )
|
||||||
|
tooltip = display_name + (tooltip ? ' (' + tooltip + ')' : '');
|
||||||
|
|
||||||
|
display_name = utils.sanitize(alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [display_name, tooltip];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Twitch Emote Data
|
// Twitch Emote Data
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
@ -505,9 +545,14 @@ FFZ.prototype.tokenize_conversation_line = function(message, prevent_notificatio
|
||||||
if ( helpers && helpers.linkifyMessage )
|
if ( helpers && helpers.linkifyMessage )
|
||||||
tokens = helpers.linkifyMessage(tokens);
|
tokens = helpers.linkifyMessage(tokens);
|
||||||
|
|
||||||
if ( user && user.login && helpers && helpers.mentionizeMessage )
|
if ( user && user.login && helpers && helpers.mentionizeMessage ) {
|
||||||
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
||||||
|
|
||||||
|
// Display names~~
|
||||||
|
if ( ! from_me && user.name && user.name.trim().toLowerCase() !== user.login )
|
||||||
|
tokens = helpers.mentionizeMessage(tokens, user.name, from_me);
|
||||||
|
}
|
||||||
|
|
||||||
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
|
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
|
||||||
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
||||||
|
|
||||||
|
@ -546,14 +591,20 @@ FFZ.prototype.tokenize_vod_line = function(msgObject, delete_links) {
|
||||||
user = this.get_user(),
|
user = this.get_user(),
|
||||||
from_me = user && from_user === user.login,
|
from_me = user && from_user === user.login,
|
||||||
emotes = msgObject.get('tags.emotes'),
|
emotes = msgObject.get('tags.emotes'),
|
||||||
|
|
||||||
tokens = [msg];
|
tokens = [msg];
|
||||||
|
|
||||||
if ( helpers && helpers.linkifyMessage )
|
if ( helpers && helpers.linkifyMessage )
|
||||||
tokens = helpers.linkifyMessage(tokens, delete_links);
|
tokens = helpers.linkifyMessage(tokens, delete_links);
|
||||||
|
|
||||||
if ( user && user.login && helpers && helpers.mentionizeMessage )
|
if ( user && user.login && helpers && helpers.mentionizeMessage ) {
|
||||||
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
||||||
|
|
||||||
|
// Display names~~
|
||||||
|
if ( ! from_me && user.name && user.name.trim().toLowerCase() !== user.login )
|
||||||
|
tokens = helpers.mentionizeMessage(tokens, user.name, from_me);
|
||||||
|
}
|
||||||
|
|
||||||
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
|
if ( helpers && helpers.emoticonizeMessage && emotes && this.settings.parse_emoticons )
|
||||||
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
||||||
|
|
||||||
|
@ -620,9 +671,14 @@ FFZ.prototype.tokenize_chat_line = function(msgObject, prevent_notification, del
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( user && user.login && helpers && helpers.mentionizeMessage )
|
if ( user && user.login && helpers && helpers.mentionizeMessage ) {
|
||||||
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
tokens = helpers.mentionizeMessage(tokens, user.login, from_me);
|
||||||
|
|
||||||
|
// Display names~~
|
||||||
|
if ( ! from_me && user.name && user.name.trim().toLowerCase() !== user.login )
|
||||||
|
tokens = helpers.mentionizeMessage(tokens, user.name, from_me);
|
||||||
|
}
|
||||||
|
|
||||||
if ( helpers && helpers.emoticonizeMessage && this.settings.parse_emoticons )
|
if ( helpers && helpers.emoticonizeMessage && this.settings.parse_emoticons )
|
||||||
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
tokens = helpers.emoticonizeMessage(tokens, emotes);
|
||||||
|
|
||||||
|
@ -754,8 +810,13 @@ FFZ.prototype.tokenize_line = function(user, room, message, no_emotes, no_emoji)
|
||||||
|
|
||||||
if ( helpers && helpers.mentionizeMessage ) {
|
if ( helpers && helpers.mentionizeMessage ) {
|
||||||
var u = this.get_user();
|
var u = this.get_user();
|
||||||
if ( u && u.login )
|
if ( u && u.login ) {
|
||||||
message = helpers.mentionizeMessage(message, u.login, user === u.login);
|
message = helpers.mentionizeMessage(message, u.login, user === u.login);
|
||||||
|
|
||||||
|
// Display names~~
|
||||||
|
if ( ! user === u.login && u.name && u.name.trim().toLowerCase() !== u.login )
|
||||||
|
tokens = helpers.mentionizeMessage(tokens, u.name, from_me);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! no_emotes && this.settings.parse_emoticons && this.settings.parse_emoticons !== 2 )
|
if ( ! no_emotes && this.settings.parse_emoticons && this.settings.parse_emoticons !== 2 )
|
||||||
|
|
|
@ -135,7 +135,7 @@ FFZ.settings_info.dark_twitch = {
|
||||||
if ( this.has_bttv )
|
if ( this.has_bttv )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
document.body.classList.toggle("ffz-dark", val);
|
(this.is_clips ? document.querySelector('html') : document.body).classList.toggle("ffz-dark", val);
|
||||||
|
|
||||||
var Settings = utils.ember_lookup('controller:settings'),
|
var Settings = utils.ember_lookup('controller:settings'),
|
||||||
settings = Settings && Settings.get('settings');
|
settings = Settings && Settings.get('settings');
|
||||||
|
@ -148,7 +148,7 @@ FFZ.settings_info.dark_twitch = {
|
||||||
settings && settings.set('darkMode', this.settings.twitch_chat_dark);
|
settings && settings.set('darkMode', this.settings.twitch_chat_dark);
|
||||||
|
|
||||||
// Try coloring chat replay
|
// Try coloring chat replay
|
||||||
jQuery('.chatReplay').toggleClass('dark', val || false);
|
window.jQuery && jQuery('.chatReplay').toggleClass('dark', val || false);
|
||||||
//jQuery('.rechat-chat-line').parents('.chat-container').toggleClass('dark', val || this.settings.twitch_chat_dark);
|
//jQuery('.rechat-chat-line').parents('.chat-container').toggleClass('dark', val || this.settings.twitch_chat_dark);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -198,7 +198,8 @@ FFZ.prototype.setup_dark = function() {
|
||||||
if ( this.has_bttv )
|
if ( this.has_bttv )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
document.body.classList.toggle("ffz-dark", this.settings.dark_twitch);
|
(this.is_clips ? document.querySelector('html') : document.body).classList.toggle('ffz-dark', this.settings.dark_twitch);
|
||||||
|
|
||||||
if ( ! this.settings.dark_twitch )
|
if ( ! this.settings.dark_twitch )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -226,6 +227,24 @@ FFZ.prototype._load_dark_css = function() {
|
||||||
|
|
||||||
s.id = "ffz-dark-css";
|
s.id = "ffz-dark-css";
|
||||||
s.setAttribute('rel', 'stylesheet');
|
s.setAttribute('rel', 'stylesheet');
|
||||||
s.setAttribute('href', constants.SERVER + "script/dark" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
s.setAttribute('href', constants.SERVER + "script/dark" + (this.is_clips ? '-clips' : '') + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype.add_clips_darken_button = function() {
|
||||||
|
if ( this.embed_in_clips )
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.log("Adding Clips Darken button.");
|
||||||
|
|
||||||
|
var f = this,
|
||||||
|
btn = utils.createElement('a', 'button button--hollow ffz-darken-clips', f.settings.dark_twitch ? 'Light' : 'Dark');
|
||||||
|
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
f.settings.set('dark_twitch', ! f.settings.dark_twitch);
|
||||||
|
btn.textContent = f.settings.dark_twitch ? 'Light' : 'Dark';
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(btn);
|
||||||
}
|
}
|
|
@ -299,20 +299,22 @@ FFZ.prototype._build_following_button = function(cont, channel_id) {
|
||||||
return this.log("Ignoring Invalid Channel: " + utils.sanitize(channel_id));
|
return this.log("Ignoring Invalid Channel: " + utils.sanitize(channel_id));
|
||||||
|
|
||||||
var f = this,
|
var f = this,
|
||||||
btn = utils.createElement('button', 'follow-button button'),
|
btn = utils.createElement('button', 'follow-button button html-tooltip'),
|
||||||
|
|
||||||
noti = utils.createElement('a', 'toggle-notification-menu js-toggle-notification-menu'),
|
noti = utils.createElement('a', 'toggle-notification-menu js-toggle-notification-menu'),
|
||||||
noti_c = utils.createElement('div', 'notification-controls v2 hidden', noti),
|
noti_c = utils.createElement('div', 'notification-controls v2 hidden', noti),
|
||||||
|
|
||||||
display_name,
|
display_name,
|
||||||
|
tooltip,
|
||||||
|
|
||||||
following = false,
|
following = false,
|
||||||
notifications = false,
|
notifications = false,
|
||||||
|
|
||||||
update = function() {
|
update = function() {
|
||||||
btn.classList.toggle('is-following', following);
|
btn.classList.toggle('is-following', following);
|
||||||
btn.classList.toggle('button--status', following);
|
btn.classList.toggle('button--status', following);
|
||||||
btn.title = (following ? "Unf" : "F") + "ollow " + utils.sanitize(display_name);
|
btn.title = tooltip ? (following ? "Unf" : "F") + "ollow " + tooltip : '';
|
||||||
btn.innerHTML = (following ? "" : "Follow ") + utils.sanitize(display_name);
|
btn.innerHTML = (following ? "" : "Follow ") + display_name;
|
||||||
noti_c.classList.toggle('hidden', !following);
|
noti_c.classList.toggle('hidden', !following);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -353,7 +355,9 @@ FFZ.prototype._build_following_button = function(cont, channel_id) {
|
||||||
},
|
},
|
||||||
|
|
||||||
on_name = function(cap_name) {
|
on_name = function(cap_name) {
|
||||||
display_name = cap_name || channel_id;
|
var results = f.format_display_name(cap_name, channel_id, true, true);
|
||||||
|
display_name = results[0];
|
||||||
|
tooltip = results[1];
|
||||||
update();
|
update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -404,9 +408,7 @@ FFZ.prototype._build_following_button = function(cont, channel_id) {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
on_name(FFZ.get_capitalization(channel_id, on_name));
|
||||||
display_name = FFZ.get_capitalization(channel_id, on_name);
|
|
||||||
update();
|
|
||||||
|
|
||||||
setTimeout(check_following, Math.random()*5000);
|
setTimeout(check_following, Math.random()*5000);
|
||||||
|
|
||||||
|
@ -429,7 +431,9 @@ FFZ.prototype._build_following_popup = function(container, channel_id, notificat
|
||||||
this._popup_allow_parent = true;
|
this._popup_allow_parent = true;
|
||||||
this._popup_parent = container;
|
this._popup_parent = container;
|
||||||
|
|
||||||
out = '<div class="header">You are following ' + FFZ.get_capitalization(channel_id) + '</div>';
|
var results = this.format_display_name(FFZ.get_capitalization(channel_id), channel_id, true);
|
||||||
|
|
||||||
|
out = '<div class="header">You are following <span' + (results[1] ? ' class="html-tooltip" title="' + utils.quote_attr(results[1]) + '"' : '') + '>' + results[0] + '</span></div>';
|
||||||
out += '<p class="clearfix">';
|
out += '<p class="clearfix">';
|
||||||
out += '<a class="switch' + (notifications ? ' active' : '') + '"><span></span></a>';
|
out += '<a class="switch' + (notifications ? ' active' : '') + '"><span></span></a>';
|
||||||
out += '<span class="switch-label">Notify me when the broadcaster goes live</span>';
|
out += '<span class="switch-label">Notify me when the broadcaster goes live</span>';
|
||||||
|
|
|
@ -80,15 +80,10 @@ FFZ.prototype.setup_menu = function() {
|
||||||
if ( ! menu )
|
if ( ! menu )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var header = document.createElement('div'),
|
var header = utils.createElement('div', 'list-header', 'FrankerFaceZ'),
|
||||||
content = document.createElement('div'),
|
content = utils.createElement('div', 'chat-menu-content'),
|
||||||
p, cb, a;
|
p, cb, a;
|
||||||
|
|
||||||
header.className = 'list-header';
|
|
||||||
header.innerHTML = 'FrankerFaceZ';
|
|
||||||
|
|
||||||
content.className = 'chat-menu-content';
|
|
||||||
|
|
||||||
// Dark Twitch
|
// Dark Twitch
|
||||||
p = document.createElement('p');
|
p = document.createElement('p');
|
||||||
p.className = 'no-bttv';
|
p.className = 'no-bttv';
|
||||||
|
|
|
@ -504,7 +504,7 @@ FFZ.menu_pages.myemotes = {
|
||||||
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
|
menu_id = set.hasOwnProperty('source_ext') ? 'ffz-ext-' + set.source_ext + '-' + set.source_id : 'ffz-' + set.id,
|
||||||
favorites = this.settings.favorite_emotes[menu_id] || [],
|
favorites = this.settings.favorite_emotes[menu_id] || [],
|
||||||
c = 0,
|
c = 0,
|
||||||
icon = set.icon || (set.hasOwnProperty('source_ext') && '//cdn.frankerfacez.com/emoji/tw-1f4ac.svg') || '//cdn.frankerfacez.com/script/devicon.png',
|
icon = set.icon || (set.hasOwnProperty('source_ext') && this._apis[set.source_ext] && this._apis[set.source_ext].icon) || '//cdn.frankerfacez.com/script/devicon.png',
|
||||||
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1;
|
collapsed = ! favorites_only && this.settings.emote_menu_collapsed.indexOf(menu_id) === -1;
|
||||||
|
|
||||||
menu.className = 'emoticon-grid';
|
menu.className = 'emoticon-grid';
|
||||||
|
|
|
@ -11,7 +11,7 @@ FFZ.prototype.setup_css = function() {
|
||||||
var s = this._main_style = document.createElement('link');
|
var s = this._main_style = document.createElement('link');
|
||||||
s.id = "ffz-main-css";
|
s.id = "ffz-main-css";
|
||||||
s.setAttribute('rel', 'stylesheet');
|
s.setAttribute('rel', 'stylesheet');
|
||||||
s.setAttribute('href', constants.SERVER + "script/style" + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
s.setAttribute('href', constants.SERVER + "script/style" + (this.is_clips ? '-clips' : '') + (constants.DEBUG ? "" : ".min") + ".css?_=" + (constants.DEBUG ? Date.now() : FFZ.version_info));
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
|
|
||||||
this.log("Readying toggleable styles.");
|
this.log("Readying toggleable styles.");
|
||||||
|
|
127
style.css
127
style.css
|
@ -39,22 +39,24 @@ body:not(.ffz-show-bits-tags) .ember-chat .chat-messages.bits-tags__offset {
|
||||||
}
|
}
|
||||||
|
|
||||||
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + .ffz-ui-toggle svg,
|
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + .ffz-ui-toggle svg,
|
||||||
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + script + .ffz-ui-toggle svg
|
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + div + .ffz-ui-toggle svg
|
||||||
{
|
{
|
||||||
height: 14px;
|
height: 14px;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + .ffz-ui-toggle,
|
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + .ffz-ui-toggle,
|
||||||
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + script + .ffz-ui-toggle {
|
body:not(.ffz-minimal-chat-input):not(.ffz-menu-replace) .chat-interface .emoticon-selector-toggle + div + .ffz-ui-toggle {
|
||||||
height: 14px;
|
height: 14px;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
top: 28px;
|
top: 28px;
|
||||||
|
right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-ui-toggle svg.svg-emoticons path { fill: rgba(0,0,0,0.2); }
|
.ffz-ui-toggle svg.svg-emoticons path { fill: rgba(0,0,0,0.2); }
|
||||||
.ffz-ui-toggle:hover svg.svg-emoticons path { fill: rgba(0,0,0,0.5); }
|
.ffz-ui-toggle:hover svg.svg-emoticons path { fill: rgba(0,0,0,0.5); }
|
||||||
|
|
||||||
|
.carousel__item .card__img .overlay_info.live svg path,
|
||||||
.streams .stream .content .overlay_info.live svg path,
|
.streams .stream .content .overlay_info.live svg path,
|
||||||
.videos .video .content .overlay_info.live svg path { fill: #ff2020; }
|
.videos .video .content .overlay_info.live svg path { fill: #ff2020; }
|
||||||
|
|
||||||
|
@ -1257,7 +1259,8 @@ img.channel_background[src="null"] { display: none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.ember-chat .ffz-moderation-card .close-button {
|
.ember-chat .ffz-moderation-card .close-button {
|
||||||
right: 7px;
|
right: 7px;
|
||||||
|
width: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ember-chat .ffz-moderation-card .extra-interface {
|
.ember-chat .ffz-moderation-card .extra-interface {
|
||||||
|
@ -1268,13 +1271,17 @@ img.channel_background[src="null"] { display: none; }
|
||||||
margin-top: -10px;
|
margin-top: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-moderation-card.ffz-has-info h3.name {
|
.ffz-moderation-card.ffz-has-info h4.name {
|
||||||
margin-top: -2px;
|
/*margin-top: -2px;*/
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-moderation-card.ffz-has-info .name .intl-login {
|
||||||
|
margin: -2px 0 -4px;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-moderation-card .info {
|
.ffz-moderation-card .info {
|
||||||
float: none;
|
float: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1359,10 +1366,10 @@ img.channel_background[src="null"] { display: none; }
|
||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-moderation-card h3.name { display: inline-block; }
|
.ffz-moderation-card h4.name { display: inline-block; }
|
||||||
|
|
||||||
.ffz-moderation-card .info,
|
.ffz-moderation-card .info,
|
||||||
.ffz-moderation-card h3.name {
|
.ffz-moderation-card h4.name {
|
||||||
text-shadow: black 0 0 5px;
|
text-shadow: black 0 0 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1403,7 +1410,7 @@ img.channel_background[src="null"] { display: none; }
|
||||||
background-color: #232323;
|
background-color: #232323;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moderation-card h3.name a { color: #fff !important; }
|
.moderation-card h4.name a { color: #fff !important; }
|
||||||
|
|
||||||
|
|
||||||
/* purge icon */
|
/* purge icon */
|
||||||
|
@ -1799,7 +1806,7 @@ th.ffz-row-switch {
|
||||||
.ffz-room-row td > span:empty,
|
.ffz-room-row td > span:empty,
|
||||||
.ffz-chat-tab span:empty { display: none; }
|
.ffz-chat-tab span:empty { display: none; }
|
||||||
|
|
||||||
.ffz-room-row td > span,
|
.ffz-room-row td > span:not(.intl-login),
|
||||||
.ffz-chat-tab span {
|
.ffz-chat-tab span {
|
||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -1815,7 +1822,7 @@ th.ffz-row-switch {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-room-row td > span {
|
.ffz-room-row td > span:not(.intl-login) {
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
@ -1860,7 +1867,7 @@ th.ffz-row-switch {
|
||||||
color: #B9A3E3;
|
color: #B9A3E3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark .ffz-room-row td > span,
|
.ffz-dark .ffz-room-row td > span:not(.intl-login),
|
||||||
.app-main.theatre .ffz-chat-tab span,
|
.app-main.theatre .ffz-chat-tab span,
|
||||||
.chat-container.dark .ffz-chat-tab span,
|
.chat-container.dark .ffz-chat-tab span,
|
||||||
.ember-chat-container.dark .ffz-chat-tab span {
|
.ember-chat-container.dark .ffz-chat-tab span {
|
||||||
|
@ -2186,11 +2193,11 @@ body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-inter
|
||||||
.ffz-no-blue .theatre .conversation-system-message,
|
.ffz-no-blue .theatre .conversation-system-message,
|
||||||
.ffz-no-blue.ffz-dark .conversation-system-message,
|
.ffz-no-blue.ffz-dark .conversation-system-message,
|
||||||
|
|
||||||
.ffz-no-blue .theatre .bits-card,
|
.ffz-no-blue .app-main.theatre .bits-card,
|
||||||
.ffz-no-blue .dark .bits-card,
|
.ffz-no-blue .dark .bits-card,
|
||||||
.ffz-no-blue .force-dark .bits-card,
|
.ffz-no-blue .force-dark .bits-card,
|
||||||
|
|
||||||
.ffz-no-blue .theatre .bits-card--standard,
|
.ffz-no-blue .app-main.theatre .bits-card--standard,
|
||||||
.ffz-no-blue .dark .bits-card--standard,
|
.ffz-no-blue .dark .bits-card--standard,
|
||||||
.ffz-no-blue .force-dark .bits-card--standard,
|
.ffz-no-blue .force-dark .bits-card--standard,
|
||||||
|
|
||||||
|
@ -2256,6 +2263,10 @@ body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-inter
|
||||||
background-color: #191919;
|
background-color: #191919;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-no-blue .app-main.theatre .bits-footer,
|
||||||
|
.ffz-no-blue .dark .bits-footer,
|
||||||
|
.ffz-no-blue .force-dark .bits-footer,
|
||||||
|
|
||||||
.ffz-no-blue .theatre .conversation-input-bar textarea,
|
.ffz-no-blue .theatre .conversation-input-bar textarea,
|
||||||
.ffz-no-blue .theatre input.text,
|
.ffz-no-blue .theatre input.text,
|
||||||
.ffz-no-blue .theatre input.countries-input,
|
.ffz-no-blue .theatre input.countries-input,
|
||||||
|
@ -2320,13 +2331,13 @@ body:not([data-current-path^="user."]) .ffz-sidebar-swap .ember-chat .chat-inter
|
||||||
border-bottom-color: #323232;
|
border-bottom-color: #323232;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-no-blue .theatre .conversation-header,
|
.ffz-no-blue .theatre .convoHeader,
|
||||||
.ffz-no-blue.ffz-dark .conversation-header,
|
.ffz-no-blue.ffz-dark .convoHeader,
|
||||||
.ffz-no-blue .theatre .conversations-list .search-divider,
|
.ffz-no-blue .theatre .conversations-list .search-divider,
|
||||||
.ffz-no-blue.ffz-dark .conversations-list .search-divider,
|
.ffz-no-blue.ffz-dark .conversations-list .search-divider,
|
||||||
.ffz-no-blue.ffz-dark .conversations-list .conversations-list-header,
|
.ffz-no-blue.ffz-dark .conversations-list .conversations-list-header,
|
||||||
.ffz-no-blue .theatre .conversation-window.has-focus .conversation-header,
|
.ffz-no-blue .theatre .conversation-window.has-focus .convoHeader,
|
||||||
.ffz-no-blue.ffz-dark .conversation-window.has-focus .conversation-header,
|
.ffz-no-blue.ffz-dark .conversation-window.has-focus .convoHeader,
|
||||||
.ffz-no-blue .theatre .conversations-list .conversations-list-item:hover,
|
.ffz-no-blue .theatre .conversations-list .conversations-list-item:hover,
|
||||||
.ffz-no-blue.ffz-dark .conversations-list .conversations-list-item:hover {
|
.ffz-no-blue.ffz-dark .conversations-list .conversations-list-item:hover {
|
||||||
background-color: #121212;
|
background-color: #121212;
|
||||||
|
@ -2418,7 +2429,7 @@ li[data-name="following"] a {
|
||||||
max-height: 90px;
|
max-height: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Player Captions *\/
|
/* Player Captions */
|
||||||
|
|
||||||
.ffz-dark .player-modal__content,
|
.ffz-dark .player-modal__content,
|
||||||
.theatre .player-modal__content {
|
.theatre .player-modal__content {
|
||||||
|
@ -2457,7 +2468,7 @@ li[data-name="following"] a {
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-dark label.cc-edge-palette__square,
|
.ffz-dark label.cc-edge-palette__square,
|
||||||
.theatre label.cc-edge-palette__square { color: #fff }*/
|
.theatre label.cc-edge-palette__square { color: #fff }
|
||||||
|
|
||||||
|
|
||||||
/* Classic Player */
|
/* Classic Player */
|
||||||
|
@ -2484,12 +2495,12 @@ li[data-name="following"] a {
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-classic-player .app-main.theatre .player .player-video,
|
.ffz-classic-player .app-main.theatre .player .player-video,
|
||||||
.ffz-classic-player .player[data-fullscreen="true"] .player-video {
|
.ffz-classic-player .player[data-isfullscreen="true"] .player-video {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-classic-player .app-main.theatre .player .player-controls-bottom,
|
.ffz-classic-player .app-main.theatre .player .player-controls-bottom,
|
||||||
.ffz-classic-player .player[data-fullscreen="true"] .player-controls-bottom {
|
.ffz-classic-player .player[data-isfullscreen="true"] .player-controls-bottom {
|
||||||
margin-bottom: -32px;
|
margin-bottom: -32px;
|
||||||
-webkit-transition: margin-bottom .2s ease-out, padding-bottom .2s ease-out;
|
-webkit-transition: margin-bottom .2s ease-out, padding-bottom .2s ease-out;
|
||||||
transition: margin-bottom .2s ease-out, padding-bottom .2s ease-out;
|
transition: margin-bottom .2s ease-out, padding-bottom .2s ease-out;
|
||||||
|
@ -2497,23 +2508,22 @@ li[data-name="following"] a {
|
||||||
|
|
||||||
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player .player-controls-bottom,
|
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player .player-controls-bottom,
|
||||||
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player[data-controls=true] .player-controls-bottom,
|
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player[data-controls=true] .player-controls-bottom,
|
||||||
.ffz-classic-player .app-main.theatre .player[data-fullscreen="true"] .player-controls-bottom,
|
.ffz-classic-player .app-main.theatre .player[data-isfullscreen="true"] .player-controls-bottom,
|
||||||
.ffz-classic-player .app-main.theatre .player[data-fullscreen="true"][data-controls=true] .player-controls-bottom {
|
.ffz-classic-player .app-main.theatre .player[data-isfullscreen="true"][data-controls=true] .player-controls-bottom {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-classic-player .app-main.theatre .player.player-isvod .player-controls-bottom,
|
.ffz-classic-player .app-main.theatre .player.player-isvod .player-controls-bottom,
|
||||||
.ffz-classic-player .player.player-isvod[data-fullscreen="true"] .player-controls-bottom {
|
.ffz-classic-player .player.player-isvod[data-isfullscreen="true"] .player-controls-bottom {
|
||||||
margin-bottom: -36px;
|
margin-bottom: -36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-classic-player .app-main.theatre .player-column:hover .player .player-controls-bottom,
|
.ffz-classic-player .app-main.theatre .player-column .player[data-controls=true] .player-controls-bottom,
|
||||||
.ffz-classic-player .app-main.theatre .player-column:focus .player .player-controls-bottom,
|
.ffz-classic-player .player[data-isfullscreen="true"][data-controls="true"] .player-controls-bottom {
|
||||||
.ffz-classic-player .player[data-fullscreen="true"][data-controls="true"] .player-controls-bottom {
|
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player-column:hover .player[data-fullscreen="false"] .player-controls-bottom {
|
.ffz-classic-player:not(.ffz-top-conversations):not(.ffz-theatre-conversations) .app-main.theatre .player[data-isfullscreen=false][data-controls=true] .player-controls-bottom {
|
||||||
padding-bottom: 40px;
|
padding-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2569,8 +2579,14 @@ li[data-name="following"] a {
|
||||||
.item .meta .title a a,
|
.item .meta .title a a,
|
||||||
.item .meta .title a img { pointer-events: none }
|
.item .meta .title a img { pointer-events: none }
|
||||||
|
|
||||||
|
.ffz-directory-logo .card__body,
|
||||||
|
.ffz-directory-logo .meta {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ffz-directory-logo .card__title,
|
||||||
.ffz-directory-logo .meta p.title {
|
.ffz-directory-logo .meta p.title {
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
min-height: 24px;
|
min-height: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2656,11 +2672,9 @@ body:not(.ffz-bttv) .conversation-window .ignore-cta:not(.hidden) + .conversatio
|
||||||
.conversation-window.collapsed .ignore-cta,
|
.conversation-window.collapsed .ignore-cta,
|
||||||
.conversation-chat-line.action .colon,
|
.conversation-chat-line.action .colon,
|
||||||
.conversation-input-bar .emoticon-selector .tabs,
|
.conversation-input-bar .emoticon-selector .tabs,
|
||||||
.conversation-preview-line .badges,
|
.conversation-preview-line .badges { display:none }
|
||||||
body.ffz-conv-title-clickable .conversation-header span.conversation-header-name,
|
|
||||||
body:not(.ffz-conv-title-clickable) .conversation-header a.conversation-header-name { display:none }
|
|
||||||
|
|
||||||
.conversation-window.has-unread .conversation-header .conversation-header-name { color: #fff !important; }
|
.conversation-window.has-unread .convoHeader .username { color: #fff !important; }
|
||||||
|
|
||||||
|
|
||||||
/* Top Conversations */
|
/* Top Conversations */
|
||||||
|
@ -2680,7 +2694,7 @@ body:not(.ffz-top-conversations) .conversations-list-bottom-bar {
|
||||||
top: 0px;
|
top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-top-conversations .conversation-window.collapsed .conversation-header {
|
.ffz-top-conversations .conversation-window.collapsed .convoHeader {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2758,13 +2772,15 @@ body:not(.ffz-top-conversations) .conversations-list-bottom-bar {
|
||||||
|
|
||||||
.user.item { position: relative; }
|
.user.item { position: relative; }
|
||||||
|
|
||||||
|
.card__img .overlay_info.length,
|
||||||
.user.item .overlay_info.length {
|
.user.item .overlay_info.length {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
right: 25px;
|
right: 15px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
@ -2775,18 +2791,20 @@ body:not(.ffz-top-conversations) .conversations-list-bottom-bar {
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card__img .overlay_info.length { right: 5px }
|
||||||
|
|
||||||
|
.card__img .overlay_info.length svg,
|
||||||
.user.item .overlay_info.length svg {
|
.user.item .overlay_info.length svg {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 3px 5px 3px 0;
|
margin: 3px 5px 3px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card__img .overlay_info.length svg path,
|
||||||
.user.item .actions .follow svg path,
|
.user.item .actions .follow svg path,
|
||||||
.user.item .overlay_info.length svg path { fill: #fff; }
|
.user.item .overlay_info.length svg path { fill: #fff; }
|
||||||
|
|
||||||
.user.item .actions {
|
.user.item .actions {
|
||||||
margin-top: -15px;
|
margin-top: 5px;
|
||||||
margin-bottom: 20px;
|
|
||||||
margin-right: 20px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
@ -2901,10 +2919,12 @@ body:not(.ffz-creative-showcase) .ct-spotlight-container { display: none; }
|
||||||
|
|
||||||
/* Banned and Spoiler Games */
|
/* Banned and Spoiler Games */
|
||||||
|
|
||||||
body:not([data-current-path^="directory.csgo"]):not([data-current-path^="directory.game"]):not([data-current-path^="directory.creative"]) .ffz-game-banned { display: none }
|
body:not([data-current-path^="directory.csgo"]):not([data-current-path^="directory.game"]):not([data-current-path^="directory.creative"]) .ffz-game-banned { display: none !important }
|
||||||
|
|
||||||
|
.ffz-game-spoilered .card__img a:not(.card__boxpin) img,
|
||||||
.ffz-game-spoilered .thumb .cap img { visibility: hidden }
|
.ffz-game-spoilered .thumb .cap img { visibility: hidden }
|
||||||
|
|
||||||
|
.ffz-game-spoilered .card__img a:not(.card__boxpin):after,
|
||||||
.ffz-game-spoilered .thumb .cap:after {
|
.ffz-game-spoilered .thumb .cap:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0; left: 0;
|
top: 0; left: 0;
|
||||||
|
@ -2986,7 +3006,7 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
|
|
||||||
/* Hide Outlines */
|
/* Hide Outlines */
|
||||||
|
|
||||||
.conversation-header,
|
.convoHeader,
|
||||||
.conversations-list-icon,
|
.conversations-list-icon,
|
||||||
.toggle-notification-menu {
|
.toggle-notification-menu {
|
||||||
outline: none !important
|
outline: none !important
|
||||||
|
@ -2997,6 +3017,10 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
|
|
||||||
.badges .badge { background-size: 18px 18px }
|
.badges .badge { background-size: 18px 18px }
|
||||||
|
|
||||||
|
.convoHeader .badges .badge {
|
||||||
|
background-size: 14px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
/*.badges .badge {
|
/*.badges .badge {
|
||||||
height: 18px;
|
height: 18px;
|
||||||
min-width: 18px;
|
min-width: 18px;
|
||||||
|
@ -3145,6 +3169,29 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
content: attr(data-amount);
|
content: attr(data-amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theatre .bits-purchase__header,
|
||||||
|
.dark .bits-purchase__header,
|
||||||
|
.force-dark .bits-purchase__header {
|
||||||
|
color: #acacbf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theatre .bits-card,
|
||||||
|
.app-main.theatre .chat-container .bits-card, /* Twitch's CSS is retarded */
|
||||||
|
.dark .bits-card,
|
||||||
|
.force-dark .bits-card,
|
||||||
|
|
||||||
|
.theatre .bits-purchase__row,
|
||||||
|
.dark .bits-purchase__row,
|
||||||
|
.force-dark .bits-purchase__row,
|
||||||
|
|
||||||
|
.theatre .bits-footer,
|
||||||
|
.dark .bits-footer,
|
||||||
|
.force-dark .bits-footer {
|
||||||
|
border-color: rgba(255,255,255,0.2);
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* New Chat Formatting */
|
/* New Chat Formatting */
|
||||||
|
|
||||||
.ember-chat .chat-messages .timestamp { margin-right: 0; }
|
.ember-chat .chat-messages .timestamp { margin-right: 0; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue