1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-26 20:48:30 +00:00
FrankerFaceZ/src/ember/channel.js

572 lines
15 KiB
JavaScript
Raw Normal View History

var FFZ = window.FrankerFaceZ,
utils = require('../utils'),
constants = require('../constants');
// --------------------
// Initialization
// --------------------
FFZ.prototype.setup_channel = function() {
2015-07-04 17:06:36 -04:00
// Style Stuff!
this.log("Creating channel style element.");
var s = this._channel_style = document.createElement("style");
s.id = "ffz-channel-css";
document.head.appendChild(s);
2015-06-05 03:59:28 -04:00
// Settings stuff!
document.body.classList.toggle("ffz-hide-view-count", !this.settings.channel_views);
this.log("Creating channel style element.");
var s = this._channel_style = document.createElement('style');
s.id = "ffz-channel-css";
document.head.appendChild(s);
2015-06-05 03:59:28 -04:00
this.log("Hooking the Ember Channel Index view.");
var Channel = App.__container__.resolve('view:channel/index'),
f = this;
if ( ! Channel )
return;
2015-06-05 03:59:28 -04:00
this._modify_cindex(Channel);
// The Stupid View Fix. Is this necessary still?
try {
Channel.create().destroy();
} catch(err) { }
// Update Existing
for(var key in Ember.View.views) {
if ( ! Ember.View.views.hasOwnProperty(key) )
continue;
var view = Ember.View.views[key];
if ( !(view instanceof Channel) )
continue;
this.log("Manually updating Channel Index view.", view);
this._modify_cindex(view);
view.ffzInit();
};
this.log("Hooking the Ember Channel model.");
Channel = App.__container__.resolve('model:channel');
if ( ! Channel )
return;
Channel.reopen({
ffz_host_target: undefined,
setHostMode: function(e) {
if ( f.settings.hosted_channels ) {
this.set('ffz_host_target', e.target);
return this._super(e);
} else {
this.set('ffz_host_target', undefined);
return this._super({target: void 0, delay: 0});
}
}
});
2015-06-05 03:59:28 -04:00
this.log("Hooking the Ember Channel controller.");
Channel = App.__container__.lookup('controller:channel');
if ( ! Channel )
return;
Channel.reopen({
ffzUpdateUptime: function() {
2015-06-05 03:59:28 -04:00
if ( f._cindex )
f._cindex.ffzUpdateUptime();
2015-06-05 03:59:28 -04:00
}.observes("isLive", "content.id"),
2015-06-05 03:59:28 -04:00
ffzUpdateTitle: function() {
var name = this.get('content.name'),
display_name = this.get('content.display_name');
2015-06-05 03:59:28 -04:00
if ( display_name )
FFZ.capitalization[name] = [display_name, Date.now()];
2015-06-05 03:59:28 -04:00
if ( f._cindex )
f._cindex.ffzFixTitle();
2015-06-10 18:46:04 -04:00
}.observes("content.status", "content.id"),
2015-06-10 18:46:04 -04:00
ffzHostTarget: function() {
2015-06-05 03:59:28 -04:00
var target = this.get('content.hostModeTarget'),
name = target && target.get('name'),
2015-07-04 17:06:36 -04:00
id = target && target.get('id'),
2015-06-05 03:59:28 -04:00
display_name = target && target.get('display_name');
2015-07-04 17:06:36 -04:00
if ( id !== f.__old_host_target ) {
if ( f.__old_host_target )
f.ws_send("unsub_channel", f.__old_host_target);
if ( id ) {
f.ws_send("sub_channel", id);
f.__old_host_target = id;
} else
delete f.__old_host_target;
}
2015-06-05 03:59:28 -04:00
if ( display_name )
FFZ.capitalization[name] = [display_name, Date.now()];
2015-06-05 03:59:28 -04:00
if ( f.settings.group_tabs && f._chatv )
f._chatv.ffzRebuildTabs();
2015-07-04 17:06:36 -04:00
if ( f.settings.follow_buttons )
f.rebuild_following_ui();
if ( f.settings.srl_races )
f.rebuild_race_ui();
2015-06-10 18:46:04 -04:00
}.observes("content.hostModeTarget")
2015-06-05 03:59:28 -04:00
});
}
2015-06-05 03:59:28 -04:00
FFZ.prototype._modify_cindex = function(view) {
var f = this;
2015-06-05 03:59:28 -04:00
view.reopen({
didInsertElement: function() {
this._super();
try {
this.ffzInit();
} catch(err) {
f.error("CIndex didInsertElement: " + err);
}
},
2015-06-05 03:59:28 -04:00
willClearRender: function() {
try {
this.ffzTeardown();
} catch(err) {
f.error("CIndex willClearRender: " + err);
}
return this._super();
},
ffzInit: function() {
2015-07-04 17:06:36 -04:00
var id = this.get('controller.id'),
el = this.get('element');
2015-06-05 03:59:28 -04:00
f._cindex = this;
2015-07-04 17:06:36 -04:00
f.ws_send("sub_channel", id);
el.setAttribute('data-channel', id);
el.classList.add('ffz-channel');
// Try changing the theater mode tooltip.
this.$('.theatre-button a').attr('title', 'Theater Mode (Alt+T)');
2015-06-05 03:59:28 -04:00
this.ffzFixTitle();
this.ffzUpdateUptime();
this.ffzUpdateChatters();
this.ffzUpdateHostButton();
2015-06-05 03:59:28 -04:00
2015-07-04 17:06:36 -04:00
var views = this.get('element').querySelector('.svg-glyph_views:not(.ffz-svg)')
if ( views )
views.parentNode.classList.add('twitch-channel-views');
if ( f.settings.follow_buttons )
f.rebuild_following_ui();
if ( f.settings.srl_races )
f.rebuild_race_ui();
2015-06-05 03:59:28 -04:00
},
ffzFixTitle: function() {
if ( f.has_bttv || ! f.settings.stream_title )
return;
var status = this.get("controller.status"),
channel = this.get("controller.id");
status = f.render_tokens(f.tokenize_line(channel, channel, status, true));
this.$(".title span").each(function(i, el) {
var scripts = el.querySelectorAll("script");
2015-07-04 17:06:36 -04:00
if ( ! scripts.length )
el.innerHTML = status;
else
el.innerHTML = scripts[0].outerHTML + status + scripts[1].outerHTML;
2015-06-05 03:59:28 -04:00
});
},
ffzUpdateHostButton: function() {
var channel_id = this.get('controller.id'),
hosted_id = this.get('controller.hostModeTarget.id'),
user = f.get_user(),
room = user && f.rooms && f.rooms[user.login] && f.rooms[user.login].room,
now_hosting = room && room.ffz_host_target,
hosts_left = room && room.ffz_hosts_left,
el = this.get('element');
this.set('ffz_host_updating', false);
if ( channel_id ) {
var container = el && el.querySelector('.stats-and-actions .channel-actions'),
btn = container && container.querySelector('#ffz-ui-host-button');
if ( ! container || ! f.settings.stream_host_button || ! user || user.login === channel_id ) {
if ( btn )
btn.parentElement.removeChild(btn);
} else {
if ( ! btn ) {
btn = document.createElement('span');
btn.id = 'ffz-ui-host-button';
btn.className = 'button action tooltip';
btn.addEventListener('click', this.ffzClickHost.bind(btn, this, false));
var before = container.querySelector(':scope > .theatre-button');
if ( before )
container.insertBefore(btn, before);
else
container.appendChild(btn);
}
btn.classList.remove('disabled');
btn.innerHTML = channel_id === now_hosting ? 'Unhost' : 'Host';
if ( now_hosting )
btn.title = 'You are now hosting ' + utils.sanitize(FFZ.get_capitalization(now_hosting)) + '.';
else
btn.title = 'You are not hosting any channel.';
if ( typeof hosts_left === "number" )
btn.title += ' You have ' + hosts_left + ' host command' + utils.pluralize(hosts_left) + ' remaining this half hour.';
}
}
if ( hosted_id ) {
var container = el && el.querySelector('#hostmode .channel-actions'),
btn = container && container.querySelector('#ffz-ui-host-button');
if ( ! container || ! f.settings.stream_host_button || ! user || user.login === hosted_id ) {
if ( btn )
btn.parentElement.removeChild(btn);
} else {
if ( ! btn ) {
btn = document.createElement('span');
btn.id = 'ffz-ui-host-button';
btn.className = 'button action tooltip';
btn.addEventListener('click', this.ffzClickHost.bind(btn, this, true));
var before = container.querySelector(':scope > .theatre-button');
if ( before )
container.insertBefore(btn, before);
else
container.appendChild(btn);
}
btn.classList.remove('disabled');
btn.innerHTML = hosted_id === now_hosting ? 'Unhost' : 'Host';
if ( now_hosting )
btn.title = 'You are currently hosting ' + utils.sanitize(FFZ.get_capitalization(now_hosting)) + '. Click to ' + (hosted_id === now_hosting ? 'unhost' : 'host') + ' this channel.';
else
btn.title = 'You are not currently hosting any channel. Click to host this channel.';
if ( typeof hosts_left === "number" )
btn.title += ' You have ' + hosts_left + ' host command' + utils.pluralize(hosts_left) + ' remaining this half hour.';
}
}
},
ffzClickHost: function(controller, is_host) {
var target = controller.get(is_host ? 'controller.hostModeTarget.id' : 'controller.id'),
user = f.get_user(),
room = user && f.rooms && f.rooms[user.login] && f.rooms[user.login].room,
now_hosting = room && room.ffz_host_target;
if ( ! room || controller.get('ffz_host_updating') )
return;
this.classList.add('disabled');
this.title = 'Updating...';
controller.set('ffz_host_updating', true);
if ( now_hosting === target )
room.send("/unhost");
else
room.send("/host " + target);
},
2015-06-05 03:59:28 -04:00
ffzUpdateChatters: function() {
// Get the counts.
var room_id = this.get('controller.id'),
room = f.rooms && f.rooms[room_id];
if ( ! room || ! f.settings.chatter_count ) {
var el = this.get('element').querySelector('#ffz-chatter-display');
el && el.parentElement.removeChild(el);
el = this.get('element').querySelector('#ffz-ffzchatter-display');
el && el.parentElement.removeChild(el);
return;
2015-06-05 03:59:28 -04:00
}
2015-06-05 03:59:28 -04:00
var chatter_count = Object.keys(room.room.get('ffz_chatters') || {}).length,
2015-07-04 17:06:36 -04:00
ffz_chatters = room.ffz_chatters || 0,
ffz_viewers = room.ffz_viewers || 0;
2015-06-05 03:59:28 -04:00
var el = this.get('element').querySelector('#ffz-chatter-display span');
if ( ! el ) {
var cont = this.get('element').querySelector('.stats-and-actions .channel-stats');
if ( ! cont )
return;
2015-06-05 03:59:28 -04:00
var stat = document.createElement('span');
stat.className = 'ffz stat';
stat.id = 'ffz-chatter-display';
2015-07-04 17:06:36 -04:00
stat.title = "Currently in Chat";
2015-06-05 03:59:28 -04:00
stat.innerHTML = constants.ROOMS + " ";
el = document.createElement("span");
stat.appendChild(el);
2015-06-05 03:59:28 -04:00
var other = cont.querySelector("#ffz-ffzchatter-display");
if ( other )
cont.insertBefore(stat, other);
else
cont.appendChild(stat);
2015-06-05 03:59:28 -04:00
jQuery(stat).tipsy();
}
2015-06-05 03:59:28 -04:00
el.innerHTML = utils.number_commas(chatter_count);
2015-07-04 17:06:36 -04:00
if ( ! ffz_chatters && ! ffz_viewers ) {
2015-06-05 03:59:28 -04:00
el = this.get('element').querySelector('#ffz-ffzchatter-display');
el && el.parentNode.removeChild(el);
return;
}
2015-06-05 03:59:28 -04:00
el = this.get('element').querySelector('#ffz-ffzchatter-display span');
if ( ! el ) {
var cont = this.get('element').querySelector('.stats-and-actions .channel-stats');
if ( ! cont )
return;
2015-06-05 03:59:28 -04:00
var stat = document.createElement('span');
stat.className = 'ffz stat';
stat.id = 'ffz-ffzchatter-display';
2015-07-04 17:06:36 -04:00
stat.title = "Viewers (In Chat) with FrankerFaceZ";
2015-06-05 03:59:28 -04:00
stat.innerHTML = constants.ZREKNARF + " ";
el = document.createElement("span");
stat.appendChild(el);
2015-06-05 03:59:28 -04:00
var other = cont.querySelector("#ffz-chatter-display");
if ( other )
cont.insertBefore(stat, other.nextSibling);
else
cont.appendChild(stat);
2015-06-05 03:59:28 -04:00
jQuery(stat).tipsy();
}
2015-07-04 17:06:36 -04:00
el.innerHTML = utils.number_commas(ffz_viewers) + " (" + utils.number_commas(ffz_chatters) + ")";
2015-06-05 03:59:28 -04:00
},
2015-06-05 03:59:28 -04:00
ffzUpdateUptime: function() {
if ( this._ffz_update_uptime ) {
clearTimeout(this._ffz_update_uptime);
delete this._ffz_update_uptime;
}
if ( ! f.settings.stream_uptime || ! this.get("controller.isLiveAccordingToKraken") ) {
var el = this.get('element').querySelector('#ffz-uptime-display');
if ( el )
el.parentElement.removeChild(el);
return;
}
2015-06-05 03:59:28 -04:00
// Schedule an update.
this._ffz_update_uptime = setTimeout(this.ffzUpdateUptime.bind(this), 1000);
// Determine when the channel last went live.
var online = this.get("controller.content.stream.created_at");
if ( ! online )
return;
online = utils.parse_date(online);
if ( ! online )
return;
var uptime = Math.floor((Date.now() - online.getTime()) / 1000);
if ( uptime < 0 )
return;
var el = this.get('element').querySelector('#ffz-uptime-display span');
if ( ! el ) {
var cont = this.get('element').querySelector('.stats-and-actions .channel-stats');
if ( ! cont )
return;
var stat = document.createElement('span');
stat.className = 'ffz stat';
stat.id = 'ffz-uptime-display';
stat.title = "Stream Uptime <nobr>(since " + online.toLocaleString() + ")</nobr>";
stat.innerHTML = constants.CLOCK + " ";
el = document.createElement("span");
stat.appendChild(el);
var viewers = cont.querySelector(".live-count");
if ( viewers )
cont.insertBefore(stat, viewers.nextSibling);
else {
try {
viewers = cont.querySelector("script:nth-child(0n+2)");
cont.insertBefore(stat, viewers.nextSibling);
} catch(err) {
cont.insertBefore(stat, cont.childNodes[0]);
}
}
jQuery(stat).tipsy({html: true});
}
el.innerHTML = utils.time_to_string(uptime);
},
ffzTeardown: function() {
2015-07-04 17:06:36 -04:00
var id = this.get('controller.id');
if ( id )
f.ws_send("unsub_channel", id);
2015-06-05 03:59:28 -04:00
this.get('element').setAttribute('data-channel', '');
f._cindex = undefined;
if ( this._ffz_update_uptime )
clearTimeout(this._ffz_update_uptime);
2015-07-04 17:06:36 -04:00
utils.update_css(f._channel_style, id, null);
}
2015-06-05 03:59:28 -04:00
});
}
2015-06-05 03:59:28 -04:00
// ---------------
// Settings
// ---------------
FFZ.settings_info.chatter_count = {
type: "boolean",
value: false,
no_mobile: true,
2015-06-05 03:59:28 -04:00
category: "Channel Metadata",
name: "Chatter Count",
help: "Display the current number of users connected to chat beneath the channel.",
on_update: function(val) {
if ( this._cindex )
this._cindex.ffzUpdateChatters();
if ( ! val || ! this.rooms )
return;
// Refresh the data.
for(var room_id in this.rooms)
this.rooms.hasOwnProperty(room_id) && this.rooms[room_id].room && this.rooms[room_id].room.ffzInitChatterCount();
}
};
FFZ.settings_info.channel_views = {
type: "boolean",
value: true,
no_mobile: true,
2015-06-05 03:59:28 -04:00
category: "Channel Metadata",
name: "Channel Views",
help: 'Display the number of times the channel has been viewed beneath the stream.',
on_update: function(val) {
document.body.classList.toggle("ffz-hide-view-count", !val);
}
};
FFZ.settings_info.hosted_channels = {
type: "boolean",
value: true,
no_mobile: true,
category: "Channel Metadata",
name: "Channel Hosting",
help: "Display other channels that have been featured by the current channel.",
on_update: function(val) {
var cb = document.querySelector('input.ffz-setting-hosted-channels');
if ( cb )
cb.checked = val;
if ( ! this._cindex )
return;
var chan = this._cindex.get('controller.model'),
room = chan && this.rooms && this.rooms[chan.get('id')],
target = room && room.room && room.room.get('ffz_host_target');
if ( ! chan || ! room )
return;
chan.setHostMode({target: target, delay: 0});
}
};
FFZ.settings_info.stream_host_button = {
type: "boolean",
value: true,
no_mobile: true,
category: "Channel Metadata",
name: "Host This Channel Button",
help: "Display a button underneath streams that make it easy to host them with your own channel.",
on_update: function(val) {
if ( this._cindex )
this._cindex.ffzUpdateHostButton();
}
};
2015-06-05 03:59:28 -04:00
FFZ.settings_info.stream_uptime = {
type: "boolean",
value: false,
no_mobile: true,
2015-06-05 03:59:28 -04:00
category: "Channel Metadata",
name: "Stream Uptime",
help: 'Display the stream uptime under a channel by the viewer count.',
on_update: function(val) {
if ( this._cindex )
this._cindex.ffzUpdateUptime();
}
};
FFZ.settings_info.stream_title = {
type: "boolean",
value: true,
no_bttv: true,
no_mobile: true,
2015-06-05 03:59:28 -04:00
category: "Channel Metadata",
name: "Title Links",
help: "Make links in stream titles clickable.",
on_update: function(val) {
if ( this._cindex )
this._cindex.ffzFixTitle();
}
};