mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-10 08:10:52 +00:00
3.5.325. Tab complete commands. CSS tweaks. Fix chat lines not updating.
This commit is contained in:
parent
1a52caab6b
commit
6ab4bd64a8
12 changed files with 354 additions and 34 deletions
|
@ -1,3 +1,15 @@
|
||||||
|
<div class="list-header">3.5.325 <time datetime="2016-10-12">(2016-10-12)</time></div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Added: Tab-complete commands in chat.</li>
|
||||||
|
<li>Fixed: When the channel title is on top and the page is narrow, don't display the needless separator bar above the channel metadata.</li>
|
||||||
|
<li>Fixed: Issue causing chat lines to stop updating when users are timed out.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="list-header">3.5.324 <time datetime="2016-10-12">(2016-10-12)</time></div>
|
||||||
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
|
<li>Fixed: The player wasn't being resized properly with BetterTTV when the chat width was changed.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<div class="list-header">3.5.323 <time datetime="2016-10-12">(2016-10-12)</time></div>
|
<div class="list-header">3.5.323 <time datetime="2016-10-12">(2016-10-12)</time></div>
|
||||||
<ul class="chat-menu-content menu-side-padding">
|
<ul class="chat-menu-content menu-side-padding">
|
||||||
<li>Changed: Refactor how the Debug tab of the About menu works so that it's easier to add more content.</li>
|
<li>Changed: Refactor how the Debug tab of the About menu works so that it's easier to add more content.</li>
|
||||||
|
|
|
@ -55,9 +55,10 @@ FFZ.settings_info.command_aliases = {
|
||||||
for(var i=0; i < this.settings.command_aliases.length; i++) {
|
for(var i=0; i < this.settings.command_aliases.length; i++) {
|
||||||
var pair = this.settings.command_aliases[i],
|
var pair = this.settings.command_aliases[i],
|
||||||
name = pair[0],
|
name = pair[0],
|
||||||
command = pair[1];
|
command = pair[1],
|
||||||
|
label = pair[2];
|
||||||
|
|
||||||
old_val.push(name + '=' + command);
|
old_val.push(name + (label ? ' ' + label : '') + '=' + command);
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.prompt(
|
utils.prompt(
|
||||||
|
@ -67,8 +68,10 @@ FFZ.settings_info.command_aliases = {
|
||||||
"Variables, such as arguments you provide running the custom command, can be inserted into the output.<hr>" +
|
"Variables, such as arguments you provide running the custom command, can be inserted into the output.<hr>" +
|
||||||
|
|
||||||
"All custom commands require names. Names go at the start of each line, and are separated from " +
|
"All custom commands require names. Names go at the start of each line, and are separated from " +
|
||||||
" the actual command by an equals sign. Do not include the leading slash or dot. Those are automatically included.<br>" +
|
"the actual command by an equals sign. Do not include the leading slash or dot. Those are automatically included. " +
|
||||||
"<strong>Example:</strong> <code>boop=/timeout {0} 15 Boop!</code><hr>" +
|
"You can also include a description of the arguments after the name but before the equals-sign " +
|
||||||
|
"to include a helpful reminder when using tab-completion with the command.<br>" +
|
||||||
|
"<strong>Example:</strong> <code>boop <user>=/timeout {0} 15 Boop!</code><hr>" +
|
||||||
|
|
||||||
"<code>{0}</code>, <code>{1}</code>, <code>{2}</code>, etc. will be replaced with any arguments you've supplied. " +
|
"<code>{0}</code>, <code>{1}</code>, <code>{2}</code>, etc. will be replaced with any arguments you've supplied. " +
|
||||||
"Follow an argument index with a <code>$</code> to also include all remaining arguments.<br>" +
|
"Follow an argument index with a <code>$</code> to also include all remaining arguments.<br>" +
|
||||||
|
@ -89,22 +92,35 @@ FFZ.settings_info.command_aliases = {
|
||||||
output = [];
|
output = [];
|
||||||
|
|
||||||
for(var i=0; i < vals.length; i++) {
|
for(var i=0; i < vals.length; i++) {
|
||||||
var cmd = vals[i],
|
var cmd = vals[i];
|
||||||
name,
|
if ( cmd.charAt(0) === '.' || cmd.charAt(0) === '/' )
|
||||||
|
cmd = cmd.substr(1);
|
||||||
|
|
||||||
|
var name,
|
||||||
|
label,
|
||||||
name_match = /^([^=]+)=/.exec(cmd);
|
name_match = /^([^=]+)=/.exec(cmd);
|
||||||
|
|
||||||
if ( ! cmd || ! cmd.length )
|
if ( ! cmd || ! cmd.length )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( name_match ) {
|
if ( name_match ) {
|
||||||
name = name_match[1].toLowerCase();
|
var ind = name_match[1].indexOf(' ');
|
||||||
|
if ( ind === -1 ) {
|
||||||
|
name = name_match[1].toLowerCase();
|
||||||
|
label = null;
|
||||||
|
} else {
|
||||||
|
name = name_match[1].substr(0,ind).toLowerCase();
|
||||||
|
label = name_match[1].substr(ind).trim();
|
||||||
|
}
|
||||||
|
|
||||||
cmd = cmd.substr(name_match[0].length);
|
cmd = cmd.substr(name_match[0].length);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push([name, cmd]);
|
output.push([name, cmd, label]);
|
||||||
}
|
}
|
||||||
|
|
||||||
f.settings.set("command_aliases", output);
|
f.settings.set("command_aliases", output);
|
||||||
|
|
||||||
}, 600, input);
|
}, 600, input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -117,14 +133,18 @@ FFZ.prototype.cache_command_aliases = function() {
|
||||||
for(var i=0; i < this.settings.command_aliases.length; i++) {
|
for(var i=0; i < this.settings.command_aliases.length; i++) {
|
||||||
var pair = this.settings.command_aliases[i],
|
var pair = this.settings.command_aliases[i],
|
||||||
name = pair[0],
|
name = pair[0],
|
||||||
command = pair[1];
|
command = pair[1],
|
||||||
|
label = pair[2];
|
||||||
|
|
||||||
// Skip taken/invalid names.
|
// Skip taken/invalid names.
|
||||||
if ( ! name || ! name.length || aliases[name] || KNOWN_COMMANDS.indexOf(name) !== -1 )
|
if ( ! name || ! name.length || aliases[name] || KNOWN_COMMANDS.indexOf(name) !== -1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
aliases[name] = command;
|
aliases[name] = [command, label];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( this._inputv )
|
||||||
|
Ember.propertyDidChange(this._inputv, 'ffz_commands');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -243,6 +263,9 @@ FFZ.chat_commands.card = function(room, args) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.card.label = '/card <user>';
|
||||||
|
FFZ.chat_commands.card.info = 'Open Moderation Card';
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.rules = function(room, args) {
|
FFZ.chat_commands.rules = function(room, args) {
|
||||||
var f = this,
|
var f = this,
|
||||||
|
@ -258,6 +281,8 @@ FFZ.chat_commands.rules = function(room, args) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.rules.info = 'Show Chat Room Rules';
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.open_link = function(room, args) {
|
FFZ.chat_commands.open_link = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
|
@ -267,6 +292,9 @@ FFZ.chat_commands.open_link = function(room, args) {
|
||||||
wnd.opener = null;
|
wnd.opener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.open_link.label = '/open_link <url>';
|
||||||
|
FFZ.chat_commands.open_link.info = 'Open URL in Tab';
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.fetch_link = function(room, args) {
|
FFZ.chat_commands.fetch_link = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
|
@ -318,6 +346,8 @@ FFZ.chat_commands.fetch_link = function(room, args) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.fetch_link.label = '/fetch_link <url> <i>[template]</i>';
|
||||||
|
FFZ.chat_commands.fetch_link.info = 'Fetch URL and Display in Chat';
|
||||||
|
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
|
@ -4,9 +4,90 @@ var FFZ = window.FrankerFaceZ,
|
||||||
|
|
||||||
is_android = navigator.userAgent.indexOf('Android') !== -1,
|
is_android = navigator.userAgent.indexOf('Android') !== -1,
|
||||||
|
|
||||||
|
MOD_COMMANDS = {
|
||||||
|
ban: {
|
||||||
|
label: '/ban <user> <i>[reason]</i>',
|
||||||
|
info: 'Permanently Ban User'
|
||||||
|
},
|
||||||
|
unban: {
|
||||||
|
label: '/unban <user>',
|
||||||
|
info: 'Unban User'
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
label: '/timeout <user> <i>[duration=600] [reason]</i>',
|
||||||
|
info: 'Temporarily Ban User'
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: {info: 'Clear Chat for All Users'},
|
||||||
|
slow: {
|
||||||
|
label: '/slow <i>[duration=120]</i>',
|
||||||
|
info: 'Enable Slow Mode'
|
||||||
|
},
|
||||||
|
slowoff: {info: 'Disable Slow Mode'},
|
||||||
|
|
||||||
|
r9kbeta: {info: 'Enable R9k Mode'},
|
||||||
|
r9kbetaoff: {info: 'Disable R9k Mode'},
|
||||||
|
|
||||||
|
subscribers: {info: 'Enable Subscribers-Only Mode'},
|
||||||
|
subscribersoff: {info: 'Disable Subscribers-Only Mode'},
|
||||||
|
|
||||||
|
emotesonly: {info: 'Enable Emotes-Only Mode'},
|
||||||
|
emotesonlyoff: {info: 'Disable Emotes-Only Mode'},
|
||||||
|
},
|
||||||
|
|
||||||
|
BROADCASTER_COMMANDS = {
|
||||||
|
mod: {
|
||||||
|
label: '/mod <user>',
|
||||||
|
info: 'Make User a Moderator'
|
||||||
|
},
|
||||||
|
unmod: {
|
||||||
|
label: '/unmod <user>',
|
||||||
|
info: 'Remove User\'s Moderator Status'
|
||||||
|
},
|
||||||
|
|
||||||
|
host: {
|
||||||
|
label: '/host <channel>',
|
||||||
|
info: 'Enter Host Mode with Channel'
|
||||||
|
},
|
||||||
|
|
||||||
|
unhost: {info: 'Exit Host Mode'},
|
||||||
|
|
||||||
|
commercial: {
|
||||||
|
label: '/commercial <i>[length]</i>',
|
||||||
|
info: 'Trigger Commercial(s) for Length'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DEFAULT_COMMANDS = {
|
||||||
|
color: {
|
||||||
|
label: '/color <color>',
|
||||||
|
info: 'Set Username Color'
|
||||||
|
},
|
||||||
|
|
||||||
|
help: {
|
||||||
|
label: '/help <i>[command]</i>',
|
||||||
|
info: 'List Available Chat Commands'
|
||||||
|
},
|
||||||
|
|
||||||
|
me: {
|
||||||
|
label: '/me <message>',
|
||||||
|
info: 'Send a Colored Chat "Action"'
|
||||||
|
},
|
||||||
|
|
||||||
|
w: {
|
||||||
|
label: '/w <user> <message>',
|
||||||
|
info: 'Whisper to User'
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnect: {info: 'Disconnect from Chat'},
|
||||||
|
mods: {info: 'List Chat Moderators'},
|
||||||
|
},
|
||||||
|
|
||||||
CHARCODES = {
|
CHARCODES = {
|
||||||
AT_SIGN: 64,
|
AT_SIGN: 64,
|
||||||
COLON: 58
|
COLON: 58,
|
||||||
|
PERIOD: 46,
|
||||||
|
SLASH: 47
|
||||||
},
|
},
|
||||||
|
|
||||||
KEYCODES = {
|
KEYCODES = {
|
||||||
|
@ -117,6 +198,23 @@ FFZ.settings_info.input_complete_emotes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.settings_info.input_complete_commands = {
|
||||||
|
type: "boolean",
|
||||||
|
value: true,
|
||||||
|
|
||||||
|
category: "Chat Input",
|
||||||
|
no_bttv: true,
|
||||||
|
|
||||||
|
name: "Tab-Complete Commands",
|
||||||
|
help: "Use tab completion to complete commands in chat.",
|
||||||
|
|
||||||
|
on_update: function(val) {
|
||||||
|
if ( this._inputv )
|
||||||
|
Ember.propertyDidChange(this._inputv, 'ffz_commands');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.settings_info.input_complete_aliases = {
|
FFZ.settings_info.input_complete_aliases = {
|
||||||
type: "select",
|
type: "select",
|
||||||
options: {
|
options: {
|
||||||
|
@ -548,10 +646,94 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
var area = t.get('chatTextArea');
|
var area = t.get('chatTextArea');
|
||||||
move_selection(area, prefix.length);
|
move_selection(area, prefix.length);
|
||||||
area.focus();
|
area.focus();
|
||||||
|
|
||||||
|
var text = t.get('textareaValue'),
|
||||||
|
ind = text.indexOf(' '),
|
||||||
|
start = ind !== -1 && text.substr(0, ind);
|
||||||
|
|
||||||
|
if ( (prefix.length-1) === ind && f.settings.input_complete_commands && (start.charAt(0) === '/' || start.charAt(0) === '.') ) {
|
||||||
|
var commands = t.get('ffz_commands'),
|
||||||
|
cmd = commands[start.substr(1)];
|
||||||
|
|
||||||
|
if ( cmd && cmd.label && cmd.label.split(' ',2)[1] === '<user>' ) {
|
||||||
|
t.ffzFetchNameSuggestions();
|
||||||
|
t.set("ffz_suggestions_visible", true);
|
||||||
|
t.ffzSetPartialWord();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
ffz_commands: function() {
|
||||||
|
var commands = _.extend({}, DEFAULT_COMMANDS),
|
||||||
|
in_conversation = ConvoInput && this.parentView instanceof ConvoInput,
|
||||||
|
room = this.get('parentView.context.model'),
|
||||||
|
is_moderator = room && room.get('isModeratorOrHigher'),
|
||||||
|
user = f.get_user(),
|
||||||
|
is_broadcaster = room && user && user.login === room.get('name');
|
||||||
|
|
||||||
|
if ( in_conversation )
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if ( is_moderator )
|
||||||
|
commands = _.extend(commands, MOD_COMMANDS);
|
||||||
|
|
||||||
|
if ( is_broadcaster)
|
||||||
|
commands = _.extend(commands, BROADCASTER_COMMANDS);
|
||||||
|
|
||||||
|
// FFZ Commands
|
||||||
|
|
||||||
|
for(var cmd in FFZ.chat_commands) {
|
||||||
|
var data = FFZ.chat_commands[cmd];
|
||||||
|
if ( commands[cmd] )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var enabled = data.hasOwnProperty('enabled') ? data.enabled : true;
|
||||||
|
if ( typeof enabled === "function" )
|
||||||
|
try {
|
||||||
|
enabled = data.enabled.call(f, room, [])
|
||||||
|
} catch(err) {
|
||||||
|
f.error('command "' + cmd + '" enabled', err);
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! enabled )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
commands[cmd] = {
|
||||||
|
label: data.label,
|
||||||
|
info: data.info,
|
||||||
|
alias: false,
|
||||||
|
short: data.short
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Aliases
|
||||||
|
for(var cmd in f._command_aliases) {
|
||||||
|
var data = f._command_aliases[cmd],
|
||||||
|
replacement = data[0],
|
||||||
|
label = data[1];
|
||||||
|
|
||||||
|
if ( ! label ) {
|
||||||
|
var vars = utils.extract_cmd_variables(replacement, true);
|
||||||
|
label = vars.join(' ');
|
||||||
|
} else
|
||||||
|
label = utils.sanitize(label);
|
||||||
|
|
||||||
|
commands[cmd] = {
|
||||||
|
label: '/' + cmd + (label ? ' ' + label : ''),
|
||||||
|
info: replacement,
|
||||||
|
alias: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return commands;
|
||||||
|
|
||||||
|
}.property('parentView.context.model.isModeratorOrHigher', 'parentView.context.model.name'),
|
||||||
|
|
||||||
|
|
||||||
ffz_emoticons: function() {
|
ffz_emoticons: function() {
|
||||||
var emotes = {},
|
var emotes = {},
|
||||||
|
|
||||||
|
@ -653,8 +835,26 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
ffz_suggestions: function() {
|
ffz_suggestions: function() {
|
||||||
var output = [],
|
var output = [],
|
||||||
emotes = this.get('ffz_emoticons'),
|
emotes = this.get('ffz_emoticons'),
|
||||||
|
commands = this.get('ffz_commands'),
|
||||||
suggestions = this.get('ffz_name_suggestions'); //.mapBy('id').uniq();
|
suggestions = this.get('ffz_name_suggestions'); //.mapBy('id').uniq();
|
||||||
|
|
||||||
|
if ( f.settings.input_complete_commands ) {
|
||||||
|
// Include Commands
|
||||||
|
for(var command_name in commands) {
|
||||||
|
var cmd = '/' + command_name,
|
||||||
|
data = commands[command_name];
|
||||||
|
|
||||||
|
output.push({
|
||||||
|
type: "command",
|
||||||
|
match: cmd,
|
||||||
|
alternate_match: command_name.toLowerCase(),
|
||||||
|
content: data.content || cmd,
|
||||||
|
label: data.label || cmd,
|
||||||
|
info: data.alias ? 'Alias: ' + data.info : (data.short ? 'Short ' : '') + 'Command' + (data.info ? ': ' + data.info : '')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( f.settings.input_complete_emotes ) {
|
if ( f.settings.input_complete_emotes ) {
|
||||||
// Include Emoticons
|
// Include Emoticons
|
||||||
for(var emote_name in emotes) {
|
for(var emote_name in emotes) {
|
||||||
|
@ -794,12 +994,14 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
}.property('ffz_emoticons', 'ffz_name_suggestions'),
|
}.property('ffz_emoticons', 'ffz_name_suggestions'),
|
||||||
|
|
||||||
|
|
||||||
ffz_filtered_suggestions: Ember.computed("ffz_suggestions", "ffz_partial_word", function() {
|
ffz_filtered_suggestions: Ember.computed("ffz_suggestions", "ffz_partial_word", "ffz_partial_word_start", function() {
|
||||||
var suggestions = this.get('ffz_suggestions'),
|
var suggestions = this.get('ffz_suggestions'),
|
||||||
partial = this.get('ffz_partial_word'),
|
partial = this.get('ffz_partial_word'),
|
||||||
|
word_start = this.get('ffz_partial_word_start'),
|
||||||
part2 = partial.substr(1),
|
part2 = partial.substr(1),
|
||||||
char = partial.charAt(0),
|
char = partial.charAt(0),
|
||||||
is_at = char === '@';
|
is_at = char === '@',
|
||||||
|
is_command = char === '.' || char === '/';
|
||||||
|
|
||||||
return suggestions.filter(function(item) {
|
return suggestions.filter(function(item) {
|
||||||
var name = item.match || item.content || item.label,
|
var name = item.match || item.content || item.label,
|
||||||
|
@ -808,6 +1010,16 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
if ( ! name )
|
if ( ! name )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ( type === 'command' ) {
|
||||||
|
if ( word_start > 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( is_command )
|
||||||
|
return item.alternate_match.indexOf(part2.toLowerCase()) === 0;
|
||||||
|
|
||||||
|
return name.toLowerCase().indexOf(partial.toLowerCase()) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( type === 'user' ) {
|
if ( type === 'user' ) {
|
||||||
// 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.
|
||||||
|
@ -946,6 +1158,19 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CHARCODES.PERIOD:
|
||||||
|
case CHARCODES.SLASH:
|
||||||
|
// If we get a command, show the menu, but only if we're at the start of a line.
|
||||||
|
if ( ! this.get('ffz_suggestions_visible') && f.settings.input_complete_commands && !(ConvoInput && this.parentView instanceof ConvoInput) ) {
|
||||||
|
var ind = selection_start(this.get('chatTextArea')) - 1;
|
||||||
|
Ember.run.next(function() {
|
||||||
|
if ( ind === -1 )
|
||||||
|
t.ffzShowSuggestions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case CHARCODES.COLON:
|
case CHARCODES.COLON:
|
||||||
if ( f.settings.input_emoji ) {
|
if ( f.settings.input_emoji ) {
|
||||||
var textarea = this.get('chatTextArea'),
|
var textarea = this.get('chatTextArea'),
|
||||||
|
@ -1139,10 +1364,15 @@ FFZ.prototype.modify_chat_input = function(component) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ( start === '/w' || start === '/ignore' || start === '/unignore' || start === '/mod' || start === '/unmod' || start === '/ban' || start === '/unban' || start === '/timeout' || start === '/purge' ) {
|
} else if ( f.settings.input_complete_commands && (start.charAt(0) === '/' || start.charAt(0) === '.') ) {
|
||||||
t.ffzFetchNameSuggestions();
|
var commands = t.get('ffz_commands'),
|
||||||
t.set("ffz_suggestions_visible", true);
|
cmd = commands[start.substr(1)];
|
||||||
t.ffzSetPartialWord();
|
|
||||||
|
if ( cmd && cmd.label && cmd.label.split(' ',2)[1] === '<user>' ) {
|
||||||
|
t.ffzFetchNameSuggestions();
|
||||||
|
t.set("ffz_suggestions_visible", true);
|
||||||
|
t.ffzSetPartialWord();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1401,6 +1401,8 @@ FFZ.chat_commands.join = function(room, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.join.no_bttv = true;
|
FFZ.chat_commands.join.no_bttv = true;
|
||||||
|
FFZ.chat_commands.join.label = '/join <channel>';
|
||||||
|
FFZ.chat_commands.join.info = 'Add Channel to Pinned Rooms';
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.part = function(room, args) {
|
FFZ.chat_commands.part = function(room, args) {
|
||||||
|
@ -1422,4 +1424,6 @@ FFZ.chat_commands.part = function(room, args) {
|
||||||
return "You are not in " + room_id + ".";
|
return "You are not in " + room_id + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.part.no_bttv = true;
|
FFZ.chat_commands.part.no_bttv = true;
|
||||||
|
FFZ.chat_commands.part.label = '/part <channel>';
|
||||||
|
FFZ.chat_commands.part.info = 'Remove Channel from Pinned Rooms';
|
|
@ -222,7 +222,7 @@ FFZ.prototype.setup_layout = function() {
|
||||||
height = size[1],
|
height = size[1],
|
||||||
host_height = size[2];
|
host_height = size[2];
|
||||||
|
|
||||||
return "<style>body[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) #player,.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .cn-hosted .dynamic-target-player,.cn-hosted .dynamic-target-player object,body[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) .cn-hosted #player, .cn-hosted .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
|
return "<style>.ffz-small-player:not(.ffz-bttv)[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) #player,.dynamic-player, .dynamic-player object, .dynamic-player video{width:" + width + "px !important;height:" + height + "px !important} .cn-hosted .dynamic-target-player,.cn-hosted .dynamic-target-player object,.ffz-small-player:not(.ffz-bttv)[data-current-path^=\"user.channel.\"] .app-main:not(.theatre) .cn-hosted #player, .cn-hosted .dynamic-target-player video{width:" + width + "px !important;height:" + host_height + "px !important}</style><style>.dynamic-player .player object, .dynamic-player .player video{width:100% !important; height:100% !important}</style>";
|
||||||
}.property("playerSize"),
|
}.property("playerSize"),
|
||||||
|
|
||||||
ffzPortraitWarning: function() {
|
ffzPortraitWarning: function() {
|
||||||
|
|
|
@ -712,6 +712,8 @@ FFZ.prototype._modify_chat_line = function(component, is_vod) {
|
||||||
return [{type: 'text', text: 'hi'}];
|
return [{type: 'text', text: 'hi'}];
|
||||||
}.property('msgObject.message'),*/
|
}.property('msgObject.message'),*/
|
||||||
|
|
||||||
|
ffz_modified: true,
|
||||||
|
|
||||||
ffzTokenizedMessage: function() {
|
ffzTokenizedMessage: function() {
|
||||||
try {
|
try {
|
||||||
return f.tokenize_chat_line(this.get('msgObject'));
|
return f.tokenize_chat_line(this.get('msgObject'));
|
||||||
|
|
|
@ -1567,7 +1567,7 @@ 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 [ban reason]";
|
return "Usage: /purge <user> [ban reason]";
|
||||||
|
|
||||||
var name = args.shift(),
|
var name = args.shift(),
|
||||||
reason = args.length ? args.join(" ") : "";
|
reason = args.length ? args.join(" ") : "";
|
||||||
|
@ -1575,25 +1575,34 @@ FFZ.chat_commands.purge = function(room, args) {
|
||||||
room.room.send("/timeout " + name + " 1 " + reason, true);
|
room.room.send("/timeout " + name + " 1 " + reason, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.purge.label = '/purge <user> <i>[reason]</i>';
|
||||||
|
FFZ.chat_commands.purge.info = 'Ban User for 1 Second';
|
||||||
|
|
||||||
FFZ.chat_commands.p = function(room, args) {
|
FFZ.chat_commands.p = function(room, args) {
|
||||||
return FFZ.chat_commands.purge.call(this, room, args);
|
return FFZ.chat_commands.purge.call(this, room, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.p.enabled = function() { return this.settings.short_commands; }
|
FFZ.chat_commands.p.enabled = function() { return this.settings.short_commands; }
|
||||||
|
FFZ.chat_commands.p.short = true;
|
||||||
|
FFZ.chat_commands.p.label = '/p <user> <i>[reason]</i>';
|
||||||
|
FFZ.chat_commands.p.info = 'Ban User for 1 Second';
|
||||||
|
|
||||||
|
|
||||||
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] [ban reason]";
|
return "Usage: /t <user> [duration=600] [reason]";
|
||||||
room.room.send("/timeout " + args.join(" "), true);
|
room.room.send("/timeout " + args.join(" "), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.t.enabled = function() { return this.settings.short_commands; }
|
FFZ.chat_commands.t.enabled = function() { return this.settings.short_commands; }
|
||||||
|
FFZ.chat_commands.t.short = true;
|
||||||
|
FFZ.chat_commands.t.label = '/t <user> <i>[duration=600] [reason]</i>';
|
||||||
|
FFZ.chat_commands.t.info = 'Temporarily Ban User';
|
||||||
|
|
||||||
|
|
||||||
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 [ban reason]";
|
return "Usage: /b <user> [reason]";
|
||||||
|
|
||||||
var name = args.shift(),
|
var name = args.shift(),
|
||||||
reason = args.length ? args.join(" ") : "";
|
reason = args.length ? args.join(" ") : "";
|
||||||
|
@ -1602,11 +1611,14 @@ FFZ.chat_commands.b = function(room, args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.b.enabled = function() { return this.settings.short_commands; }
|
FFZ.chat_commands.b.enabled = function() { return this.settings.short_commands; }
|
||||||
|
FFZ.chat_commands.b.short = true;
|
||||||
|
FFZ.chat_commands.b.label = '/b <user> <i>[reason]</i>';
|
||||||
|
FFZ.chat_commands.b.info = 'Permanently Ban User';
|
||||||
|
|
||||||
|
|
||||||
FFZ.chat_commands.u = function(room, args) {
|
FFZ.chat_commands.u = function(room, args) {
|
||||||
if ( ! args || ! args.length )
|
if ( ! args || ! args.length )
|
||||||
return "Unban Usage: /u username [more usernames separated by spaces]";
|
return "Usage: /u <user> [more usernames separated by spaces]";
|
||||||
|
|
||||||
if ( args.length > 10 )
|
if ( args.length > 10 )
|
||||||
return "Please only unban up to 10 users at once.";
|
return "Please only unban up to 10 users at once.";
|
||||||
|
@ -1618,4 +1630,7 @@ FFZ.chat_commands.u = function(room, args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FFZ.chat_commands.u.enabled = function() { return this.settings.short_commands; }
|
FFZ.chat_commands.u.enabled = function() { return this.settings.short_commands; }
|
||||||
|
FFZ.chat_commands.u.short = true;
|
||||||
|
FFZ.chat_commands.u.label = '/u <user> <i>[<user> ...]';
|
||||||
|
FFZ.chat_commands.u.info = 'Unban User(s)';
|
|
@ -727,7 +727,7 @@ FFZ.prototype.run_command = function(text, room_id) {
|
||||||
try {
|
try {
|
||||||
val = command.enabled.call(this, room, args);
|
val = command.enabled.call(this, room, args);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
this.error('command "' + cmd + '" enabled: ' + err);
|
this.error('command "' + cmd + '" enabled', err);
|
||||||
val = false;
|
val = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2147,7 +2147,7 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
was_handled = true;
|
was_handled = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var alias = f._command_aliases[cmd],
|
var alias = f._command_aliases[cmd][0],
|
||||||
args = text.substr(1 + cmd.length).trimLeft().split(/\s+/g),
|
args = text.substr(1 + cmd.length).trimLeft().split(/\s+/g),
|
||||||
output = utils.replace_cmd_variables(alias, null, this, null, args);
|
output = utils.replace_cmd_variables(alias, null, this, null, args);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ FFZ.prototype.setup_ember_wrapper = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FFZ.prototype.update_views = function(klass, modifier, if_not_exists, immediate) {
|
FFZ.prototype.update_views = function(klass, modifier, if_not_exists, immediate, no_modify_existing) {
|
||||||
var original_klass;
|
var original_klass;
|
||||||
if ( typeof klass === 'string' ) {
|
if ( typeof klass === 'string' ) {
|
||||||
original_klass = klass;
|
original_klass = klass;
|
||||||
|
@ -33,10 +33,10 @@ FFZ.prototype.update_views = function(klass, modifier, if_not_exists, immediate)
|
||||||
} else
|
} else
|
||||||
original_klass = klass.toString();
|
original_klass = klass.toString();
|
||||||
|
|
||||||
if ( this._ember_finalized || immediate )
|
if ( this._ember_finalized || immediate || ! this._views_to_update )
|
||||||
this._update_views([[original_klass, klass, modifier]]);
|
this._update_views([[original_klass, klass, modifier, no_modify_existing || false]]);
|
||||||
else
|
else
|
||||||
this._views_to_update.push([original_klass, klass, modifier]);
|
this._views_to_update.push([original_klass, klass, modifier, no_modify_existing || false]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -79,10 +79,12 @@ FFZ.prototype._update_views = function(klasses) {
|
||||||
updated_instances++;
|
updated_instances++;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ( ! view.ffz_modified )
|
if ( ! view.ffz_modified && ! klasses[i][3] )
|
||||||
klasses[i][2].call(this, view);
|
klasses[i][2].call(this, view);
|
||||||
|
|
||||||
(view.ffz_update || view.ffz_init).call(view);
|
var func = view.ffz_update || view.ffz_init;
|
||||||
|
if ( func )
|
||||||
|
func.call(view);
|
||||||
|
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
this.error("An error occured when updating an existing Ember instance of: " + klasses[i][0], err);
|
this.error("An error occured when updating an existing Ember instance of: " + klasses[i][0], err);
|
||||||
|
|
|
@ -34,7 +34,7 @@ FFZ.msg_commands = {};
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
var VER = FFZ.version_info = {
|
var VER = FFZ.version_info = {
|
||||||
major: 3, minor: 5, revision: 323,
|
major: 3, minor: 5, revision: 325,
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
|
||||||
}
|
}
|
||||||
|
@ -335,6 +335,7 @@ FFZ.prototype.init_normal = function(delay, no_socket) {
|
||||||
|
|
||||||
// Initialize all the modules.
|
// Initialize all the modules.
|
||||||
this.load_settings();
|
this.load_settings();
|
||||||
|
this.setup_ember_wrapper();
|
||||||
|
|
||||||
// Start this early, for quick loading.
|
// Start this early, for quick loading.
|
||||||
this.setup_dark();
|
this.setup_dark();
|
||||||
|
@ -357,6 +358,7 @@ FFZ.prototype.init_normal = function(delay, no_socket) {
|
||||||
this.setup_following_count(false);
|
this.setup_following_count(false);
|
||||||
this.setup_menu();
|
this.setup_menu();
|
||||||
|
|
||||||
|
this.finalize_ember_wrapper();
|
||||||
this.setup_message_event();
|
this.setup_message_event();
|
||||||
this.fix_tooltips();
|
this.fix_tooltips();
|
||||||
this.find_bttv(10);
|
this.find_bttv(10);
|
||||||
|
@ -384,6 +386,7 @@ FFZ.prototype.init_dashboard = function(delay) {
|
||||||
|
|
||||||
// Initialize all the modules.
|
// Initialize all the modules.
|
||||||
this.load_settings();
|
this.load_settings();
|
||||||
|
this.setup_ember_wrapper();
|
||||||
|
|
||||||
// Start this early, for quick loading.
|
// Start this early, for quick loading.
|
||||||
this.setup_dark();
|
this.setup_dark();
|
||||||
|
@ -406,6 +409,8 @@ FFZ.prototype.init_dashboard = function(delay) {
|
||||||
this.setup_dash_stats();
|
this.setup_dash_stats();
|
||||||
this.setup_dash_feed();
|
this.setup_dash_feed();
|
||||||
|
|
||||||
|
this.finalize_ember_wrapper();
|
||||||
|
|
||||||
this._update_subscribers();
|
this._update_subscribers();
|
||||||
|
|
||||||
// Set up the FFZ message passer.
|
// Set up the FFZ message passer.
|
||||||
|
|
13
src/utils.js
13
src/utils.js
|
@ -554,6 +554,19 @@ module.exports = FFZ.utils = {
|
||||||
|
|
||||||
CMD_VAR_REGEX: CMD_VAR_REGEX,
|
CMD_VAR_REGEX: CMD_VAR_REGEX,
|
||||||
|
|
||||||
|
extract_cmd_variables: function(command, args_only) {
|
||||||
|
var matches = [];
|
||||||
|
|
||||||
|
CMD_VAR_REGEX.lastIndex = 0;
|
||||||
|
command.replace(CMD_VAR_REGEX, function(match, variable) {
|
||||||
|
if ( args_only && ! /\d+(?:$\d*)?/.test(variable) )
|
||||||
|
return;
|
||||||
|
matches.push('{' + variable + '}');
|
||||||
|
});
|
||||||
|
|
||||||
|
return _.unique(matches);
|
||||||
|
},
|
||||||
|
|
||||||
replace_cmd_variables: function(command, user, room, message, args) {
|
replace_cmd_variables: function(command, user, room, message, args) {
|
||||||
user = user || {};
|
user = user || {};
|
||||||
room = room || {};
|
room = room || {};
|
||||||
|
|
|
@ -311,7 +311,7 @@ body.ffz-bttv-dark .ffz-ui-toggle.blue.live:hover svg.svg-emoticons path { fill:
|
||||||
width: auto;
|
width: auto;
|
||||||
|
|
||||||
z-index: 7;
|
z-index: 7;
|
||||||
padding: 10px;
|
padding: 10px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ffz-theater-stats .app-main.theatre .cn-metabar__more {
|
.ffz-theater-stats .app-main.theatre .cn-metabar__more {
|
||||||
|
@ -3534,6 +3534,13 @@ body.ffz-bttv #ffz-feed-tabs .tabs { margin-bottom: 0 }
|
||||||
padding-top: 80px;
|
padding-top: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ffz-channel-title-top .cn-metabar__more,
|
||||||
|
.app-main.theatre .cn-metabar__more {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ffz-hide-channel-banner .cn-cover { height: 0 !important }
|
.ffz-hide-channel-banner .cn-cover { height: 0 !important }
|
||||||
.ffz-minimal-channel-title.ffz-channel-title-top #channel { padding-top: 50px }
|
.ffz-minimal-channel-title.ffz-channel-title-top #channel { padding-top: 50px }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue