2015-05-17 19:02:57 -04:00
var FFZ = window . FrankerFaceZ ,
2015-02-10 01:34:23 -05:00
utils = require ( "../utils" ) ,
2015-07-13 21:52:44 -04:00
constants = require ( "../constants" ) ,
2015-01-20 20:25:26 -05:00
2015-02-24 00:33:29 -05:00
SEPARATORS = "[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]" ,
2015-07-29 01:03:10 -04:00
SPLITTER = new RegExp ( SEPARATORS + "*," + SEPARATORS + "*" ) ;
2015-02-08 02:01:09 -05:00
2015-05-17 19:02:57 -04:00
// ---------------------
// Settings
// ---------------------
2015-07-06 00:09:21 -04:00
FFZ . settings _info . room _status = {
type : "boolean" ,
value : true ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
2015-07-06 00:09:21 -04:00
no _bttv : true ,
name : "Room Status Indicators" ,
help : "Display the current room state (slow mode, sub mode, and r9k mode) next to the Chat button." ,
on _update : function ( ) {
if ( this . _roomv )
this . _roomv . ffzUpdateStatus ( ) ;
}
} ;
FFZ . settings _info . replace _bad _emotes = {
type : "boolean" ,
value : true ,
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
no _bttv : true ,
2015-08-02 02:41:03 -04:00
2015-07-06 00:09:21 -04:00
name : "Fix Low Quality Twitch Global Emoticons" ,
help : "Replace emoticons such as DansGame and RedCoat with cleaned up versions that don't have pixels around the edges or white backgrounds for nicer display on dark chat."
2015-08-04 01:43:08 -04:00
} ;
2015-07-06 00:09:21 -04:00
2015-07-04 17:06:36 -04:00
FFZ . settings _info . parse _emoji = {
2015-08-28 22:54:12 -04:00
type : "select" ,
options : {
0 : "No Images / Font Only" ,
1 : "Twitter Emoji Images" ,
2 : "Google Noto Images"
} ,
value : 1 ,
process _value : function ( val ) {
if ( val === false )
return 0 ;
if ( val === true )
return 1 ;
if ( typeof val === "string" )
return parseInt ( val || "0" ) ;
return val ;
} ,
2015-07-04 17:06:36 -04:00
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
2015-07-04 17:06:36 -04:00
2015-08-28 22:54:12 -04:00
name : "Emoji Display" ,
help : "Replace emoji in chat messages with nicer looking images from either Twitter or Google."
2015-07-04 17:06:36 -04:00
} ;
FFZ . settings _info . room _status = {
type : "boolean" ,
value : true ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
2015-07-04 17:06:36 -04:00
no _bttv : true ,
name : "Room Status Indicators" ,
help : "Display the current room state (slow mode, sub mode, and r9k mode) next to the Chat button." ,
on _update : function ( ) {
if ( this . _roomv )
this . _roomv . ffzUpdateStatus ( ) ;
}
} ;
FFZ . settings _info . scrollback _length = {
type : "button" ,
value : 150 ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
2015-07-04 17:06:36 -04:00
no _bttv : true ,
name : "Scrollback Length" ,
help : "Set the maximum number of lines to keep in chat." ,
method : function ( ) {
var new _val = prompt ( "Scrollback Length\n\nPlease enter a new maximum length for the chat scrollback. Default: 150\n\nNote: Making this too large will cause your browser to lag." , this . settings . scrollback _length ) ;
if ( new _val === null || new _val === undefined )
return ;
new _val = parseInt ( new _val ) ;
if ( new _val === NaN )
return ;
if ( new _val < 10 )
new _val = 10 ;
this . settings . set ( "scrollback_length" , new _val ) ;
// Update our everything.
var Chat = App . _ _container _ _ . lookup ( 'controller:chat' ) ,
current _id = Chat && Chat . get ( 'currentRoom.id' ) ;
for ( var room _id in this . rooms ) {
var room = this . rooms [ room _id ] ;
2015-11-14 23:52:49 -05:00
room . room && room . room . set ( 'messageBufferSize' , new _val + ( ( this . _roomv && ! this . _roomv . get ( 'stuckToBottom' ) && current _id === room _id ) ? 150 : 0 ) ) ;
2015-07-04 17:06:36 -04:00
}
}
} ;
2015-07-29 01:03:10 -04:00
FFZ . settings _info . hosted _sub _notices = {
type : "boolean" ,
value : true ,
category : "Chat Filtering" ,
no _bttv : true ,
name : "Show Hosted Channel Subscriber Notices" ,
help : "Display notices in chat when someone subscribes to the hosted channel."
} ;
2015-08-21 19:00:48 -04:00
FFZ . settings _info . filter _bad _shorteners = {
type : "boolean" ,
value : true ,
category : "Chat Filtering" ,
no _bttv : true ,
name : "Auto-Hide Potentially Dangerous Shortened Links" ,
help : "Replace potentially dangerous shortened links. Links are still accessible, but require an extra click to access."
} ;
2015-02-24 00:33:29 -05:00
FFZ . settings _info . banned _words = {
type : "button" ,
value : [ ] ,
2015-07-13 21:52:44 -04:00
category : "Chat Filtering" ,
2015-05-17 19:02:57 -04:00
no _bttv : true ,
2015-02-24 00:33:29 -05:00
name : "Banned Words" ,
help : "Set a list of words that will be locally removed from chat messages." ,
method : function ( ) {
var old _val = this . settings . banned _words . join ( ", " ) ,
new _val = prompt ( "Banned Words\n\nPlease enter a comma-separated list of words that you would like to be removed from chat messages." , old _val ) ;
if ( new _val === null || new _val === undefined )
return ;
new _val = new _val . trim ( ) . split ( SPLITTER ) ;
var vals = [ ] ;
for ( var i = 0 ; i < new _val . length ; i ++ )
new _val [ i ] && vals . push ( new _val [ i ] ) ;
if ( vals . length == 1 && vals [ 0 ] == "disable" )
vals = [ ] ;
this . settings . set ( "banned_words" , vals ) ;
}
} ;
2015-02-08 02:01:09 -05:00
FFZ . settings _info . keywords = {
type : "button" ,
value : [ ] ,
2015-07-13 21:52:44 -04:00
category : "Chat Filtering" ,
2015-05-17 19:02:57 -04:00
no _bttv : true ,
2015-02-08 02:01:09 -05:00
name : "Highlight Keywords" ,
help : "Set additional keywords that will be highlighted in chat." ,
method : function ( ) {
var old _val = this . settings . keywords . join ( ", " ) ,
new _val = prompt ( "Highlight Keywords\n\nPlease enter a comma-separated list of words that you would like to be highlighted in chat." , old _val ) ;
2015-02-10 01:34:23 -05:00
if ( new _val === null || new _val === undefined )
2015-02-08 02:01:09 -05:00
return ;
// Split them up.
2015-02-24 00:33:29 -05:00
new _val = new _val . trim ( ) . split ( SPLITTER ) ;
var vals = [ ] ;
for ( var i = 0 ; i < new _val . length ; i ++ )
new _val [ i ] && vals . push ( new _val [ i ] ) ;
2015-02-08 02:01:09 -05:00
2015-02-24 00:33:29 -05:00
if ( vals . length == 1 && vals [ 0 ] == "disable" )
vals = [ ] ;
2015-02-08 02:01:09 -05:00
2015-02-24 00:33:29 -05:00
this . settings . set ( "keywords" , vals ) ;
2015-02-08 02:01:09 -05:00
}
} ;
2015-07-31 17:44:20 -04:00
FFZ . settings _info . clickable _emoticons = {
type : "boolean" ,
value : false ,
category : "Chat Tooltips" ,
no _bttv : true ,
no _mobile : true ,
name : "Emoticon Information Pages" ,
help : "When enabled, holding shift and clicking on an emoticon will open it on the FrankerFaceZ website or Twitch Emotes."
} ;
2015-07-18 21:10:27 -04:00
FFZ . settings _info . link _info = {
2015-02-10 01:34:23 -05:00
type : "boolean" ,
2015-02-26 00:42:11 -05:00
value : true ,
2015-02-10 01:34:23 -05:00
2015-07-18 21:10:27 -04:00
category : "Chat Tooltips" ,
2015-05-17 19:02:57 -04:00
no _bttv : true ,
2015-02-10 01:34:23 -05:00
2015-07-18 21:10:27 -04:00
name : "Link Information <span>Beta</span>" ,
help : "Check links against known bad websites, unshorten URLs, and show YouTube info."
2015-02-10 01:34:23 -05:00
} ;
2015-07-18 21:10:27 -04:00
FFZ . settings _info . link _image _hover = {
2015-05-17 19:02:57 -04:00
type : "boolean" ,
2015-07-18 21:10:27 -04:00
value : false ,
2015-05-17 19:02:57 -04:00
2015-07-18 21:10:27 -04:00
category : "Chat Tooltips" ,
2015-05-17 19:02:57 -04:00
no _bttv : true ,
2015-07-18 21:10:27 -04:00
no _mobile : true ,
2015-05-17 19:02:57 -04:00
2015-07-18 21:10:27 -04:00
name : "Image Preview" ,
help : "Display image thumbnails for links to Imgur and YouTube."
} ;
2015-11-14 23:52:49 -05:00
FFZ . settings _info . emote _image _hover = {
type : "boolean" ,
value : false ,
category : "Chat Tooltips" ,
no _mobile : true ,
name : "Emote Preview" ,
help : "Display scaled up high-DPI emoticon images in tooltips to help see details on low-resolution monitors." ,
on _update : function ( val ) {
this . _reset _tooltips ( ) ;
}
} ;
2015-07-18 21:10:27 -04:00
FFZ . settings _info . image _hover _all _domains = {
type : "boolean" ,
value : false ,
2015-08-02 02:41:03 -04:00
2015-07-18 21:10:27 -04:00
category : "Chat Tooltips" ,
no _bttv : true ,
no _mobile : true ,
2015-08-02 02:41:03 -04:00
2015-07-18 21:10:27 -04:00
name : "Image Preview - All Domains" ,
help : "<i>Requires Image Preview.</i> Attempt to show an image preview for any URL ending in the appropriate extension. <b>Warning: This may be used to leak your IP address to malicious users.</b>"
2015-05-17 19:02:57 -04:00
} ;
2015-02-08 02:01:09 -05:00
FFZ . settings _info . chat _rows = {
type : "boolean" ,
value : false ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
2015-05-17 19:02:57 -04:00
no _bttv : true ,
2015-02-08 02:01:09 -05:00
name : "Chat Line Backgrounds" ,
help : "Display alternating background colors for lines in chat." ,
2015-11-11 02:06:02 -05:00
on _update : function ( val ) {
this . toggle _style ( 'chat-background' , ! this . has _bttv && val ) ;
this . toggle _style ( 'chat-setup' , ! this . has _bttv && ( val || this . settings . chat _separators ) ) ;
}
2015-07-13 21:52:44 -04:00
} ;
FFZ . settings _info . chat _separators = {
2015-07-18 21:10:27 -04:00
type : "select" ,
options : {
0 : "Disabled" ,
1 : "Basic Line (1px solid)" ,
2015-10-17 18:05:44 -04:00
2 : "3D Line (2px groove)" ,
3 : "3D Line (2px groove inset)" ,
4 : "Wide Line (2px solid)"
2015-07-18 21:10:27 -04:00
} ,
2015-10-17 18:05:44 -04:00
value : 0 ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
no _bttv : true ,
2015-08-02 02:41:03 -04:00
2015-07-18 21:10:27 -04:00
process _value : function ( val ) {
if ( val === false )
2015-10-17 18:05:44 -04:00
return 0 ;
2015-07-18 21:10:27 -04:00
else if ( val === true )
2015-10-17 18:05:44 -04:00
return 1 ;
else if ( typeof val === "string" )
return parseInt ( val ) || 0 ;
2015-07-18 21:10:27 -04:00
return val ;
} ,
2015-07-13 21:52:44 -04:00
name : "Chat Line Separators" ,
help : "Display thin lines between chat messages for further visual separation." ,
2015-07-18 21:10:27 -04:00
on _update : function ( val ) {
2015-11-11 02:06:02 -05:00
this . toggle _style ( 'chat-setup' , ! this . has _bttv && ( val || this . settings . chat _rows ) ) ;
this . toggle _style ( 'chat-separator' , ! this . has _bttv && val ) ;
this . toggle _style ( 'chat-separator-3d' , ! this . has _bttv && val === 2 ) ;
this . toggle _style ( 'chat-separator-3d-inset' , ! this . has _bttv && val === 3 ) ;
this . toggle _style ( 'chat-separator-wide' , ! this . has _bttv && val === 4 ) ;
2015-07-18 21:10:27 -04:00
}
2015-07-13 21:52:44 -04:00
} ;
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
FFZ . settings _info . chat _padding = {
type : "boolean" ,
value : false ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Reduced Chat Line Padding" ,
help : "Reduce the amount of padding around chat messages to fit more on-screen at once." ,
2015-11-11 02:06:02 -05:00
on _update : function ( val ) { this . toggle _style ( 'chat-padding' , ! this . has _bttv && val ) ; }
2015-07-13 21:52:44 -04:00
} ;
FFZ . settings _info . high _contrast _chat = {
2015-07-31 17:44:20 -04:00
type : "select" ,
options : {
'222' : "Disabled" ,
'212' : "Bold" ,
'221' : "Text" ,
'211' : "Text + Bold" ,
'122' : "Background" ,
'121' : "Background + Text" ,
'112' : "Background + Bold" ,
'111' : 'All'
} ,
2015-08-04 01:43:08 -04:00
value : '222' ,
2015-07-13 21:52:44 -04:00
category : "Chat Appearance" ,
no _bttv : true ,
name : "High Contrast" ,
help : "Display chat using white and black for maximum contrast. This is suitable for capturing and chroma keying chat to display on stream." ,
2015-07-31 17:44:20 -04:00
process _value : function ( val ) {
if ( val === false )
2015-08-04 01:43:08 -04:00
return '222' ;
2015-07-31 17:44:20 -04:00
else if ( val === true )
return '111' ;
return val ;
} ,
on _update : function ( val ) {
2015-11-11 02:06:02 -05:00
this . toggle _style ( 'chat-hc-text' , ! this . has _bttv && val [ 2 ] === '1' ) ;
this . toggle _style ( 'chat-hc-bold' , ! this . has _bttv && val [ 1 ] === '1' ) ;
this . toggle _style ( 'chat-hc-background' , ! this . has _bttv && val [ 0 ] === '1' ) ;
2015-07-31 17:44:20 -04:00
}
2015-07-13 21:52:44 -04:00
} ;
2015-08-28 22:54:12 -04:00
FFZ . settings _info . chat _font _family = {
type : "button" ,
value : null ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Font Family" ,
help : "Change the font used for rendering chat messages." ,
method : function ( ) {
var old _val = this . settings . chat _font _family || "" ,
new _val = prompt ( "Chat Font Family\n\nPlease enter a font family to use rendering chat. Leave this blank to use the default." , old _val ) ;
if ( new _val === null || new _val === undefined )
return ;
// Should we wrap this with quotes?
if ( ! new _val )
new _val = null ;
this . settings . set ( "chat_font_family" , new _val ) ;
} ,
on _update : function ( val ) {
if ( this . has _bttv || ! this . _chat _style )
return ;
var css ;
if ( ! val )
css = "" ;
else {
// Let's escape this to avoid goofing anything up if there's bad user input.
if ( val . indexOf ( ' ' ) !== - 1 && val . indexOf ( ',' ) === - 1 && val . indexOf ( '"' ) === - 1 && val . indexOf ( "'" ) === - 1 )
val = '"' + val + '"' ;
var span = document . createElement ( 'span' ) ;
span . style . fontFamily = val ;
2015-11-14 23:52:49 -05:00
css = ".timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history,.ember-chat .chat-messages {" + span . style . cssText + "}" ;
2015-08-28 22:54:12 -04:00
}
utils . update _css ( this . _chat _style , "chat_font_family" , css ) ;
}
} ;
2015-07-13 21:52:44 -04:00
FFZ . settings _info . chat _font _size = {
type : "button" ,
value : 12 ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Font Size" ,
help : "Make the chat font bigger or smaller." ,
method : function ( ) {
var old _val = this . settings . chat _font _size ,
new _val = prompt ( "Chat Font Size\n\nPlease enter a new size for the chat font. The default is 12." , old _val ) ;
if ( new _val === null || new _val === undefined )
2015-02-10 01:34:23 -05:00
return ;
2015-07-13 21:52:44 -04:00
var parsed = parseInt ( new _val ) ;
2015-07-31 17:44:20 -04:00
if ( ! parsed || parsed === NaN || parsed < 1 )
2015-07-13 21:52:44 -04:00
parsed = 12 ;
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
this . settings . set ( "chat_font_size" , parsed ) ;
} ,
on _update : function ( val ) {
if ( this . has _bttv || ! this . _chat _style )
return ;
var css ;
2015-07-29 01:03:10 -04:00
if ( val === 12 || ! val )
2015-07-13 21:52:44 -04:00
css = "" ;
else {
var lh = Math . max ( 20 , Math . round ( ( 20 / 12 ) * val ) ) ,
pd = Math . floor ( ( lh - 20 ) / 2 ) ;
2015-11-14 23:52:49 -05:00
css = ".timestamp-line,.conversation-chat-line,.conversation-system-messages,.chat-history .chat-line,.ember-chat .chat-messages .chat-line { font-size: " + val + "px !important; line-height: " + lh + "px !important; }" ;
2015-07-13 21:52:44 -04:00
if ( pd )
css += ".ember-chat .chat-messages .chat-line .mod-icons, .ember-chat .chat-messages .chat-line .badges { padding-top: " + pd + "px; }" ;
}
utils . update _css ( this . _chat _style , "chat_font_size" , css ) ;
2015-07-18 21:10:27 -04:00
FFZ . settings _info . chat _ts _size . on _update . bind ( this ) ( this . settings . chat _ts _size ) ;
}
} ;
FFZ . settings _info . chat _ts _size = {
type : "button" ,
value : null ,
category : "Chat Appearance" ,
no _bttv : true ,
name : "Timestamp Font Size" ,
help : "Make the chat timestamp font bigger or smaller." ,
method : function ( ) {
var old _val = this . settings . chat _ts _size ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( ! old _val )
2015-07-18 21:10:27 -04:00
old _val = this . settings . chat _font _size ;
2015-08-02 02:41:03 -04:00
2015-07-18 21:10:27 -04:00
var new _val = prompt ( "Chat Timestamp Font Size\n\nPlease enter a new size for the chat timestamp font. The default is to match the regular chat font size." , old _val ) ;
if ( new _val === null || new _val === undefined )
return ;
var parsed = parseInt ( new _val ) ;
2015-07-31 17:44:20 -04:00
if ( ! parsed || parsed === NaN || parsed < 1 )
2015-07-18 21:10:27 -04:00
parsed = null ;
2015-08-02 02:41:03 -04:00
2015-07-18 21:10:27 -04:00
this . settings . set ( "chat_ts_size" , parsed ) ;
} ,
on _update : function ( val ) {
if ( this . has _bttv || ! this . _chat _style )
return ;
var css ;
if ( val === null )
css = "" ;
else {
var lh = Math . max ( 20 , Math . round ( ( 20 / 12 ) * val ) , Math . round ( ( 20 / 12 ) * this . settings . chat _font _size ) ) ;
2015-11-14 23:52:49 -05:00
css = ".chat-history .timestamp,.ember-chat .chat-messages .timestamp { font-size: " + val + "px !important; line-height: " + lh + "px !important; }" ;
2015-07-18 21:10:27 -04:00
}
utils . update _css ( this . _chat _style , "chat_ts_font_size" , css ) ;
2015-02-08 02:01:09 -05:00
}
} ;
2015-01-20 01:53:18 -05:00
// ---------------------
// Initialization
// ---------------------
FFZ . prototype . setup _line = function ( ) {
2015-07-13 21:52:44 -04:00
// Tipsy Handler
jQuery ( document . body ) . on ( "mouseleave" , ".tipsy" , function ( ) {
this . parentElement . removeChild ( this ) ;
} ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
// Aliases
try {
this . aliases = JSON . parse ( localStorage . ffz _aliases || '{}' ) ;
} catch ( err ) {
this . log ( "Error Loading Aliases: " + err ) ;
this . aliases = { } ;
}
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
// Chat Style
var s = this . _chat _style = document . createElement ( 'style' ) ;
s . id = "ffz-style-chat" ;
s . type = 'text/css' ;
2015-08-02 02:41:03 -04:00
document . head . appendChild ( s ) ;
2015-07-13 21:52:44 -04:00
// Initial calculation.
FFZ . settings _info . chat _font _size . on _update . bind ( this ) ( this . settings . chat _font _size ) ;
2015-08-28 22:54:12 -04:00
FFZ . settings _info . chat _font _family . on _update . bind ( this ) ( this . settings . chat _font _family ) ;
2015-07-18 21:10:27 -04:00
2015-08-02 02:41:03 -04:00
2015-02-10 01:34:23 -05:00
// Chat Enhancements
2015-11-11 02:06:02 -05:00
this . toggle _style ( 'chat-setup' , ! this . has _bttv && ( this . settings . chat _rows || this . settings . chat _separators ) ) ;
this . toggle _style ( 'chat-padding' , ! this . has _bttv && this . settings . chat _padding ) ;
this . toggle _style ( 'chat-background' , ! this . has _bttv && this . settings . chat _rows ) ;
2015-08-02 02:41:03 -04:00
2015-11-11 02:06:02 -05:00
this . toggle _style ( 'chat-separator' , ! this . has _bttv && this . settings . chat _separators ) ;
this . toggle _style ( 'chat-separator-3d' , ! this . has _bttv && this . settings . chat _separators === 2 ) ;
this . toggle _style ( 'chat-separator-3d-inset' , ! this . has _bttv && this . settings . chat _separators === 3 ) ;
this . toggle _style ( 'chat-separator-wide' , ! this . has _bttv && this . settings . chat _separators === 4 ) ;
2015-08-02 02:41:03 -04:00
2015-11-11 02:06:02 -05:00
this . toggle _style ( 'chat-hc-text' , ! this . has _bttv && this . settings . high _contrast _chat [ 2 ] === '1' ) ;
this . toggle _style ( 'chat-hc-bold' , ! this . has _bttv && this . settings . high _contrast _chat [ 1 ] === '1' ) ;
this . toggle _style ( 'chat-hc-background' , ! this . has _bttv && this . settings . high _contrast _chat [ 0 ] === '1' ) ;
2015-02-10 01:34:23 -05:00
2015-02-08 02:01:09 -05:00
this . _last _row = { } ;
2015-07-13 21:52:44 -04:00
this . log ( "Hooking the Ember Whisper Line component." ) ;
2015-06-10 18:46:04 -04:00
var Whisper = App . _ _container _ _ . resolve ( 'component:whisper-line' ) ;
if ( Whisper )
this . _modify _line ( Whisper ) ;
2015-02-24 00:33:29 -05:00
2015-07-13 21:52:44 -04:00
this . log ( "Hooking the Ember Message Line component." ) ;
2015-06-10 18:46:04 -04:00
var Line = App . _ _container _ _ . resolve ( 'component:message-line' ) ;
if ( Line )
this . _modify _line ( Line ) ;
2015-01-20 01:53:18 -05:00
2015-06-10 18:46:04 -04:00
// Store the capitalization of our own name.
var user = this . get _user ( ) ;
if ( user && user . name )
FFZ . capitalization [ user . login ] = [ user . name , Date . now ( ) ] ;
}
2015-07-29 01:03:10 -04:00
FFZ . prototype . save _aliases = function ( ) {
this . log ( "Saving " + Object . keys ( this . aliases ) . length + " aliases to local storage." ) ;
localStorage . ffz _aliases = JSON . stringify ( this . aliases ) ;
}
2015-11-07 22:56:15 -05:00
FFZ . prototype . _modify _line = function ( component ) {
var f = this ,
Layout = App . _ _container _ _ . lookup ( 'controller:layout' ) ,
Settings = App . _ _container _ _ . lookup ( 'controller:settings' ) ;
2015-07-29 01:03:10 -04:00
2015-11-07 22:56:15 -05:00
component . reopen ( {
tokenizedMessage : function ( ) {
try {
return f . tokenize _chat _line ( this . get ( 'msgObject' ) ) ;
} catch ( err ) {
f . error ( "chat-line tokenizedMessage: " + err ) ;
return this . _super ( ) ;
}
2015-01-20 01:53:18 -05:00
2015-06-05 03:59:28 -04:00
} . property ( "msgObject.message" , "isChannelLinksDisabled" , "currentUserNick" , "msgObject.from" , "msgObject.tags.emotes" ) ,
2015-01-20 01:53:18 -05:00
2015-06-10 18:46:04 -04:00
ffzUpdated : Ember . observer ( "msgObject.ffz_deleted" , "msgObject.ffz_old_messages" , function ( ) {
this . rerender ( ) ;
} ) ,
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
click : function ( e ) {
2015-07-29 01:03:10 -04:00
if ( e . target && e . target . classList . contains ( 'ffz-old-messages' ) )
return f . _show _deleted ( this . get ( 'msgObject.room' ) ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( e . target && e . target . classList . contains ( 'deleted-link' ) )
return f . _deleted _link _click . bind ( e . target ) ( e ) ;
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
if ( e . target && e . target . classList . contains ( 'mod-icon' ) ) {
jQuery ( e . target ) . trigger ( 'mouseout' ) ;
2015-08-02 02:41:03 -04:00
2015-10-17 18:05:44 -04:00
if ( e . target . classList . contains ( 'custom' ) ) {
var room _id = this . get ( 'msgObject.room' ) ,
room = room _id && f . rooms [ room _id ] && f . rooms [ room _id ] . room ,
cmd = e . target . getAttribute ( 'data-cmd' ) ;
if ( room ) {
2015-11-14 23:52:49 -05:00
var lines = cmd . split ( "\n" ) ;
for ( var i = 0 ; i < lines . length ; i ++ )
room . send ( lines [ i ] , true ) ;
2015-10-17 18:05:44 -04:00
if ( e . target . classList . contains ( 'is-timeout' ) )
room . clearMessages ( this . get ( 'msgObject.from' ) ) ;
}
return ;
2015-07-13 21:52:44 -04:00
}
}
2015-08-02 02:41:03 -04:00
2015-11-07 22:56:15 -05:00
if ( f . _click _emote ( e . target , e ) )
return ;
2015-08-02 02:41:03 -04:00
2015-07-13 21:52:44 -04:00
return this . _super ( e ) ;
} ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
ffzUserLevel : function ( ) {
if ( this . get ( 'isStaff' ) )
return 5 ;
else if ( this . get ( 'isAdmin' ) )
return 4 ;
else if ( this . get ( 'isBroadcaster' ) )
return 3 ;
2015-10-17 18:05:44 -04:00
else if ( this . get ( 'isGlobalMod' ) )
2015-07-29 01:03:10 -04:00
return 2 ;
else if ( this . get ( 'isModerator' ) )
return 1 ;
return 0 ;
} . property ( 'msgObject.labels.[]' ) ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
render : function ( e ) {
var deleted = this . get ( 'msgObject.deleted' ) ,
r = this ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
badges = { } ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
user = this . get ( 'msgObject.from' ) ,
room _id = this . get ( 'msgObject.room' ) ,
room = f . rooms && f . rooms [ room _id ] ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
recipient = this . get ( 'msgObject.to' ) ,
is _whisper = recipient && recipient . length ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
this _ul = this . get ( 'ffzUserLevel' ) ,
other _ul = room && room . room && room . room . get ( 'ffzUserLevel' ) || 0 ,
2015-05-17 19:02:57 -04:00
2015-07-31 17:44:20 -04:00
raw _color = this . get ( 'msgObject.color' ) ,
colors = raw _color && f . _handle _color ( raw _color ) ,
2015-08-02 02:41:03 -04:00
2015-07-31 17:44:20 -04:00
is _dark = ( Layout && Layout . get ( 'isTheatreMode' ) ) || ( Settings && Settings . get ( 'model.darkMode' ) ) ;
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
e . push ( '<div class="indicator"></div>' ) ;
e . push ( '<span class="timestamp float-left">' + this . get ( "timestamp" ) + '</span> ' ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( ! is _whisper && this _ul < other _ul ) {
e . push ( '<span class="mod-icons float-left">' ) ;
2015-10-17 18:05:44 -04:00
for ( var i = 0 , l = f . settings . mod _buttons . length ; i < l ; i ++ ) {
var pair = f . settings . mod _buttons [ i ] ,
prefix = pair [ 0 ] , btn = pair [ 1 ] ,
cmd , tip ;
if ( btn === false ) {
if ( deleted )
e . push ( '<a class="mod-icon float-left tooltip unban" title="Unban User" href="#">Unban</a>' ) ;
else
e . push ( '<a class="mod-icon float-left tooltip ban" title="Ban User" href="#">Ban</a>' ) ;
} else if ( btn === 600 )
e . push ( '<a class="mod-icon float-left tooltip timeout" title="Timeout User (10m)" href="#">Timeout</a>' ) ;
else {
if ( typeof btn === "string" ) {
2015-11-14 23:52:49 -05:00
cmd = btn . replace ( /{user}/g , user ) . replace ( / *<LINE> */ , "\n" ) ;
tip = 'Custom Command' + ( cmd . indexOf ( '\n' ) !== - 1 ? 's' : '' ) + '\n' + cmd ;
2015-10-17 18:05:44 -04:00
} else {
cmd = "/timeout " + user + " " + btn ;
tip = "Timeout User (" + utils . duration _string ( btn ) + ")" ;
}
e . push ( '<a class="mod-icon float-left tooltip' + ( cmd . substr ( 0 , 9 ) === '/timeout' ? ' is-timeout' : '' ) + ' custom" data-cmd="' + utils . quote _attr ( cmd ) + '" title="' + utils . quote _attr ( tip ) + '" href="#">' + prefix + '</a>' ) ;
}
}
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
e . push ( '</span>' ) ;
}
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
// Stock Badges
if ( ! is _whisper && this . get ( 'isBroadcaster' ) )
badges [ 0 ] = { klass : 'broadcaster' , title : 'Broadcaster' } ;
else if ( this . get ( 'isStaff' ) )
badges [ 0 ] = { klass : 'staff' , title : 'Staff' } ;
else if ( this . get ( 'isAdmin' ) )
badges [ 0 ] = { klass : 'admin' , title : 'Admin' } ;
else if ( this . get ( 'isGlobalMod' ) )
2015-11-07 22:56:15 -05:00
badges [ 0 ] = { klass : 'global-moderator' , title : 'Global Moderator' } ;
2015-07-29 01:03:10 -04:00
else if ( ! is _whisper && this . get ( 'isModerator' ) )
badges [ 0 ] = { klass : 'moderator' , title : 'Moderator' } ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( ! is _whisper && this . get ( 'isSubscriber' ) )
badges [ 10 ] = { klass : 'subscriber' , title : 'Subscriber' } ;
if ( this . get ( 'hasTurbo' ) )
badges [ 15 ] = { klass : 'turbo' , title : 'Turbo' } ;
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
// FFZ Badges
badges = f . render _badges ( this , badges ) ;
2015-07-04 17:06:36 -04:00
2015-07-29 01:03:10 -04:00
// Rendering!
e . push ( '<span class="badges float-left">' ) ;
2015-07-04 17:06:36 -04:00
2015-07-29 01:03:10 -04:00
for ( var key in badges ) {
var badge = badges [ key ] ,
css = badge . image ? 'background-image:url("' + badge . image + '");' : '' ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( badge . color )
css += 'background-color:' + badge . color + ';' ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( badge . extra _css )
css += badge . extra _css ;
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
e . push ( '<div class="badge float-left tooltip ' + badge . klass + '"' + ( css ? ' style="' + css + '"' : '' ) + ' title="' + badge . title + '"></div>' ) ;
}
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
e . push ( '</span>' ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
var alias = f . aliases [ user ] ,
2015-07-31 17:44:20 -04:00
name = this . get ( 'msgObject.tags.display-name' ) || ( user && user . capitalize ( ) ) || "unknown user" ,
style = colors && 'color:' + ( is _dark ? colors [ 1 ] : colors [ 0 ] ) ,
2015-08-02 02:41:03 -04:00
colored = style ? ' has-color' : '' ;
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
if ( alias )
2015-07-31 17:44:20 -04:00
e . push ( '<span class="from ffz-alias tooltip' + colored + '" style="' + style + ( colors ? '" data-color="' + raw _color : '' ) + '" title="' + utils . sanitize ( name ) + '">' + utils . sanitize ( alias ) + '</span>' ) ;
2015-07-29 01:03:10 -04:00
else
2015-07-31 17:44:20 -04:00
e . push ( '<span class="from' + colored + '" style="' + style + ( colors ? '" data-color="' + raw _color : '' ) + '">' + utils . sanitize ( name ) + '</span>' ) ;
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
if ( is _whisper ) {
var to _alias = f . aliases [ recipient ] ,
2015-07-31 17:44:20 -04:00
to _name = this . get ( 'msgObject.tags.recipient-display-name' ) || ( recipient && recipient . capitalize ( ) ) || "unknown user" ,
2015-08-02 02:41:03 -04:00
2015-07-31 17:44:20 -04:00
to _color = this . get ( 'msgObject.toColor' ) ,
to _colors = to _color && f . _handle _color ( to _color ) ,
2015-07-31 21:40:51 -04:00
to _style = to _color && 'color:' + ( is _dark ? to _colors [ 1 ] : to _colors [ 0 ] ) ,
2015-07-31 17:44:20 -04:00
to _colored = to _style ? ' has-color' : '' ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
this . _renderWhisperArrow ( e ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( to _alias )
2015-07-31 17:44:20 -04:00
e . push ( '<span class="to ffz-alias tooltip' + to _colored + '" style="' + to _style + ( to _color ? '" data-color="' + to _color : '' ) + '" title="' + utils . sanitize ( to _name ) + '">' + utils . sanitize ( to _alias ) + '</span>' ) ;
2015-07-29 01:03:10 -04:00
else
2015-07-31 17:44:20 -04:00
e . push ( '<span class="to' + to _colored + '" style="' + to _style + ( to _colors ? '" data-color="' + to _color : '' ) + '">' + utils . sanitize ( to _name ) + '</span>' ) ;
2015-07-29 01:03:10 -04:00
}
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
e . push ( '<span class="colon">:</span> ' ) ;
2015-08-02 02:41:03 -04:00
2015-07-31 17:44:20 -04:00
if ( this . get ( 'msgObject.style' ) !== 'action' ) {
style = '' ;
colored = '' ;
}
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
if ( deleted )
e . push ( '<span class="deleted"><a class="undelete" href="#"><message deleted></a></span>' ) ;
else {
2015-11-07 22:56:15 -05:00
e . push ( '<span class="message' + colored + '" style="' + style + ( colors ? '" data-color="' + raw _color : '' ) + '">' ) ;
2015-07-29 01:03:10 -04:00
e . push ( f . render _tokens ( this . get ( 'tokenizedMessage' ) , true ) ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
var old _messages = this . get ( 'msgObject.ffz_old_messages' ) ;
if ( old _messages && old _messages . length )
e . push ( '<div class="button primary float-right ffz-old-messages">Show ' + utils . number _commas ( old _messages . length ) + ' Old</div>' ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
e . push ( '</span>' ) ;
}
} ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
classNameBindings : [
'msgObject.ffz_has_mention:ffz-mentioned' ,
'ffzWasDeleted:ffz-deleted' ,
'ffzHasOldMessages:clearfix' ,
'ffzHasOldMessages:ffz-has-deleted'
] ,
2015-08-02 02:41:03 -04:00
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
ffzWasDeleted : function ( ) {
return f . settings . prevent _clear && this . get ( 'msgObject.ffz_deleted' ) ;
} . property ( 'msgObject.ffz_deleted' ) ,
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
ffzHasOldMessages : function ( ) {
var old _messages = this . get ( 'msgObject.ffz_old_messages' ) ;
return old _messages && old _messages . length ;
} . property ( 'msgObject.ffz_old_messages' ) ,
2015-02-24 00:33:29 -05:00
2015-07-29 01:03:10 -04:00
didInsertElement : function ( ) {
this . _super ( ) ;
2015-08-02 02:41:03 -04:00
2015-07-29 01:03:10 -04:00
var el = this . get ( 'element' ) ;
2015-07-31 17:44:20 -04:00
2015-07-29 01:03:10 -04:00
el . setAttribute ( 'data-room' , this . get ( 'msgObject.room' ) ) ;
el . setAttribute ( 'data-sender' , this . get ( 'msgObject.from' ) ) ;
el . setAttribute ( 'data-deleted' , this . get ( 'msgObject.deleted' ) || false ) ;
2015-01-20 01:53:18 -05:00
}
} ) ;
}
// ---------------------
// Capitalization
// ---------------------
FFZ . capitalization = { } ;
FFZ . _cap _fetching = 0 ;
FFZ . get _capitalization = function ( name , callback ) {
2015-02-08 02:59:20 -05:00
if ( ! name )
return name ;
2015-01-20 01:53:18 -05:00
name = name . toLowerCase ( ) ;
if ( name == "jtv" || name == "twitchnotify" )
return name ;
var old _data = FFZ . capitalization [ name ] ;
if ( old _data ) {
if ( Date . now ( ) - old _data [ 1 ] < 3600000 )
return old _data [ 0 ] ;
}
2015-02-24 00:33:29 -05:00
if ( FFZ . _cap _fetching < 25 ) {
2015-01-20 01:53:18 -05:00
FFZ . _cap _fetching ++ ;
2015-02-24 00:33:29 -05:00
FFZ . get ( ) . ws _send ( "get_display_name" , name , function ( success , data ) {
var cap _name = success ? data : name ;
FFZ . capitalization [ name ] = [ cap _name , Date . now ( ) ] ;
FFZ . _cap _fetching -- ;
typeof callback === "function" && callback ( cap _name ) ;
} ) ;
2015-01-20 01:53:18 -05:00
}
return old _data ? old _data [ 0 ] : name ;
}
2015-02-24 00:33:29 -05:00
// ---------------------
// Banned Words
// ---------------------
FFZ . prototype . _remove _banned = function ( tokens ) {
2015-08-09 02:31:55 -04:00
var banned _words = this . settings . banned _words ,
2015-10-17 18:05:44 -04:00
banned _links = this . settings . filter _bad _shorteners ? [ 'apo.af' , 'goo.gl' , 'j.mp' , 'bit.ly' ] : null ,
2015-08-09 02:31:55 -04:00
has _banned _words = banned _words && banned _words . length ;
if ( ! has _banned _words && ( ! banned _links || ! banned _links . length ) )
2015-02-24 00:33:29 -05:00
return tokens ;
if ( typeof tokens == "string" )
tokens = [ tokens ] ;
var regex = FFZ . _words _to _regex ( banned _words ) ,
2015-08-21 19:00:48 -04:00
link _regex = this . settings . filter _bad _shorteners && FFZ . _words _to _regex ( banned _links ) ,
2015-02-24 00:33:29 -05:00
new _tokens = [ ] ;
2015-08-21 19:00:48 -04:00
for ( var i = 0 , l = tokens . length ; i < l ; i ++ ) {
2015-02-24 00:33:29 -05:00
var token = tokens [ i ] ;
if ( ! _ . isString ( token ) ) {
2015-08-09 02:31:55 -04:00
if ( token . emoticonSrc && has _banned _words && regex . test ( token . altText ) )
2015-02-24 00:33:29 -05:00
new _tokens . push ( token . altText . replace ( regex , "$1***" ) ) ;
2015-08-09 02:31:55 -04:00
else if ( token . isLink && has _banned _words && regex . test ( token . href ) )
2015-02-24 00:33:29 -05:00
new _tokens . push ( {
2015-07-29 01:03:10 -04:00
isLink : true ,
href : token . href ,
isDeleted : true ,
isLong : false ,
censoredHref : token . href . replace ( regex , "$1***" )
} ) ;
2015-08-21 19:00:48 -04:00
else if ( token . isLink && this . settings . filter _bad _shorteners && link _regex . test ( token . href ) )
2015-08-09 02:31:55 -04:00
new _tokens . push ( {
isLink : true ,
href : token . href ,
isDeleted : true ,
isLong : false ,
2015-08-21 19:00:48 -04:00
isShortened : true
2015-08-09 02:31:55 -04:00
} ) ;
2015-02-24 00:33:29 -05:00
else
new _tokens . push ( token ) ;
2015-08-09 02:31:55 -04:00
} else if ( has _banned _words )
2015-02-24 00:33:29 -05:00
new _tokens . push ( token . replace ( regex , "$1***" ) ) ;
2015-08-09 13:08:04 -04:00
else
new _tokens . push ( token ) ;
2015-02-24 00:33:29 -05:00
}
return new _tokens ;
2015-01-20 20:25:26 -05:00
}
2015-01-20 01:53:18 -05:00
// ---------------------
// Emoticon Replacement
// ---------------------
2015-06-05 03:59:28 -04:00
FFZ . prototype . _emoticonize = function ( component , tokens ) {
2015-06-10 18:46:04 -04:00
var room _id = component . get ( "msgObject.room" ) ,
2015-06-05 03:59:28 -04:00
user _id = component . get ( "msgObject.from" ) ;
2015-01-20 01:53:18 -05:00
2015-06-05 03:59:28 -04:00
return this . tokenize _emotes ( user _id , room _id , tokens ) ;
2015-01-12 17:58:07 -05:00
}