mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-29 15:55:33 +00:00
Added basic support for highlighting arbitrary words in chat. Added capitalization to auto-completion entries.
This commit is contained in:
parent
343a9c927b
commit
3d68cd45ab
5 changed files with 186 additions and 14 deletions
98
script.js
98
script.js
|
@ -344,7 +344,11 @@ FFZ.prototype._modify_cview = function(view) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},{}],6:[function(require,module,exports){
|
},{}],6:[function(require,module,exports){
|
||||||
var FFZ = window.FrankerFaceZ;
|
var FFZ = window.FrankerFaceZ,
|
||||||
|
|
||||||
|
reg_escape = function(str) {
|
||||||
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
@ -360,7 +364,13 @@ FFZ.prototype.setup_line = function() {
|
||||||
Line.reopen({
|
Line.reopen({
|
||||||
tokenizedMessage: function() {
|
tokenizedMessage: function() {
|
||||||
// Add our own step to the tokenization procedure.
|
// Add our own step to the tokenization procedure.
|
||||||
return f._emoticonize(this, this._super());
|
var tokens = f._emoticonize(this, this._super()),
|
||||||
|
user = f.get_user();
|
||||||
|
|
||||||
|
if ( ! user || this.get("model.from") != user.login )
|
||||||
|
tokens = f._mentionize(this, tokens);
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
|
||||||
}.property("model.message", "isModeratorOrHigher", "controllers.emoticons.emoticons.[]")
|
}.property("model.message", "isModeratorOrHigher", "controllers.emoticons.emoticons.[]")
|
||||||
// TODO: Copy the new properties from the new Twitch!
|
// TODO: Copy the new properties from the new Twitch!
|
||||||
|
@ -382,7 +392,7 @@ FFZ.prototype.setup_line = function() {
|
||||||
|
|
||||||
f.render_badge(this);
|
f.render_badge(this);
|
||||||
|
|
||||||
if ( localStorage['ffzCapitalize'] != 'false' )
|
if ( localStorage.ffzCapitalize != 'false' )
|
||||||
f.capitalize(this, user);
|
f.capitalize(this, user);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -392,6 +402,12 @@ FFZ.prototype.setup_line = function() {
|
||||||
var user = this.get_user();
|
var user = this.get_user();
|
||||||
if ( user && user.name )
|
if ( user && user.name )
|
||||||
FFZ.capitalization[user.login] = [user.name, Date.now()];
|
FFZ.capitalization[user.login] = [user.name, Date.now()];
|
||||||
|
|
||||||
|
// Load the mention words.
|
||||||
|
if ( localStorage.ffzMentionize )
|
||||||
|
this.mention_words = JSON.parse(localStorage.ffzMentionize);
|
||||||
|
else
|
||||||
|
this.mention_words = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -420,7 +436,7 @@ FFZ.get_capitalization = function(name, callback) {
|
||||||
var cap_name = data.display_name || name;
|
var cap_name = data.display_name || name;
|
||||||
FFZ.capitalization[name] = [cap_name, Date.now()];
|
FFZ.capitalization[name] = [cap_name, Date.now()];
|
||||||
FFZ._cap_fetching--;
|
FFZ._cap_fetching--;
|
||||||
callback && callback(cap_name);
|
typeof callback === "function" && callback(cap_name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,6 +468,63 @@ FFZ.chat_commands.capitalization = function(room, args) {
|
||||||
FFZ.chat_commands.capitalization.help = "Usage: /ffz capitalization <on|off>\nEnable or disable Chat Name Capitalization. This setting does not work with BetterTTV.";
|
FFZ.chat_commands.capitalization.help = "Usage: /ffz capitalization <on|off>\nEnable or disable Chat Name Capitalization. This setting does not work with BetterTTV.";
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Extra Mentions
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
FFZ._regex_cache = {};
|
||||||
|
|
||||||
|
FFZ.get_regex = function(word) {
|
||||||
|
return FFZ._regex_cache[word] = FFZ._regex_cache[word] || RegExp("\\b" + reg_escape(word) + "\\b", "i");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype._mentionize = function(controller, tokens) {
|
||||||
|
if ( ! this.mention_words )
|
||||||
|
return tokens;
|
||||||
|
|
||||||
|
if ( typeof tokens == "string" )
|
||||||
|
tokens = [tokens];
|
||||||
|
|
||||||
|
_.each(this.mention_words, function(word) {
|
||||||
|
var eo = {mentionedUser: word, own: false};
|
||||||
|
|
||||||
|
tokens = _.compact(_.flatten(_.map(tokens, function(token) {
|
||||||
|
if ( _.isObject(token) )
|
||||||
|
return token;
|
||||||
|
|
||||||
|
var tbits = token.split(FFZ.get_regex(word)), bits = [];
|
||||||
|
tbits.forEach(function(val, ind) {
|
||||||
|
bits.push(val);
|
||||||
|
if ( ind !== tbits.length - 1 )
|
||||||
|
bits.push(eo);
|
||||||
|
});
|
||||||
|
return bits;
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.chat_commands.mentionize = function(room, args) {
|
||||||
|
if ( args && args.length ) {
|
||||||
|
this.mention_words = args.join(" ").trim().split(/\W*,\W*/);
|
||||||
|
if ( this.mention_words.length == 1 && this.mention_words[0] == "disable" )
|
||||||
|
this.mention_words = [];
|
||||||
|
|
||||||
|
localStorage.ffzMentionize = JSON.stringify(this.mention_words);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.mention_words.length )
|
||||||
|
return "The following words will be treated as mentions: " + this.mention_words.join(", ");
|
||||||
|
else
|
||||||
|
return "There are no words set that will be treated as mentions.";
|
||||||
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.mentionize.help = "Usage: /ffz mentionize <comma, separated, word, list|disable>\nSet a list of words that will also be treated as mentions and be displayed specially in chat.";
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Emoticon Replacement
|
// Emoticon Replacement
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
@ -725,6 +798,7 @@ FFZ.prototype._load_room_json = function(room_id, callback, data) {
|
||||||
FFZ.prototype._modify_room = function(room) {
|
FFZ.prototype._modify_room = function(room) {
|
||||||
var f = this;
|
var f = this;
|
||||||
room.reopen({
|
room.reopen({
|
||||||
|
// Track which rooms the user is currently in.
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super();
|
this._super();
|
||||||
f.add_room(this.id, this);
|
f.add_room(this.id, this);
|
||||||
|
@ -735,6 +809,18 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
f.remove_room(this.id);
|
f.remove_room(this.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSuggestions: function() {
|
||||||
|
// This returns auto-complete suggestions for use in chat. We want
|
||||||
|
// to apply our capitalizations here. Overriding the
|
||||||
|
// filteredSuggestions property of the chat-input component would
|
||||||
|
// be even better, but I was already hooking the room model.
|
||||||
|
var suggestions = this._super();
|
||||||
|
if ( localStorage.ffzCapitalize != 'false' )
|
||||||
|
suggestions = _.map(suggestions, FFZ.get_capitalization);
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
},
|
||||||
|
|
||||||
send: function(text) {
|
send: function(text) {
|
||||||
var cmd = text.split(' ', 1)[0].toLowerCase();
|
var cmd = text.split(' ', 1)[0].toLowerCase();
|
||||||
if ( cmd === "/ffz" ) {
|
if ( cmd === "/ffz" ) {
|
||||||
|
@ -1066,14 +1152,14 @@ FFZ.prototype._legacy_load_set = function(set_id, callback, tries) {
|
||||||
|
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
if ( data.status == 404 )
|
if ( data.status == 404 )
|
||||||
return callback && callback(false);
|
return typeof callback == "function" && callback(false);
|
||||||
|
|
||||||
tries = tries || 0;
|
tries = tries || 0;
|
||||||
tries++;
|
tries++;
|
||||||
if ( tries < 10 )
|
if ( tries < 10 )
|
||||||
return this._legacy_load_set(set_id, callback, tries);
|
return this._legacy_load_set(set_id, callback, tries);
|
||||||
|
|
||||||
return callback && callback(false);
|
return typeof callback == "function" && callback(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
script.min.js
vendored
4
script.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,8 @@
|
||||||
var FFZ = window.FrankerFaceZ;
|
var FFZ = window.FrankerFaceZ,
|
||||||
|
|
||||||
|
reg_escape = function(str) {
|
||||||
|
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
@ -14,7 +18,13 @@ FFZ.prototype.setup_line = function() {
|
||||||
Line.reopen({
|
Line.reopen({
|
||||||
tokenizedMessage: function() {
|
tokenizedMessage: function() {
|
||||||
// Add our own step to the tokenization procedure.
|
// Add our own step to the tokenization procedure.
|
||||||
return f._emoticonize(this, this._super());
|
var tokens = f._emoticonize(this, this._super()),
|
||||||
|
user = f.get_user();
|
||||||
|
|
||||||
|
if ( ! user || this.get("model.from") != user.login )
|
||||||
|
tokens = f._mentionize(this, tokens);
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
|
||||||
}.property("model.message", "isModeratorOrHigher", "controllers.emoticons.emoticons.[]")
|
}.property("model.message", "isModeratorOrHigher", "controllers.emoticons.emoticons.[]")
|
||||||
// TODO: Copy the new properties from the new Twitch!
|
// TODO: Copy the new properties from the new Twitch!
|
||||||
|
@ -36,7 +46,7 @@ FFZ.prototype.setup_line = function() {
|
||||||
|
|
||||||
f.render_badge(this);
|
f.render_badge(this);
|
||||||
|
|
||||||
if ( localStorage['ffzCapitalize'] != 'false' )
|
if ( localStorage.ffzCapitalize != 'false' )
|
||||||
f.capitalize(this, user);
|
f.capitalize(this, user);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +56,12 @@ FFZ.prototype.setup_line = function() {
|
||||||
var user = this.get_user();
|
var user = this.get_user();
|
||||||
if ( user && user.name )
|
if ( user && user.name )
|
||||||
FFZ.capitalization[user.login] = [user.name, Date.now()];
|
FFZ.capitalization[user.login] = [user.name, Date.now()];
|
||||||
|
|
||||||
|
// Load the mention words.
|
||||||
|
if ( localStorage.ffzMentionize )
|
||||||
|
this.mention_words = JSON.parse(localStorage.ffzMentionize);
|
||||||
|
else
|
||||||
|
this.mention_words = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,7 +90,7 @@ FFZ.get_capitalization = function(name, callback) {
|
||||||
var cap_name = data.display_name || name;
|
var cap_name = data.display_name || name;
|
||||||
FFZ.capitalization[name] = [cap_name, Date.now()];
|
FFZ.capitalization[name] = [cap_name, Date.now()];
|
||||||
FFZ._cap_fetching--;
|
FFZ._cap_fetching--;
|
||||||
callback && callback(cap_name);
|
typeof callback === "function" && callback(cap_name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +122,63 @@ FFZ.chat_commands.capitalization = function(room, args) {
|
||||||
FFZ.chat_commands.capitalization.help = "Usage: /ffz capitalization <on|off>\nEnable or disable Chat Name Capitalization. This setting does not work with BetterTTV.";
|
FFZ.chat_commands.capitalization.help = "Usage: /ffz capitalization <on|off>\nEnable or disable Chat Name Capitalization. This setting does not work with BetterTTV.";
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------
|
||||||
|
// Extra Mentions
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
FFZ._regex_cache = {};
|
||||||
|
|
||||||
|
FFZ.get_regex = function(word) {
|
||||||
|
return FFZ._regex_cache[word] = FFZ._regex_cache[word] || RegExp("\\b" + reg_escape(word) + "\\b", "i");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.prototype._mentionize = function(controller, tokens) {
|
||||||
|
if ( ! this.mention_words )
|
||||||
|
return tokens;
|
||||||
|
|
||||||
|
if ( typeof tokens == "string" )
|
||||||
|
tokens = [tokens];
|
||||||
|
|
||||||
|
_.each(this.mention_words, function(word) {
|
||||||
|
var eo = {mentionedUser: word, own: false};
|
||||||
|
|
||||||
|
tokens = _.compact(_.flatten(_.map(tokens, function(token) {
|
||||||
|
if ( _.isObject(token) )
|
||||||
|
return token;
|
||||||
|
|
||||||
|
var tbits = token.split(FFZ.get_regex(word)), bits = [];
|
||||||
|
tbits.forEach(function(val, ind) {
|
||||||
|
bits.push(val);
|
||||||
|
if ( ind !== tbits.length - 1 )
|
||||||
|
bits.push(eo);
|
||||||
|
});
|
||||||
|
return bits;
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FFZ.chat_commands.mentionize = function(room, args) {
|
||||||
|
if ( args && args.length ) {
|
||||||
|
this.mention_words = args.join(" ").trim().split(/\W*,\W*/);
|
||||||
|
if ( this.mention_words.length == 1 && this.mention_words[0] == "disable" )
|
||||||
|
this.mention_words = [];
|
||||||
|
|
||||||
|
localStorage.ffzMentionize = JSON.stringify(this.mention_words);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( this.mention_words.length )
|
||||||
|
return "The following words will be treated as mentions: " + this.mention_words.join(", ");
|
||||||
|
else
|
||||||
|
return "There are no words set that will be treated as mentions.";
|
||||||
|
}
|
||||||
|
|
||||||
|
FFZ.chat_commands.mentionize.help = "Usage: /ffz mentionize <comma, separated, word, list|disable>\nSet a list of words that will also be treated as mentions and be displayed specially in chat.";
|
||||||
|
|
||||||
|
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Emoticon Replacement
|
// Emoticon Replacement
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
|
@ -211,6 +211,7 @@ FFZ.prototype._load_room_json = function(room_id, callback, data) {
|
||||||
FFZ.prototype._modify_room = function(room) {
|
FFZ.prototype._modify_room = function(room) {
|
||||||
var f = this;
|
var f = this;
|
||||||
room.reopen({
|
room.reopen({
|
||||||
|
// Track which rooms the user is currently in.
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super();
|
this._super();
|
||||||
f.add_room(this.id, this);
|
f.add_room(this.id, this);
|
||||||
|
@ -221,6 +222,18 @@ FFZ.prototype._modify_room = function(room) {
|
||||||
f.remove_room(this.id);
|
f.remove_room(this.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSuggestions: function() {
|
||||||
|
// This returns auto-complete suggestions for use in chat. We want
|
||||||
|
// to apply our capitalizations here. Overriding the
|
||||||
|
// filteredSuggestions property of the chat-input component would
|
||||||
|
// be even better, but I was already hooking the room model.
|
||||||
|
var suggestions = this._super();
|
||||||
|
if ( localStorage.ffzCapitalize != 'false' )
|
||||||
|
suggestions = _.map(suggestions, FFZ.get_capitalization);
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
},
|
||||||
|
|
||||||
send: function(text) {
|
send: function(text) {
|
||||||
var cmd = text.split(' ', 1)[0].toLowerCase();
|
var cmd = text.split(' ', 1)[0].toLowerCase();
|
||||||
if ( cmd === "/ffz" ) {
|
if ( cmd === "/ffz" ) {
|
||||||
|
|
|
@ -159,14 +159,14 @@ FFZ.prototype._legacy_load_set = function(set_id, callback, tries) {
|
||||||
|
|
||||||
}).fail(function(data) {
|
}).fail(function(data) {
|
||||||
if ( data.status == 404 )
|
if ( data.status == 404 )
|
||||||
return callback && callback(false);
|
return typeof callback == "function" && callback(false);
|
||||||
|
|
||||||
tries = tries || 0;
|
tries = tries || 0;
|
||||||
tries++;
|
tries++;
|
||||||
if ( tries < 10 )
|
if ( tries < 10 )
|
||||||
return this._legacy_load_set(set_id, callback, tries);
|
return this._legacy_load_set(set_id, callback, tries);
|
||||||
|
|
||||||
return callback && callback(false);
|
return typeof callback == "function" && callback(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue