2017-04-04 07:53:27 +02:00
/* global $ */
/* global Materialize */
/* global Mustache */
/* global guild_id */
2017-04-05 08:25:07 +02:00
/* global bot_client_id */
2017-04-05 21:06:51 +02:00
/* global moment */
2017-05-26 04:58:04 +02:00
/* global localStorage */
2017-06-09 06:22:33 +02:00
/* global visitors_enabled */
2017-06-15 21:58:15 +02:00
/* global cheet */
2017-08-19 07:09:13 +02:00
/* global location */
/* global io */
2017-09-06 09:11:32 +02:00
/* global twemoji */
2017-09-15 08:25:03 +02:00
/* global jQuery */
2017-09-21 09:12:49 +02:00
/* global grecaptcha */
2017-09-23 19:38:14 +02:00
/* global hljs */
/* global linkify */
2017-11-04 03:58:26 +01:00
/* global unauth_captcha_enabled */
2017-11-13 02:26:00 +01:00
/* global soundManager */
2017-04-04 07:53:27 +02:00
2017-04-13 02:42:32 +02:00
( function ( ) {
2017-05-26 03:13:53 +02:00
const theme _options = [ "DiscordDark" , "BetterTitan" ] ; // All the avaliable theming names
2017-12-07 07:49:32 +01:00
const badges _options = [ "administrator" , "partner" , "supporter" , "star" ] ; // All badges avaliable
2017-05-26 01:17:22 +02:00
2017-05-26 05:16:23 +02:00
var user _def _css ; // Saves the user defined css
2017-07-20 04:26:35 +02:00
var has _already _been _initially _resized = false ; // keep track if the embed initially been resized
2017-10-29 03:00:21 +01:00
var has _handled _noscroll = false ; // Prevent scrolling to bottom of embed at load if false
2017-04-13 02:42:32 +02:00
var logintimer ; // timer to keep track of user inactivity after hitting login
var last _message _id ; // last message tracked
2017-08-09 03:26:11 +02:00
var selected _channel = null ; // user selected channel
2017-04-13 08:05:04 +02:00
var guild _channels = { } ; // all server channels used to highlight channels in messages
2017-08-22 09:53:41 +02:00
var emoji _store = [ ] ; // all server emojis
2017-05-24 06:42:01 +02:00
var current _username _discrim ; // Current username/discrim pair, eg EndenDraogn#4151
2017-08-27 09:55:08 +02:00
var current _user _discord _id ; // Current user discord snowflake id, eg mine is 140252024666062848
2017-06-09 06:22:33 +02:00
var visitor _mode = false ; // Keep track of if using the visitor mode or authenticate mode
2017-08-21 06:26:51 +02:00
var socket = null ; // Socket.io object
2017-08-22 08:57:30 +02:00
var authenticated _users _list = [ ] ; // List of all authenticated users
var unauthenticated _users _list = [ ] ; // List of all guest users
var discord _users _list = [ ] ; // List of all discord users that are probably online
2017-08-25 08:37:14 +02:00
var guild _channels _list = [ ] ; // guild channels, but as a list of them
2017-09-15 08:25:03 +02:00
var message _users _cache = { } ; // {"name#discrim": {"data": {}, "msgs": []} Cache of the users fetched from websockets to paint the messages
2017-09-01 09:28:44 +02:00
var shift _pressed = false ; // Track down if shift pressed on messagebox
2017-09-24 06:17:06 +02:00
var global _guest _icon = null ; // Guest icon
2017-11-13 02:26:00 +01:00
var notification _sound = null ; // Sound Manager 2 demonstrative.mp3 object https://notificationsounds.com/message-tones/demonstrative-516
var notification _sound _setting ; // nothing, mentions, newmsgs - to control what new sound it makes
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function element _in _view ( element , fullyInView ) {
var pageTop = $ ( window ) . scrollTop ( ) ;
var pageBottom = pageTop + $ ( window ) . height ( ) ;
var elementTop = $ ( element ) . offset ( ) . top ;
var elementBottom = elementTop + $ ( element ) . height ( ) ;
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
if ( fullyInView === true ) {
return ( ( pageTop < elementTop ) && ( pageBottom > elementBottom ) ) ;
} else {
return ( ( elementTop <= pageBottom ) && ( elementBottom >= pageTop ) ) ;
}
2017-04-05 05:46:48 +02:00
}
2017-06-10 05:43:23 +02:00
String . prototype . replaceAll = function ( target , replacement ) {
return this . split ( target ) . join ( replacement ) ;
} ;
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function query _guild ( ) {
2017-06-09 06:22:33 +02:00
var url = "/api/query_guild" ;
if ( visitor _mode ) {
url = url += "_visitor" ;
}
2017-04-13 02:42:32 +02:00
var funct = $ . ajax ( {
dataType : "json" ,
2017-06-09 06:22:33 +02:00
url : url ,
2017-04-13 02:42:32 +02:00
data : { "guild_id" : guild _id }
2017-04-04 07:53:27 +02:00
} ) ;
2017-04-13 02:42:32 +02:00
return funct . promise ( ) ;
2017-04-04 07:53:27 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function create _authenticated _user ( ) {
var funct = $ . ajax ( {
method : "POST" ,
dataType : "json" ,
url : "/api/create_authenticated_user" ,
data : { "guild_id" : guild _id }
} ) ;
return funct . promise ( ) ;
2017-04-04 07:53:27 +02:00
}
2017-04-14 08:10:13 +02:00
2017-09-21 09:12:49 +02:00
function create _unauthenticated _user ( username , captchaResponse ) {
2017-04-13 02:42:32 +02:00
var funct = $ . ajax ( {
method : "POST" ,
dataType : "json" ,
url : "/api/create_unauthenticated_user" ,
2017-09-21 09:12:49 +02:00
data : { "username" : username , "guild_id" : guild _id , "captcha_response" : captchaResponse }
2017-04-10 01:40:11 +02:00
} ) ;
2017-04-13 02:42:32 +02:00
return funct . promise ( ) ;
2017-04-04 07:53:27 +02:00
}
2017-08-10 23:27:08 +02:00
function change _unauthenticated _username ( username ) {
var funct = $ . ajax ( {
method : "POST" ,
dataType : "json" ,
url : "/api/change_unauthenticated_username" ,
data : { "username" : username , "guild_id" : guild _id }
} ) ;
return funct . promise ( ) ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function fetch ( channel _id , after = null ) {
2017-06-09 06:22:33 +02:00
var url = "/api/fetch" ;
if ( visitor _mode ) {
url += "_visitor" ;
}
2017-04-13 02:42:32 +02:00
var funct = $ . ajax ( {
method : "GET" ,
dataType : "json" ,
2017-06-09 06:22:33 +02:00
url : url ,
2017-04-13 02:42:32 +02:00
data : { "guild_id" : guild _id , "channel_id" : channel _id , "after" : after }
2017-04-10 01:40:11 +02:00
} ) ;
2017-04-13 02:42:32 +02:00
return funct . promise ( ) ;
2017-04-04 07:53:27 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function post ( channel _id , content ) {
var funct = $ . ajax ( {
method : "POST" ,
dataType : "json" ,
url : "/api/post" ,
data : { "guild_id" : guild _id , "channel_id" : channel _id , "content" : content }
} ) ;
return funct . promise ( ) ;
2017-04-04 07:53:27 +02:00
}
2017-05-23 20:58:49 +02:00
2017-05-24 07:03:48 +02:00
function discord _embed ( ) {
var funct = $ . ajax ( {
dataType : "json" ,
url : "https://discordapp.com/api/guilds/" + guild _id + "/widget.json" ,
} ) ;
return funct . promise ( ) ;
}
2017-12-07 07:49:32 +01:00
function api _badges ( user _id ) {
var funct = $ . ajax ( {
dataType : "json" ,
url : "/api/badges/" + user _id ,
} ) ;
return funct . promise ( ) ;
}
2017-05-23 20:58:49 +02:00
$ ( function ( ) {
2017-05-26 05:16:23 +02:00
if ( $ ( "#user-defined-css" ) . length > 0 ) {
user _def _css = $ ( "#user-defined-css" ) . text ( ) ;
}
2017-05-26 00:50:15 +02:00
$ ( 'select' ) . material _select ( ) ;
2017-06-10 04:20:22 +02:00
$ ( "#loginmodal" ) . modal ( {
dismissible : visitors _enabled , // Modal can be dismissed by clicking outside of the modal
opacity : . 5 , // Opacity of modal background
inDuration : 300 , // Transition in duration
outDuration : 200 , // Transition out duration
startingTop : '4%' , // Starting top style attribute
endingTop : '10%' , // Ending top style attribute
}
) ;
$ ( '#loginmodal' ) . modal ( 'open' ) ;
2017-09-21 09:12:49 +02:00
$ ( "#recaptchamodal" ) . modal ( {
dismissible : true ,
opacity : . 5 ,
inDuration : 400 ,
outDuration : 400 ,
startingTop : '40%' ,
endingTop : '30%' ,
} ) ;
2017-05-26 00:50:15 +02:00
$ ( "#userembedmodal" ) . modal ( {
dismissible : true ,
opacity : . 5 ,
inDuration : 400 ,
outDuration : 400 ,
} ) ;
2017-12-07 07:49:32 +01:00
$ ( "#usercard" ) . modal ( {
opacity : . 5 ,
} ) ;
2017-05-23 20:58:49 +02:00
2017-05-26 00:50:15 +02:00
$ ( "#nameplate" ) . click ( function ( ) {
$ ( "#userembedmodal" ) . modal ( "open" ) ;
} ) ;
2017-06-09 06:22:33 +02:00
$ ( "#visitor_login_btn" ) . click ( function ( ) {
$ ( "#loginmodal" ) . modal ( "open" ) ;
} ) ;
2017-08-13 12:14:03 +02:00
$ ( "#emoji-tray-toggle" ) . click ( function ( ) {
$ ( "#emoji-picker" ) . fadeToggle ( ) ;
var offset = $ ( "#emoji-tray-toggle" ) . offset ( ) . top ;
$ ( "#emoji-picker" ) . offset ( { "top" : offset - 120 } ) ;
$ ( "#emoji-picker-emojis" ) . html ( "" ) ;
var template = $ ( '#mustache_message_emoji' ) . html ( ) ;
Mustache . parse ( template ) ;
for ( var i = 0 ; i < emoji _store . length ; i ++ ) {
var emoji = emoji _store [ i ] ;
var rendered = Mustache . render ( template , { "id" : emoji . id , "name" : emoji . name } ) . trim ( ) ;
var jqueryed = $ ( rendered ) ;
jqueryed . click ( function ( ) {
var emote _name = $ ( this ) . attr ( "data-tooltip" ) ;
place _emoji ( emote _name ) ;
} ) ;
$ ( "#emoji-picker-emojis" ) . append ( jqueryed ) ;
}
$ ( '.tooltipped' ) . tooltip ( ) ;
} ) ;
$ ( "#chatcontent" ) . click ( function ( ) {
var emojipck _display = $ ( '#emoji-picker' ) . css ( 'display' ) ;
if ( emojipck _display != "none" ) {
$ ( "#emoji-picker" ) . fadeToggle ( ) ;
}
} ) ;
$ ( "#messagebox" ) . click ( function ( ) {
var emojipck _display = $ ( '#emoji-picker' ) . css ( 'display' ) ;
if ( emojipck _display != "none" ) {
$ ( "#emoji-picker" ) . fadeToggle ( ) ;
}
} ) ;
2017-08-08 05:14:17 +02:00
$ ( "#theme-selector" ) . change ( function ( ) {
2017-05-26 00:50:15 +02:00
var theme = $ ( "#theme-selector option:selected" ) . val ( ) ;
2017-08-08 05:14:17 +02:00
var keep _custom _css = $ ( "#overwrite_theme_custom_css_checkbox" ) . is ( ':checked' ) ;
changeTheme ( theme , keep _custom _css ) ;
} ) ;
$ ( "#overwrite_theme_custom_css_checkbox" ) . change ( function ( ) {
var keep _custom _css = $ ( "#overwrite_theme_custom_css_checkbox" ) . is ( ':checked' ) ;
changeTheme ( null , keep _custom _css ) ;
2017-05-26 00:50:15 +02:00
} ) ;
2017-05-26 01:17:22 +02:00
2017-09-23 19:38:14 +02:00
hljs . configure ( { useBR : true } ) ;
linkify . options . defaults . ignoreTags = [ "code" ] ;
2017-05-26 01:17:22 +02:00
var themeparam = getParameterByName ( 'theme' ) ;
2017-05-26 04:58:04 +02:00
var localstore _theme = localStorage . getItem ( "theme" ) ;
2017-08-08 05:14:17 +02:00
if ( ( themeparam && $ . inArray ( themeparam , theme _options ) != - 1 ) || ( localstore _theme ) ) {
2017-05-26 04:58:04 +02:00
var theme ;
if ( themeparam ) {
theme = themeparam ;
} else {
theme = localstore _theme ;
}
2017-10-04 08:04:27 +02:00
changeTheme ( theme , true , false ) ;
2017-05-26 01:17:22 +02:00
$ ( "#theme-selector option" ) . removeAttr ( 'selected' ) ;
2017-05-26 04:58:04 +02:00
$ ( "#theme-selector option[value=" + theme + "]" ) . attr ( 'selected' , 'selected' ) ;
$ ( 'select' ) . material _select ( ) ;
2017-05-26 01:17:22 +02:00
}
2017-05-26 05:16:23 +02:00
2017-11-13 02:26:00 +01:00
$ ( "[name=notification_sound_radiobtn]" ) . click ( function ( event ) {
changeNotificationSound ( event . target . value ) ;
} ) ;
var localstore _notification _sound = localStorage . getItem ( "notification_sound" ) ;
if ( localstore _notification _sound ) {
changeNotificationSound ( localstore _notification _sound ) ;
} else {
changeNotificationSound ( "mentions" ) ;
}
notification _sound = soundManager . createSound ( {
id : 'notification_sound_id' ,
url : "/static/audio/demonstrative.mp3" ,
volume : 8 ,
} ) ;
2017-06-10 04:20:22 +02:00
var dembed = discord _embed ( ) ;
dembed . done ( function ( data ) {
$ ( "#modal_invite_btn" ) . attr ( "href" , data . instant _invite ) ;
} ) ;
2017-10-29 03:00:21 +01:00
if ( getParameterByName ( "noscroll" ) != "true" ) {
has _handled _noscroll = true ;
}
2017-07-20 04:26:35 +02:00
$ ( window ) . resize ( function ( ) {
// For those who decides to hide the embed at first load (display: none), resulting in the messages being not scrolled down.
if ( ! has _already _been _initially _resized ) {
has _already _been _initially _resized = true ;
2017-10-29 03:00:21 +01:00
if ( has _handled _noscroll ) {
$ ( "html, body" ) . animate ( { scrollTop : $ ( document ) . height ( ) } , "fast" ) ;
} else {
has _handled _noscroll = true ;
Materialize . toast ( 'Continue scrolling to read on...' , 5000 ) ;
}
2017-07-20 04:26:35 +02:00
}
} ) ;
2017-08-27 23:47:25 +02:00
primeEmbed ( ) ;
2017-08-21 06:26:51 +02:00
setInterval ( send _socket _heartbeat , 5000 ) ;
2017-08-30 20:48:26 +02:00
if ( getParameterByName ( "username" ) ) {
$ ( "#custom_username_field" ) . val ( getParameterByName ( "username" ) ) ;
}
2017-05-23 20:58:49 +02:00
} ) ;
2017-05-26 00:50:15 +02:00
2017-11-13 02:26:00 +01:00
function changeNotificationSound ( sound ) {
var soundTypes = [ "newmsgs" , "mentions" , "nothing" ] ;
if ( $ . inArray ( sound , soundTypes ) != - 1 ) {
notification _sound _setting = sound ;
$ ( "[name=notification_sound_radiobtn][value=" + sound + "]" ) . prop ( "checked" , true ) ;
localStorage . setItem ( "notification_sound" , sound ) ;
}
}
2017-10-04 08:04:27 +02:00
function changeTheme ( theme = null , keep _custom _css = true , modifyLocalStore = true ) {
2017-05-26 01:17:22 +02:00
if ( theme == "" ) {
$ ( "#css-theme" ) . attr ( "href" , "" ) ;
2017-05-26 05:16:23 +02:00
$ ( "#user-defined-css" ) . text ( user _def _css ) ;
2017-10-04 08:04:27 +02:00
if ( modifyLocalStore ) {
localStorage . removeItem ( "theme" ) ;
}
2017-08-08 05:14:17 +02:00
} else if ( $ . inArray ( theme , theme _options ) != - 1 || theme == null ) {
if ( ! keep _custom _css ) {
$ ( "#user-defined-css" ) . text ( "" ) ;
} else {
$ ( "#user-defined-css" ) . text ( user _def _css ) ;
}
if ( theme ) {
$ ( "#css-theme" ) . attr ( "href" , "/static/themes/" + theme + "/css/style.css" ) ;
2017-10-04 08:04:27 +02:00
if ( modifyLocalStore ) {
localStorage . setItem ( "theme" , theme ) ;
}
2017-08-08 05:14:17 +02:00
}
2017-05-26 01:17:22 +02:00
}
}
/* https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript */
function getParameterByName ( name , url ) {
if ( ! url ) url = window . location . href ;
name = name . replace ( /[\[\]]/g , "\\$&" ) ;
var regex = new RegExp ( "[?&]" + name + "(=([^&#]*)|&|#|$)" ) ,
results = regex . exec ( url ) ;
if ( ! results ) return null ;
if ( ! results [ 2 ] ) return '' ;
return decodeURIComponent ( results [ 2 ] . replace ( /\+/g , " " ) ) ;
}
2017-06-09 06:22:33 +02:00
function setVisitorMode ( enabled ) {
if ( ! visitors _enabled ) {
return ;
}
visitor _mode = enabled ;
if ( visitor _mode ) {
$ ( "#visitor_mode_message" ) . show ( ) ;
$ ( "#messagebox" ) . hide ( ) ;
2017-08-13 12:14:03 +02:00
$ ( "#emoji-tray-toggle" ) . hide ( ) ;
2017-06-09 06:22:33 +02:00
} else {
$ ( "#visitor_mode_message" ) . hide ( ) ;
$ ( "#messagebox" ) . show ( ) ;
2017-08-13 12:14:03 +02:00
$ ( "#emoji-tray-toggle" ) . show ( ) ;
2017-06-09 06:22:33 +02:00
}
}
2017-05-23 20:58:49 +02:00
function primeEmbed ( ) {
2017-04-26 09:30:36 +02:00
lock _login _fields ( ) ;
2017-04-13 02:42:32 +02:00
var guild = query _guild ( ) ;
guild . fail ( function ( ) {
2017-04-26 09:30:36 +02:00
unlock _login _fields ( ) ;
2017-06-09 06:22:33 +02:00
if ( visitors _enabled ) {
setVisitorMode ( true ) ;
var guild2 = query _guild ( ) ;
guild2 . done ( function ( data ) {
initialize _embed ( data ) ;
} ) ;
guild2 . fail ( function ( ) {
setVisitorMode ( false ) ;
} ) ;
}
2017-04-04 07:53:27 +02:00
} ) ;
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
guild . done ( function ( data ) {
initialize _embed ( data ) ;
2017-04-04 07:53:27 +02:00
} ) ;
2017-05-23 20:58:49 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function lock _login _fields ( ) {
$ ( "#loginProgress" ) . show ( ) ;
$ ( "#discordlogin_btn" ) . attr ( "disabled" , true ) ;
$ ( "#custom_username_field" ) . prop ( "disabled" , true ) ;
logintimer = setTimeout ( function ( ) {
unlock _login _fields ( ) ;
} , 60000 ) ;
2017-04-05 20:43:59 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function unlock _login _fields ( ) {
$ ( "#loginProgress" ) . hide ( ) ;
$ ( "#discordlogin_btn" ) . attr ( "disabled" , false ) ;
$ ( "#custom_username_field" ) . prop ( "disabled" , false ) ;
clearTimeout ( logintimer ) ;
2017-04-05 07:10:20 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function initialize _embed ( guildobj ) {
2017-08-21 06:26:51 +02:00
if ( socket ) {
socket . disconnect ( ) ;
2017-09-02 06:06:15 +02:00
socket = null ;
2017-08-21 06:26:51 +02:00
}
2017-04-13 02:42:32 +02:00
if ( guildobj === undefined ) {
var guild = query _guild ( ) ;
guild . done ( function ( data ) {
2017-07-18 06:46:26 +02:00
switch _to _default _channel ( data . channels ) ;
2017-04-13 02:42:32 +02:00
prepare _guild ( data ) ;
2017-04-26 09:30:36 +02:00
$ ( '#loginmodal' ) . modal ( 'close' ) ;
unlock _login _fields ( ) ;
2017-04-13 02:42:32 +02:00
} ) ;
} else {
2017-07-18 06:46:26 +02:00
switch _to _default _channel ( guildobj . channels ) ;
2017-04-13 02:42:32 +02:00
prepare _guild ( guildobj ) ;
2017-04-26 09:30:36 +02:00
$ ( '#loginmodal' ) . modal ( 'close' ) ;
unlock _login _fields ( ) ;
2017-04-09 00:32:28 +02:00
}
2017-04-12 15:15:05 +02:00
}
2017-07-18 06:46:26 +02:00
function switch _to _default _channel ( guildchannels ) {
var defaultChannel = getParameterByName ( "defaultchannel" ) ;
if ( ! defaultChannel ) {
return ;
}
for ( var i = 0 ; i < guildchannels . length ; i ++ ) {
if ( guildchannels [ i ] . channel . id == defaultChannel ) {
2017-08-09 04:07:13 +02:00
if ( ! guildchannels [ i ] . read ) {
return ;
}
2017-07-18 06:46:26 +02:00
selected _channel = defaultChannel ;
return ;
}
}
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function prepare _guild ( guildobj ) {
2017-09-24 06:35:51 +02:00
global _guest _icon = guildobj . guest _icon ;
2017-06-09 10:22:22 +02:00
emoji _store = guildobj . emojis ;
2017-04-13 02:42:32 +02:00
fill _channels ( guildobj . channels ) ;
fill _discord _members ( guildobj . discordmembers ) ;
fill _authenticated _users ( guildobj . embedmembers . authenticated ) ;
fill _unauthenticated _users ( guildobj . embedmembers . unauthenticated ) ;
2017-05-24 05:41:12 +02:00
$ ( "#instant-inv" ) . attr ( "href" , guildobj . instant _invite ) ;
2017-04-13 02:42:32 +02:00
run _fetch _routine ( ) ;
2017-08-21 06:26:51 +02:00
initiate _websockets ( ) ;
2017-04-05 05:46:48 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function fill _channels ( channels ) {
2017-08-25 08:37:14 +02:00
guild _channels _list = channels ;
2017-04-13 02:42:32 +02:00
var template = $ ( '#mustache_channellistings' ) . html ( ) ;
Mustache . parse ( template ) ;
2017-09-09 23:46:00 +02:00
var template _category = $ ( '#mustache_channelcategory' ) . html ( ) ;
Mustache . parse ( template _category ) ;
2017-04-13 02:42:32 +02:00
$ ( "#channels-list" ) . empty ( ) ;
2017-08-09 03:26:11 +02:00
var curr _default _channel = selected _channel ;
2017-09-09 23:46:00 +02:00
var categories = [ {
"channel" : { id : null , name : "Uncategorized" } ,
"children" : [ ] ,
"read" : true ,
} ] ;
2017-04-13 02:42:32 +02:00
for ( var i = 0 ; i < channels . length ; i ++ ) {
var chan = channels [ i ] ;
2017-04-13 08:05:04 +02:00
guild _channels [ chan . channel . id ] = chan ;
2017-09-09 23:46:00 +02:00
if ( chan . channel . type == "category" ) {
chan . children = [ ] ;
categories . push ( chan ) ;
}
}
categories . sort ( function ( a , b ) {
return parseInt ( a . channel . position ) - parseInt ( b . channel . position ) ;
} ) ;
for ( var i = 0 ; i < channels . length ; i ++ ) {
var chan = channels [ i ] ;
if ( chan . channel . type == "text" ) {
var cate = chan . channel . parent _id ;
for ( var j = 0 ; j < categories . length ; j ++ ) {
var thiscategory = categories [ j ] ;
if ( thiscategory . channel . id == cate ) {
thiscategory . children . push ( chan ) ;
break ;
}
}
}
}
for ( var i = 0 ; i < categories . length ; i ++ ) {
var cate = categories [ i ] ;
cate . read = false ;
for ( var j = 0 ; j < cate . children . length ; j ++ ) {
var chan = cate . children [ j ] ;
if ( chan . channel . type == "text" && chan . read ) {
cate . read = true ;
break ;
}
}
}
for ( var i = 0 ; i < categories . length ; i ++ ) {
var cate = categories [ i ] ;
var children = cate . children ;
children . sort ( function ( a , b ) {
return parseInt ( a . channel . position ) - parseInt ( b . channel . position ) ;
} ) ;
if ( i != 0 ) {
if ( cate . read ) {
var rendered _category = Mustache . render ( template _category , { "name" : cate . channel . name } ) ;
$ ( "#channels-list" ) . append ( rendered _category ) ;
}
}
for ( var j = 0 ; j < children . length ; j ++ ) {
var chan = children [ j ] ;
if ( chan . read ) {
var rendered _channel = Mustache . render ( template , { "channelid" : chan . channel . id , "channelname" : chan . channel . name } ) ;
$ ( "#channels-list" ) . append ( rendered _channel ) ;
$ ( "#channel-" + chan . channel . id . toString ( ) ) . click ( { "channel_id" : chan . channel . id . toString ( ) } , function ( event ) {
select _channel ( event . data . channel _id ) ;
} ) ;
if ( ! selected _channel && ( ! curr _default _channel || chan . channel . position < curr _default _channel . channel . position ) ) {
curr _default _channel = chan ;
}
}
2017-04-13 02:42:32 +02:00
}
}
2017-08-09 03:26:11 +02:00
if ( typeof curr _default _channel == "object" ) {
selected _channel = curr _default _channel . channel . id ;
}
var this _channel = guild _channels [ selected _channel ] ;
if ( this _channel . write ) {
$ ( "#messagebox" ) . prop ( 'disabled' , false ) ;
$ ( "#messagebox" ) . prop ( 'placeholder' , "Enter message" ) ;
} else {
$ ( "#messagebox" ) . prop ( 'disabled' , true ) ;
$ ( "#messagebox" ) . prop ( 'placeholder' , "Messages is disabled in this channel." ) ;
}
$ ( "#channeltopic" ) . text ( this _channel . channel . topic ) ;
2017-04-13 02:42:32 +02:00
$ ( "#channel-" + selected _channel ) . parent ( ) . addClass ( "active" ) ;
2017-04-05 05:46:48 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function mention _member ( member _id ) {
if ( ! $ ( '#messagebox' ) . prop ( 'disabled' ) ) {
$ ( '#messagebox' ) . val ( $ ( '#messagebox' ) . val ( ) + "[@" + member _id + "] " ) ;
$ ( '.button-collapse' ) . sideNav ( 'hide' ) ;
$ ( "#messagebox" ) . focus ( ) ;
}
2017-04-05 05:46:48 +02:00
}
2017-08-13 12:14:03 +02:00
function place _emoji ( emoji _name ) {
if ( ! $ ( '#messagebox' ) . prop ( 'disabled' ) ) {
$ ( '#messagebox' ) . val ( $ ( '#messagebox' ) . val ( ) + emoji _name + " " ) ;
$ ( "#messagebox" ) . focus ( ) ;
}
var emojipck _display = $ ( '#emoji-picker' ) . css ( 'display' ) ;
if ( emojipck _display != "none" ) {
$ ( "#emoji-picker" ) . fadeToggle ( ) ;
}
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function fill _discord _members ( discordmembers ) {
2017-08-22 08:57:30 +02:00
discord _users _list = discordmembers ;
2017-04-13 02:42:32 +02:00
var template = $ ( '#mustache_authedusers' ) . html ( ) ;
Mustache . parse ( template ) ;
$ ( "#discord-members" ) . empty ( ) ;
2017-04-14 08:10:13 +02:00
var guild _members = { } ;
2017-04-13 02:42:32 +02:00
for ( var i = 0 ; i < discordmembers . length ; i ++ ) {
var member = discordmembers [ i ] ;
2017-04-14 08:10:13 +02:00
if ( member [ "hoist-role" ] ) {
if ( ! ( member [ "hoist-role" ] [ "id" ] in guild _members ) ) {
guild _members [ member [ "hoist-role" ] [ "id" ] ] = { } ;
guild _members [ member [ "hoist-role" ] [ "id" ] ] [ "name" ] = member [ "hoist-role" ] [ "name" ] ;
guild _members [ member [ "hoist-role" ] [ "id" ] ] [ "members" ] = [ ] ;
2017-05-24 05:20:23 +02:00
guild _members [ member [ "hoist-role" ] [ "id" ] ] [ "position" ] = member [ "hoist-role" ] [ "position" ] ;
2017-04-14 08:10:13 +02:00
}
guild _members [ member [ "hoist-role" ] [ "id" ] ] [ "members" ] . push ( member ) ;
} else {
if ( ! ( "0" in guild _members ) ) {
guild _members [ "0" ] = { } ;
guild _members [ "0" ] [ "name" ] = null ;
guild _members [ "0" ] [ "members" ] = [ ] ;
guild _members [ "0" ] [ "position" ] = 0 ;
}
guild _members [ "0" ] [ "members" ] . push ( member ) ;
}
}
var guild _members _arr = [ ] ;
2017-05-24 05:20:23 +02:00
for ( var key in guild _members ) {
2017-04-14 08:10:13 +02:00
guild _members _arr . push ( guild _members [ key ] ) ;
}
guild _members _arr . sort ( function ( a , b ) {
return parseInt ( b . position ) - parseInt ( a . position ) ;
2017-04-15 09:14:09 +02:00
} ) ;
2017-04-14 08:10:13 +02:00
var template _role = $ ( '#mustache_memberrole' ) . html ( ) ;
Mustache . parse ( template _role ) ;
var template _user = $ ( '#mustache_authedusers' ) . html ( ) ;
Mustache . parse ( template _user ) ;
$ ( "#discord-members" ) . empty ( ) ;
2017-04-22 08:35:30 +02:00
var discordmembercnt = 0 ;
2017-04-14 08:10:13 +02:00
for ( var i = 0 ; i < guild _members _arr . length ; i ++ ) {
var roleobj = guild _members _arr [ i ] ;
if ( ! roleobj [ "name" ] ) {
roleobj [ "name" ] = "Uncategorized" ;
}
2017-04-22 08:35:30 +02:00
var rendered _role = Mustache . render ( template _role , { "name" : roleobj [ "name" ] + " - " + roleobj [ "members" ] . length } ) ;
discordmembercnt += roleobj [ "members" ] . length ;
2017-04-14 08:10:13 +02:00
$ ( "#discord-members" ) . append ( rendered _role ) ;
2017-08-22 09:53:41 +02:00
roleobj . members . sort ( function ( a , b ) {
var name _a = a . username ;
var name _b = b . username ;
if ( a . nick ) {
name _a = a . nick ;
}
if ( b . nick ) {
name _b = b . nick ;
}
name _a = name _a . toUpperCase ( ) ;
name _b = name _b . toUpperCase ( ) ;
if ( name _a < name _b ) return - 1 ;
if ( name _a > name _b ) return 1 ;
return 0 ;
} ) ;
2017-04-14 08:10:13 +02:00
for ( var j = 0 ; j < roleobj . members . length ; j ++ ) {
var member = roleobj . members [ j ] ;
2017-08-07 05:08:26 +02:00
var member _name = member . nick ;
if ( ! member _name ) {
member _name = member . username ;
}
var rendered _user = Mustache . render ( template _user , { "id" : member . id . toString ( ) + "d" , "username" : member _name , "avatar" : member . avatar _url } ) ;
2017-04-14 08:10:13 +02:00
$ ( "#discord-members" ) . append ( rendered _user ) ;
2017-04-13 02:42:32 +02:00
$ ( "#discorduser-" + member . id . toString ( ) + "d" ) . click ( { "member_id" : member . id . toString ( ) } , function ( event ) {
2017-12-07 07:49:32 +01:00
openUserCard ( event . data . member _id ) ;
2017-04-13 02:42:32 +02:00
} ) ;
2017-04-14 08:10:13 +02:00
if ( member . color ) {
$ ( "#discorduser-" + member . id . toString ( ) + "d" ) . css ( "color" , "#" + member . color ) ;
}
}
2017-04-05 06:00:44 +02:00
}
2017-04-22 08:35:30 +02:00
$ ( "#discord-members-count" ) . html ( discordmembercnt ) ;
2017-04-13 02:42:32 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function fill _authenticated _users ( users ) {
var template = $ ( '#mustache_authedusers' ) . html ( ) ;
Mustache . parse ( template ) ;
$ ( "#embed-discord-members" ) . empty ( ) ;
2017-04-22 08:35:30 +02:00
$ ( "#embed-discord-members-count" ) . html ( users . length ) ;
2017-04-13 02:42:32 +02:00
for ( var i = 0 ; i < users . length ; i ++ ) {
var member = users [ i ] ;
2017-08-10 04:05:05 +02:00
var username = member . username ;
if ( member . nickname ) {
username = member . nickname ;
}
var rendered = Mustache . render ( template , { "id" : member . id . toString ( ) + "a" , "username" : username , "avatar" : member . avatar _url } ) ;
2017-04-13 02:42:32 +02:00
$ ( "#embed-discord-members" ) . append ( rendered ) ;
$ ( "#discorduser-" + member . id . toString ( ) + "a" ) . click ( { "member_id" : member . id . toString ( ) } , function ( event ) {
2017-12-07 07:49:32 +01:00
openUserCard ( event . data . member _id ) ;
2017-04-13 02:42:32 +02:00
} ) ;
2017-04-05 05:46:48 +02:00
}
2017-08-22 08:57:30 +02:00
authenticated _users _list = users ;
2017-04-04 21:16:21 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function fill _unauthenticated _users ( users ) {
var template = $ ( '#mustache_unauthedusers' ) . html ( ) ;
Mustache . parse ( template ) ;
$ ( "#embed-unauth-users" ) . empty ( ) ;
2017-04-22 08:35:30 +02:00
$ ( "#guest-members-count" ) . html ( users . length ) ;
2017-04-13 02:42:32 +02:00
for ( var i = 0 ; i < users . length ; i ++ ) {
var member = users [ i ] ;
var rendered = Mustache . render ( template , { "username" : member . username , "discriminator" : member . discriminator } ) ;
$ ( "#embed-unauth-users" ) . append ( rendered ) ;
2017-04-08 23:53:58 +02:00
}
2017-08-22 08:57:30 +02:00
unauthenticated _users _list = users ;
2017-04-13 02:42:32 +02:00
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function wait _for _discord _login ( ) {
_wait _for _discord _login ( 0 ) ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function _wait _for _discord _login ( index ) {
setTimeout ( function ( ) {
var usr = create _authenticated _user ( ) ;
2017-04-08 23:53:58 +02:00
usr . done ( function ( data ) {
2017-06-09 06:22:33 +02:00
setVisitorMode ( false ) ;
2017-04-08 23:53:58 +02:00
initialize _embed ( ) ;
2017-04-13 02:42:32 +02:00
return ;
2017-04-08 23:53:58 +02:00
} ) ;
usr . fail ( function ( data ) {
2017-04-13 02:42:32 +02:00
if ( data . status == 403 ) {
2017-04-08 23:53:58 +02:00
Materialize . toast ( 'Authentication error! You have been banned.' , 10000 ) ;
2017-06-09 06:22:33 +02:00
setVisitorMode ( true ) ;
2017-09-21 23:47:00 +02:00
} else if ( data . status == 422 ) {
if ( data . responseJSON . code == 403 ) {
Materialize . toast ( "Attempting to add you into the server store has failed. The bot does not have permissions to create instant invite. Therefore, Discord Login has been disabled." , 10000 ) ;
} else {
Materialize . toast ( "Attempting to add you into the server has failed. Either you are banned, reached 100 servers in Discord, or something else bad has happened." , 10000 ) ;
}
2017-04-13 02:42:32 +02:00
} else if ( index < 10 ) {
_wait _for _discord _login ( index + 1 ) ;
2017-04-08 23:53:58 +02:00
}
2017-04-13 02:42:32 +02:00
} ) ;
} , 5000 ) ;
2017-04-05 20:43:59 +02:00
}
2017-11-01 07:31:44 +01:00
2017-12-07 07:49:32 +01:00
function openUserCard ( user _id ) {
var bgs = api _badges ( user _id ) ;
bgs . done ( function ( data ) {
for ( var i = 0 ; i < badges _options . length ; i ++ ) {
var badge = badges _options [ i ] ;
if ( data . indexOf ( badge ) != - 1 ) {
$ ( ` #usercard .badges . ${ badge } ` ) . show ( ) ;
} else {
$ ( ` #usercard .badges . ${ badge } ` ) . hide ( ) ;
}
}
} ) ;
for ( var i = 0 ; i < discord _users _list . length ; i ++ ) {
var usr = discord _users _list [ i ] ;
if ( usr . id == user _id ) {
$ ( "#usercard .avatar" ) . attr ( "src" , usr . avatar _url ) ;
$ ( "#usercard .identity .username" ) . text ( usr . username ) ;
$ ( "#usercard .identity .discriminator" ) . text ( usr . discriminator ) ;
if ( usr . bot ) {
$ ( "#usercard .bottag" ) . show ( ) ;
} else {
$ ( "#usercard .bottag" ) . hide ( ) ;
}
if ( usr . status == "offline" ) {
$ ( "#usercard .offline-text" ) . show ( ) ;
} else {
$ ( "#usercard .offline-text" ) . hide ( ) ;
}
if ( usr [ "hoist-role" ] ) {
$ ( "#usercard .role" ) . show ( ) ;
$ ( "#usercard .role .text" ) . text ( usr [ "hoist-role" ] . name ) ;
if ( usr . color ) {
$ ( "#usercard .role .bubble" ) . css ( "color" , "#" + usr . color ) ;
$ ( "#usercard .role .color" ) . css ( "background-color" , "#" + usr . color ) ;
}
} else {
$ ( "#usercard .role" ) . hide ( ) ;
}
if ( usr . game ) {
$ ( "#usercard .game" ) . show ( ) ;
$ ( "#usercard .game .text" ) . text ( usr . game . name ) ;
} else {
$ ( "#usercard .game" ) . hide ( ) ;
}
$ ( "#usercard-mention-btn" ) . off ( "click" ) ;
$ ( "#usercard-mention-btn" ) . click ( function ( ) {
mention _member ( user _id ) ;
$ ( "#usercard" ) . modal ( 'close' ) ;
} ) ;
}
}
$ ( "#usercard" ) . modal ( 'open' ) ;
}
2017-11-01 07:31:44 +01:00
function flashElement ( element ) {
var opacity = element . css ( "opacity" ) ;
for ( var i = 0 ; i < 3 ; i ++ ) {
element . animate ( { opacity : 0 } , "fast" ) ;
element . animate ( { opacity : 100 } , "fast" ) ;
}
element . css ( "opacity" , opacity ) ;
}
function select _channel ( channel _id , animate _it ) {
if ( selected _channel != channel _id && guild _channels [ channel _id ] && guild _channels [ channel _id ] . read ) {
if ( animate _it ) {
$ ( "#guild-btn" ) . sideNav ( "show" ) ;
2017-11-01 18:30:47 +01:00
$ ( "#channel-" + channel _id ) [ 0 ] . scrollIntoView ( { behavior : "smooth" } ) ;
2017-11-01 07:31:44 +01:00
flashElement ( $ ( "#channel-" + channel _id ) ) ;
setTimeout ( function ( ) {
$ ( "#guild-btn" ) . sideNav ( "hide" ) ;
select _channel ( channel _id ) ;
} , 1000 ) ;
return ;
}
2017-04-13 02:42:32 +02:00
selected _channel = channel _id ;
last _message _id = null ;
$ ( "#channels-list > li.active" ) . removeClass ( "active" ) ;
$ ( "#channel-" + selected _channel ) . parent ( ) . addClass ( "active" ) ;
2017-04-05 08:25:07 +02:00
run _fetch _routine ( ) ;
2017-04-13 02:42:32 +02:00
}
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function replace _message _mentions ( message ) {
var mentions = message . mentions ;
2017-11-06 04:12:18 +01:00
var template = $ ( '#mustache_discordmention' ) . html ( ) ;
Mustache . parse ( template ) ;
2017-04-13 02:42:32 +02:00
for ( var i = 0 ; i < mentions . length ; i ++ ) {
var mention = mentions [ i ] ;
2017-08-10 04:56:45 +02:00
var username = mention . username ;
if ( mention . nickname ) {
username = mention . nickname ;
}
2017-11-06 04:12:18 +01:00
var rendered = Mustache . render ( template , { "username" : username , "discriminator" : mention . discriminator } ) . trim ( ) ;
message . content = message . content . replace ( new RegExp ( "<@" + mention . id + ">" , 'g' ) , rendered ) ;
message . content = message . content . replace ( new RegExp ( "<@!" + mention . id + ">" , 'g' ) , rendered ) ;
2017-11-06 03:57:46 +01:00
message . content = message . content . replace ( "<@&" + guild _id + ">" , "@everyone" ) ;
2017-04-13 02:42:32 +02:00
}
return message ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function getPosition ( string , subString , index ) {
return string . split ( subString , index ) . join ( subString ) . length ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function format _bot _message ( message ) {
if ( message . author . id == bot _client _id && ( message . content . includes ( "**" ) && ( ( message . content . includes ( "<" ) && message . content . includes ( ">" ) ) || ( message . content . includes ( "[" ) && message . content . includes ( "]" ) ) ) ) ) {
var usernamefield = message . content . substring ( getPosition ( message . content , "**" , 1 ) + 3 , getPosition ( message . content , "**" , 2 ) - 1 ) ;
2017-07-06 19:18:15 +02:00
if ( message . content . startsWith ( "(Titan Dev) " ) ) {
message . content = message . content . substring ( usernamefield . length + 18 ) ;
} else {
message . content = message . content . substring ( usernamefield . length + 7 ) ;
}
2017-04-13 02:42:32 +02:00
message . author . username = usernamefield . split ( "#" ) [ 0 ] ;
message . author . discriminator = usernamefield . split ( "#" ) [ 1 ] ;
2017-07-01 08:52:21 +02:00
} else if ( message . author . bot && message . author . discriminator == "0000" && message . author . username . substring ( message . author . username . length - 5 , message . author . username . length - 4 ) == "#" ) {
var namestr = message . author . username ;
2017-07-06 19:18:15 +02:00
if ( message . content . startsWith ( "(Titan Dev) " ) ) {
message . author . username = "(Titan Dev) " + namestr . substring ( 0 , namestr . length - 5 ) ;
message . content = message . content . substring ( 11 ) ;
} else {
message . author . username = namestr . substring ( 0 , namestr . length - 5 ) ;
}
2017-07-01 08:52:21 +02:00
message . author . discriminator = namestr . substring ( namestr . length - 4 ) ;
2017-04-13 02:42:32 +02:00
}
return message ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function parse _message _time ( message ) {
var mome = moment ( message . timestamp ) ;
message . formatted _timestamp = mome . toDate ( ) . toString ( ) ;
2017-06-04 08:31:06 +02:00
message . formatted _time = mome . calendar ( ) ;
/*message.formatted_time = mome.format("h:mm A");*/
2017-04-13 02:42:32 +02:00
return message ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function parse _message _attachments ( message ) {
for ( var i = 0 ; i < message . attachments . length ; i ++ ) {
var attach = "" ;
if ( message . content . length != 0 ) {
attach = " " ;
}
2017-11-05 07:09:05 +01:00
if ( message . attachments [ i ] . url . endsWith ( ".png" ) || message . attachments [ i ] . url . endsWith ( ".jpg" ) || message . attachments [ i ] . url . endsWith ( ".jpeg" ) || message . attachments [ i ] . url . endsWith ( ".gif" ) ) {
attach += "<img class=\"attachment\" src=\"" + message . attachments [ i ] . url + "\">" ;
} else {
attach += message . attachments [ i ] . url ;
}
2017-04-13 02:42:32 +02:00
message . content += attach ;
}
return message ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function handle _last _message _mention ( ) {
var lastmsg = $ ( "#chatcontent p:last-child" ) ;
var content = lastmsg . text ( ) . toLowerCase ( ) ;
2017-05-24 06:42:01 +02:00
var username _discrim = current _username _discrim . toLowerCase ( ) ;
2017-06-12 06:31:34 +02:00
if ( content . includes ( "@everyone" ) || content . includes ( "@here" ) || content . includes ( "@" + username _discrim ) ) {
lastmsg . addClass ( "mentioned" ) ;
2017-04-13 02:42:32 +02:00
}
}
2017-11-13 02:26:00 +01:00
function play _notification _sound ( type ) { // type can be mention or new
if ( notification _sound _setting == "nothing" ) {
return ;
} else if ( notification _sound _setting == "mentions" && type != "mention" ) {
return ;
}
if ( notification _sound . playState == 0 ) {
notification _sound . play ( ) ;
}
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function escapeHtml ( unsafe ) { /* http://stackoverflow.com/questions/6234773/can-i-escape-html-special-chars-in-javascript */
return unsafe
. replace ( /&/g , "&" )
. replace ( /</g , "<" )
. replace ( />/g , ">" )
. replace ( /"/g , """ )
. replace ( /'/g , "'" ) ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function nl2br ( str , is _xhtml ) { /* http://stackoverflow.com/questions/2919337/jquery-convert-line-breaks-to-br-nl2br-equivalent/ */
2017-04-14 08:10:13 +02:00
var breakTag = ( is _xhtml || typeof is _xhtml === 'undefined' ) ? '<br />' : '<br>' ;
2017-04-13 02:42:32 +02:00
return ( str + '' ) . replace ( /([^>\r\n]?)(\r\n|\n\r|\r|\n)/g , '$1' + breakTag + '$2' ) ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 08:05:04 +02:00
function parse _channels _in _message ( message ) {
var channelids = Object . keys ( guild _channels ) ;
for ( var i = 0 ; i < channelids . length ; i ++ ) {
2017-11-01 07:31:44 +01:00
var pattern = "<#" + channelids [ i ] + ">" ;
var elem = "<span class=\"channellink\" channelid=\"" + channelids [ i ] + "\">#" + guild _channels [ channelids [ i ] ] . channel . name + "</span>" ;
message . content = message . content . replace ( new RegExp ( pattern , "g" ) , elem ) ;
2017-04-13 08:05:04 +02:00
}
return message ;
}
2017-06-09 10:22:22 +02:00
function parse _emoji _in _message ( message ) {
var template = $ ( '#mustache_message_emoji' ) . html ( ) ;
Mustache . parse ( template ) ;
for ( var i = 0 ; i < emoji _store . length ; i ++ ) {
var emoji = emoji _store [ i ] ;
var emoji _format = "<:" + emoji . name + ":" + emoji . id + ">" ;
var rendered = Mustache . render ( template , { "id" : emoji . id , "name" : emoji . name } ) . trim ( ) ;
2017-06-10 05:43:23 +02:00
message . content = message . content . replaceAll ( emoji _format , rendered ) ;
2017-06-09 10:22:22 +02:00
}
2017-09-06 08:42:17 +02:00
var rendered = Mustache . render ( template , { "id" : "$2" , "name" : "$1" } ) . trim ( ) ;
message . content = message . content . replace ( /<:(.*?):(.*?)>/g , rendered ) ;
2017-09-06 09:11:32 +02:00
message . content = twemoji . parse ( message . content , {
className : "message_emoji" ,
callback : function ( icon , options , variant ) { // exclude special characters
switch ( icon ) {
case 'a9' : // © copyright
case 'ae' : // ® registered trademark
case '2122' : // ™ trademark
return false ;
}
return '' . concat ( options . base , options . size , '/' , icon , options . ext ) ;
}
} ) ;
2017-06-09 10:22:22 +02:00
return message ;
}
2017-08-10 03:00:14 +02:00
function parse _message _markdown ( text ) {
2017-09-13 05:56:10 +02:00
var geturl _regex = /(\(.*?)?\b((?:https?|ftp|file):\/\/[-a-z0-9+&@#\/%?=~_()|!:,.;]*[-a-z0-9+&@#\/%=~_()|])/ig ;
var links = text . match ( geturl _regex ) ; // temporarily remove urls so markdown won't mark inside of the url
if ( links ) {
for ( var i = 0 ; i < links . length ; i ++ ) {
text = text . replace ( links [ i ] , "$LINK" + i + "$" ) ;
}
}
2017-08-10 03:00:14 +02:00
text = text . replace ( /\*\*(.*?)\*\*/g , "<b>$1</b>" ) ;
text = text . replace ( /\*(.*?)\*/g , "<i>$1</i>" ) ;
text = text . replace ( /__(.*?)__/g , "<u>$1</u>" ) ;
2017-08-10 03:11:18 +02:00
text = text . replace ( /_(.*?)_/g , "<i>$1</i>" ) ;
2017-08-10 03:00:14 +02:00
text = text . replace ( /~~(.*?)~~/g , "<del>$1</del>" ) ;
2017-09-23 19:59:06 +02:00
text = text . replace ( /\`\`\`([^]+?)\`\`\`/g , "<code class=\"blockcode\">$1</code>" ) ;
2017-08-10 03:00:14 +02:00
text = text . replace ( /\`(.*?)\`/g , "<code>$1</code>" ) ;
2017-09-13 05:56:10 +02:00
if ( links ) {
for ( var i = 0 ; i < links . length ; i ++ ) {
text = text . replace ( "$LINK" + i + "$" , links [ i ] ) ;
}
}
2017-08-10 03:00:14 +02:00
return text ;
}
2017-09-23 19:38:14 +02:00
function render _code _highlighting ( element ) {
2017-09-24 02:15:25 +02:00
for ( var i = 0 ; i < element . length ; i ++ ) {
var elem = $ ( element [ i ] ) ;
2017-09-23 19:38:14 +02:00
var codetext = elem . text ( ) ;
var splitted = codetext . split ( "\n" ) ;
if ( splitted . length > 1 ) {
var firstLine = splitted [ 0 ] ;
if ( ! ( /^\s/ . test ( firstLine ) ) ) { // make sure no whitespace at begining
var firstLineSplitted = firstLine . split ( /[ ]+/ ) ; // split at whitespace
if ( firstLineSplitted . length == 1 && firstLineSplitted [ 0 ] != "" ) { // only one token and the token is not empty
var language = firstLineSplitted [ 0 ] ; // assume token is lang
if ( hljs . getLanguage ( language ) ) {
splitted . splice ( 0 , 1 ) ; // delete first line
var restOfCode = splitted . join ( "\n" ) ;
var highlighted = hljs . highlight ( language , restOfCode , true ) ;
2017-09-24 02:15:25 +02:00
elem . html ( highlighted . value ) ;
2017-09-23 19:38:14 +02:00
}
}
}
}
2017-09-24 02:15:25 +02:00
}
2017-09-23 19:38:14 +02:00
}
2017-09-24 06:17:06 +02:00
function generate _avatar _url ( user _id , avatar _hash , message _contents = null ) {
if ( user _id == bot _client _id && ( message _contents . includes ( "**" ) && ( ( message _contents . includes ( "<" ) && message _contents . includes ( ">" ) ) || ( message _contents . includes ( "[" ) && message _contents . includes ( "]" ) ) ) ) ) {
return global _guest _icon ;
} else {
return "https://cdn.discordapp.com/avatars/" + user _id + "/" + avatar _hash + ".png" ;
}
}
2017-11-05 06:59:06 +01:00
function parse _message _embeds ( embeds ) {
var emb = [ ] ;
for ( var i = 0 ; i < embeds . length ; i ++ ) {
var disembed = embeds [ i ] ;
2017-11-21 00:10:06 +01:00
if ( $ . inArray ( disembed . type , [ "rich" , "link" , "video" ] ) == - 1 ) {
2017-11-05 06:59:06 +01:00
continue ;
}
disembed . toRenderFooter = false ;
if ( disembed . footer ) {
disembed . toRenderFooter = true ;
} else if ( disembed . timestamp ) {
disembed . toRenderFooter = true ;
}
disembed . footerVerticalBar = disembed . footer && disembed . timestamp ;
if ( disembed . timestamp ) {
disembed . formatted _timestamp = moment ( disembed . timestamp ) . format ( 'ddd MMM Do, YYYY [at] h:mm A' ) ;
}
if ( disembed . color ) {
disembed . hexColor = "#" + disembed . color . toString ( 16 ) ;
}
var template = $ ( '#mustache_richembed' ) . html ( ) ;
Mustache . parse ( template ) ;
var rendered = Mustache . render ( template , disembed ) ;
emb . push ( rendered ) ;
}
return emb ;
}
2017-04-14 08:10:13 +02:00
2017-08-22 08:57:30 +02:00
function fill _discord _messages ( messages , jumpscroll , replace = null ) {
2017-04-13 02:42:32 +02:00
if ( messages . length == 0 ) {
return last _message _id ;
}
var last = 0 ;
var template = $ ( '#mustache_usermessage' ) . html ( ) ;
Mustache . parse ( template ) ;
for ( var i = messages . length - 1 ; i >= 0 ; i -- ) {
var message = messages [ i ] ;
2017-10-09 19:56:00 +02:00
if ( message . author . avatar ) {
var avatar = generate _avatar _url ( message . author . id , message . author . avatar , message . content ) ;
} else {
var avatar = global _guest _icon ;
}
2017-04-13 02:42:32 +02:00
message = format _bot _message ( message ) ;
message = parse _message _time ( message ) ;
2017-09-06 08:34:51 +02:00
message . content = message . content . replaceAll ( "\\<" , "<" ) ;
message . content = message . content . replaceAll ( "\\>" , ">" ) ;
2017-06-09 10:22:22 +02:00
message . content = escapeHtml ( message . content ) ;
2017-11-06 03:57:46 +01:00
message = replace _message _mentions ( message ) ;
2017-11-05 07:09:05 +01:00
message = parse _message _attachments ( message ) ;
2017-08-10 03:00:14 +02:00
message . content = parse _message _markdown ( message . content ) ;
2017-11-01 07:31:44 +01:00
message = parse _channels _in _message ( message ) ;
2017-06-09 10:22:22 +02:00
message = parse _emoji _in _message ( message ) ;
2017-08-10 04:05:05 +02:00
var username = message . author . username ;
if ( message . author . nickname ) {
username = message . author . nickname ;
}
2017-09-24 06:17:06 +02:00
var rendered = Mustache . render ( template , { "id" : message . id , "full_timestamp" : message . formatted _timestamp , "time" : message . formatted _time , "username" : username , "discriminator" : message . author . discriminator , "avatar" : avatar , "content" : nl2br ( message . content ) } ) ;
2017-08-22 08:57:30 +02:00
if ( replace == null ) {
$ ( "#chatcontent" ) . append ( rendered ) ;
handle _last _message _mention ( ) ;
$ ( "#chatcontent p:last-child" ) . find ( ".blockcode" ) . find ( "br" ) . remove ( ) ; // Remove excessive breaks in codeblocks
2017-09-23 19:38:14 +02:00
render _code _highlighting ( $ ( "#chatcontent p:last-child" ) . find ( ".blockcode" ) ) ;
2017-10-09 06:47:51 +02:00
$ ( "#chatcontent .chatusername" ) . last ( ) . click ( function ( ) {
var discordid = $ ( this ) . parent ( ) . attr ( "discord_userid" ) ;
if ( discordid ) {
2017-12-07 07:49:32 +01:00
openUserCard ( discordid ) ;
2017-10-09 06:47:51 +02:00
}
} ) ;
2017-11-01 07:31:44 +01:00
$ ( "#chatcontent p:last-child" ) . find ( ".channellink" ) . click ( function ( ) {
select _channel ( $ ( this ) . attr ( "channelid" ) , true ) ;
} ) ;
2017-08-22 08:57:30 +02:00
} else {
replace . html ( $ ( rendered ) . html ( ) ) ;
replace . find ( ".blockcode" ) . find ( "br" ) . remove ( ) ;
2017-09-23 19:38:14 +02:00
render _code _highlighting ( replace . find ( ".blockcode" ) ) ;
2017-11-01 07:31:44 +01:00
replace . find ( ".channellink" ) . click ( function ( ) {
select _channel ( $ ( this ) . attr ( "channelid" ) , true ) ;
} ) ;
2017-08-22 08:57:30 +02:00
}
2017-11-05 06:59:06 +01:00
var embeds = parse _message _embeds ( message . embeds ) ;
$ ( "#discordmessage_" + message . id ) . parent ( ) . find ( "span.embeds" ) . text ( "" ) ;
for ( var j = 0 ; j < embeds . length ; j ++ ) {
$ ( "#discordmessage_" + message . id ) . parent ( ) . find ( "span.embeds" ) . append ( embeds [ j ] ) ;
}
2017-09-15 08:25:03 +02:00
var usrcachekey = username + "#" + message . author . discriminator ;
2017-09-15 09:15:51 +02:00
if ( usrcachekey . startsWith ( "(Titan Dev) " ) ) {
usrcachekey = usrcachekey . substr ( 12 ) ;
}
2017-09-15 08:25:03 +02:00
if ( ! ( usrcachekey in message _users _cache ) ) {
message _users _cache [ usrcachekey ] = { "data" : { } , "msgs" : [ ] } ;
}
message _users _cache [ usrcachekey ] [ "msgs" ] . push ( message . id ) ;
2017-04-13 02:42:32 +02:00
last = message . id ;
}
2017-11-13 02:26:00 +01:00
if ( replace == null ) {
play _notification _sound ( "new" ) ;
} else if ( $ ( "#chatcontent p:last-child.mentioned" ) . length ) {
play _notification _sound ( "mention" ) ;
}
2017-10-07 17:20:27 +02:00
if ( replace == null && jumpscroll ) {
2017-10-29 03:00:21 +01:00
if ( ! has _handled _noscroll ) {
has _handled _noscroll = true ;
Materialize . toast ( 'Continue scrolling to read on...' , 5000 ) ;
} else {
$ ( "html, body" ) . animate ( { scrollTop : $ ( document ) . height ( ) } , "slow" ) ;
}
2017-08-22 08:57:30 +02:00
}
2017-04-13 02:42:32 +02:00
$ ( '#chatcontent' ) . linkify ( {
target : "_blank"
2017-04-05 08:25:07 +02:00
} ) ;
2017-06-10 05:13:39 +02:00
$ ( '.tooltipped' ) . tooltip ( ) ;
2017-09-15 08:25:03 +02:00
process _message _users _cache ( ) ;
2017-04-13 02:42:32 +02:00
return last ;
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
function run _fetch _routine ( ) {
var channel _id = selected _channel ;
var fet ;
var jumpscroll ;
if ( last _message _id == null ) {
$ ( "#chatcontent" ) . empty ( ) ;
fet = fetch ( channel _id ) ;
jumpscroll = true ;
} else {
fet = fetch ( channel _id , last _message _id ) ;
2017-11-05 06:59:06 +01:00
jumpscroll = element _in _view ( $ ( '#discordmessage_' + last _message _id ) . parent ( ) ) ;
2017-04-13 02:42:32 +02:00
}
fet . done ( function ( data ) {
var status = data . status ;
2017-06-09 06:22:33 +02:00
if ( visitor _mode ) {
2017-08-10 04:05:05 +02:00
update _embed _userchip ( false , null , "Titan" , null , "0001" , null ) ;
2017-08-10 23:27:08 +02:00
update _change _username _modal ( ) ;
2017-06-09 06:22:33 +02:00
} else {
2017-08-10 04:05:05 +02:00
update _embed _userchip ( status . authenticated , status . avatar , status . username , status . nickname , status . user _id , status . discriminator ) ;
2017-08-10 23:27:08 +02:00
update _change _username _modal ( status . authenticated , status . username ) ;
2017-08-27 09:55:08 +02:00
current _user _discord _id = status . user _id ;
2017-06-09 06:22:33 +02:00
}
2017-04-13 02:42:32 +02:00
last _message _id = fill _discord _messages ( data . messages , jumpscroll ) ;
2017-06-09 06:22:33 +02:00
if ( ! visitor _mode && status . manage _embed ) {
2017-04-13 02:42:32 +02:00
$ ( "#administrate_link" ) . show ( ) ;
} else {
$ ( "#administrate_link" ) . hide ( ) ;
}
2017-08-20 21:56:54 +02:00
var guild = query _guild ( ) ;
guild . done ( function ( guildobj ) {
fill _channels ( guildobj . channels ) ;
fill _discord _members ( guildobj . discordmembers ) ;
fill _authenticated _users ( guildobj . embedmembers . authenticated ) ;
fill _unauthenticated _users ( guildobj . embedmembers . unauthenticated ) ;
$ ( "#instant-inv" ) . attr ( "href" , guildobj . instant _invite ) ;
} ) ;
2017-04-05 08:25:07 +02:00
} ) ;
2017-04-13 02:42:32 +02:00
fet . fail ( function ( data ) {
if ( data . status == 403 ) {
$ ( '#loginmodal' ) . modal ( 'open' ) ;
Materialize . toast ( 'Authentication error! You have been disconnected by the server.' , 10000 ) ;
} else if ( data . status == 401 ) {
$ ( '#loginmodal' ) . modal ( 'open' ) ;
Materialize . toast ( 'Session expired! You have been logged out.' , 10000 ) ;
2017-04-05 08:25:07 +02:00
}
2017-08-21 06:26:51 +02:00
setVisitorMode ( true ) ;
2017-04-13 02:42:32 +02:00
} ) ;
2017-04-05 08:25:07 +02:00
}
2017-09-15 08:25:03 +02:00
function process _message _users _cache ( ) {
var keys = Object . keys ( message _users _cache ) ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
var key = keys [ i ] ;
var hashpos = key . lastIndexOf ( "#" ) ;
var name = key . substring ( 0 , hashpos ) ;
var discriminator = key . substring ( hashpos + 1 ) ;
if ( name . startsWith ( "(Titan Dev) " ) ) {
name = name . substring ( 12 ) ;
}
var key _helper = name + "#" + discriminator ;
if ( jQuery . isEmptyObject ( message _users _cache [ key _helper ] [ "data" ] ) ) {
if ( socket ) {
socket . emit ( "lookup_user_info" , { "guild_id" : guild _id , "name" : name , "discriminator" : discriminator } ) ;
}
} else {
process _message _users _cache _helper ( key _helper , message _users _cache [ key _helper ] [ "data" ] ) ;
}
}
}
function process _message _users _cache _helper ( key , usr ) {
var msgs = message _users _cache [ key ] [ "msgs" ] ;
while ( msgs . length > 0 ) {
var element = $ ( "#discordmessage_" + msgs . pop ( ) ) ;
var parent = element . parent ( ) ;
if ( usr . color ) {
parent . find ( ".chatusername" ) . css ( "color" , "#" + usr . color ) ;
} else {
parent . find ( ".chatusername" ) . css ( "color" , null ) ;
}
2017-12-08 02:43:01 +01:00
if ( usr . stargazer ) {
parent . find ( ".chatusername" ) . addClass ( "stargazer" ) ;
}
2017-09-24 06:17:06 +02:00
if ( usr . avatar _url ) {
parent . attr ( "discord_userid" , usr . id ) ;
parent . find ( ".authoravatar" ) . prop ( "src" , usr . avatar _url ) ;
}
2017-09-15 08:25:03 +02:00
}
2017-10-20 09:05:18 +02:00
collapse _messages ( ) ;
2017-09-15 08:25:03 +02:00
}
2017-10-20 08:50:48 +02:00
function collapse _messages ( ) {
var allMessages = $ ( '[id^="discordmessage_"]' ) . parent ( ) ;
for ( var i = 1 ; i < allMessages . length ; i ++ ) {
var last = $ ( allMessages [ i - 1 ] ) ;
var current = $ ( allMessages [ i ] ) ;
2017-10-20 08:59:06 +02:00
if ( last . attr ( "discord_userid" ) == current . attr ( "discord_userid" ) && current . attr ( "discord_userid" ) ) {
2017-10-20 08:50:48 +02:00
current . addClass ( "collapsed" ) ;
} else {
current . removeClass ( "collapsed" ) ;
}
}
}
2017-04-14 08:10:13 +02:00
2017-08-10 04:05:05 +02:00
function update _embed _userchip ( authenticated , avatar , username , nickname , userid , discrim = null ) {
2017-04-13 02:42:32 +02:00
if ( authenticated ) {
$ ( "#currentuserimage" ) . show ( ) ;
$ ( "#currentuserimage" ) . attr ( "src" , avatar ) ;
2017-05-24 06:42:01 +02:00
$ ( "#curuser_name" ) . text ( username ) ;
$ ( "#curuser_discrim" ) . text ( "#" + discrim ) ;
2017-08-10 04:05:05 +02:00
current _username _discrim = "#" + discrim ;
2017-04-13 02:42:32 +02:00
} else {
$ ( "#currentuserimage" ) . hide ( ) ;
2017-05-24 06:42:01 +02:00
$ ( "#curuser_name" ) . text ( username ) ;
$ ( "#curuser_discrim" ) . text ( "#" + userid ) ;
2017-08-10 04:05:05 +02:00
current _username _discrim = "#" + userid ;
}
if ( nickname ) {
$ ( "#curuser_name" ) . text ( nickname ) ;
current _username _discrim = nickname + current _username _discrim ;
} else {
current _username _discrim = username + current _username _discrim ;
2017-04-13 02:42:32 +02:00
}
}
2017-08-10 23:27:08 +02:00
function update _change _username _modal ( authenticated = false , username = null ) {
if ( ! $ ( "#change_username_field" ) || $ ( "#change_username_field" ) . is ( ":focus" ) ) {
return ;
}
if ( authenticated || visitor _mode ) {
$ ( "#change_username_field" ) . attr ( "disabled" , true ) ;
$ ( "#change_username_field" ) . val ( "" ) ;
} else {
$ ( "#change_username_field" ) . attr ( "disabled" , false ) ;
$ ( "#change_username_field" ) . val ( username ) ;
}
}
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
$ ( "#discordlogin_btn" ) . click ( function ( ) {
lock _login _fields ( ) ;
wait _for _discord _login ( ) ;
} ) ;
2017-09-21 09:12:49 +02:00
2017-04-13 02:42:32 +02:00
$ ( "#custom_username_field" ) . keyup ( function ( event ) {
if ( event . keyCode == 13 ) {
if ( ! ( new RegExp ( /^[a-z\d\-_\s]+$/i ) . test ( $ ( this ) . val ( ) ) ) ) {
Materialize . toast ( 'Illegal username provided! Only alphanumeric, spaces, dashes, and underscores allowed in usernames.' , 10000 ) ;
return ;
}
if ( $ ( this ) . val ( ) . length >= 2 && $ ( this ) . val ( ) . length <= 32 ) {
2017-09-21 09:12:49 +02:00
$ ( "#custom_username_field" ) . blur ( ) ;
2017-11-04 03:58:26 +01:00
if ( unauth _captcha _enabled ) {
$ ( '#recaptchamodal' ) . modal ( 'open' ) ;
} else {
submit _unauthenticated _captcha ( ) ;
}
2017-04-13 02:42:32 +02:00
}
}
} ) ;
2017-09-21 09:12:49 +02:00
$ ( "#submit-unauthenticated-captcha-btn" ) . click ( function ( ) {
lock _login _fields ( ) ;
var usr = create _unauthenticated _user ( $ ( "#custom_username_field" ) . val ( ) , grecaptcha . getResponse ( ) ) ;
usr . done ( function ( data ) {
grecaptcha . reset ( ) ;
setVisitorMode ( false ) ;
initialize _embed ( ) ;
} ) ;
usr . fail ( function ( data ) {
if ( data . status == 429 ) {
Materialize . toast ( 'Sorry! You are allowed to log in as a guest three times in a span of 30 minutes.' , 10000 ) ;
} else if ( data . status == 403 ) {
Materialize . toast ( 'Authentication error! You have been banned.' , 10000 ) ;
} else if ( data . status == 406 ) {
Materialize . toast ( 'Illegal username provided! Only alphanumeric, spaces, dashes, and underscores allowed in usernames.' , 10000 ) ;
} else if ( data . status == 412 ) {
Materialize . toast ( "reCAPTCHA reponse has failed. Try again?" , 10000 ) ;
}
unlock _login _fields ( ) ;
setVisitorMode ( true ) ;
} ) ;
} ) ;
2017-08-10 23:27:08 +02:00
$ ( "#change_username_field" ) . keyup ( function ( event ) {
if ( event . keyCode == 13 ) {
$ ( this ) . blur ( ) ;
if ( ! ( new RegExp ( /^[a-z\d\-_\s]+$/i ) . test ( $ ( this ) . val ( ) ) ) ) {
Materialize . toast ( 'Illegal username provided! Only alphanumeric, spaces, dashes, and underscores allowed in usernames.' , 10000 ) ;
return ;
}
if ( ( $ ( this ) . val ( ) . length >= 2 && $ ( this ) . val ( ) . length <= 32 ) && $ ( "#curuser_name" ) . text ( ) != $ ( this ) . val ( ) ) {
var usr = change _unauthenticated _username ( $ ( this ) . val ( ) ) ;
usr . done ( function ( data ) {
Materialize . toast ( 'Username changed successfully!' , 10000 ) ;
2017-08-25 09:45:59 +02:00
if ( socket ) {
run _fetch _routine ( ) ;
socket . disconnect ( ) ;
2017-09-02 06:06:15 +02:00
socket = null ;
2017-08-25 09:45:59 +02:00
}
2017-09-02 06:06:15 +02:00
initiate _websockets ( ) ;
2017-08-10 23:27:08 +02:00
} ) ;
usr . fail ( function ( data ) {
if ( data . status == 429 ) {
2017-09-20 09:07:55 +02:00
Materialize . toast ( 'Sorry! You are allowed to change your username once every 10 minutes.' , 10000 ) ;
2017-08-10 23:27:08 +02:00
} else if ( data . status == 403 ) {
Materialize . toast ( 'Authentication error! You have been banned.' , 10000 ) ;
} else if ( data . status == 406 ) {
Materialize . toast ( 'Illegal username provided! Only alphanumeric, spaces, dashes, and underscores allowed in usernames.' , 10000 ) ;
} else {
Materialize . toast ( 'Something unexpected happened! Error code of ' + data . status , 10000 ) ;
}
} ) ;
}
}
} ) ;
2017-09-01 09:28:44 +02:00
$ ( "#messagebox" ) . keyup ( function ( event ) {
if ( event . keyCode == 16 ) {
shift _pressed = false ;
}
} ) ;
2017-04-14 08:10:13 +02:00
2017-09-01 09:28:44 +02:00
$ ( "#messagebox" ) . keydown ( function ( event ) {
2017-04-13 02:42:32 +02:00
if ( $ ( this ) . val ( ) . length == 1 ) {
$ ( this ) . val ( $ . trim ( $ ( this ) . val ( ) ) ) ;
}
2017-09-01 09:28:44 +02:00
if ( event . keyCode == 16 ) {
shift _pressed = true ;
}
if ( event . keyCode == 13 && ! shift _pressed && $ ( this ) . val ( ) . length >= 1 && $ ( this ) . val ( ) . length <= 350 ) {
2017-04-13 02:42:32 +02:00
$ ( this ) . val ( $ . trim ( $ ( this ) . val ( ) ) ) ;
$ ( this ) . blur ( ) ;
$ ( "#messagebox" ) . attr ( 'readonly' , true ) ;
var funct = post ( selected _channel , $ ( this ) . val ( ) ) ;
funct . done ( function ( data ) {
$ ( "#messagebox" ) . val ( "" ) ;
} ) ;
funct . fail ( function ( data ) {
Materialize . toast ( 'Failed to send message.' , 10000 ) ;
2017-05-13 18:19:19 +02:00
if ( data . responseJSON ) {
for ( var i = 0 ; i < data . responseJSON . illegal _reasons . length ; i ++ ) {
Materialize . toast ( data . responseJSON . illegal _reasons [ i ] , 10000 ) ;
}
2017-05-09 03:39:22 +02:00
}
2017-04-13 02:42:32 +02:00
} ) ;
funct . catch ( function ( data ) {
if ( data . status == 429 ) {
2017-08-27 23:48:45 +02:00
Materialize . toast ( 'You are sending messages too fast! 1 message per 5 seconds' , 10000 ) ;
2017-04-13 02:42:32 +02:00
}
} ) ;
funct . always ( function ( ) {
$ ( "#messagebox" ) . attr ( 'readonly' , false ) ;
2017-08-05 23:41:19 +02:00
$ ( "#messagebox" ) . focus ( ) ;
2017-04-13 02:42:32 +02:00
} ) ;
}
} ) ;
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
$ ( '#guild-btn' ) . sideNav ( {
menuWidth : 300 , // Default is 300
edge : 'left' , // Choose the horizontal origin
closeOnClick : true , // Closes side-nav on <a> clicks, useful for Angular/Meteor
draggable : true // Choose whether you can drag to open on touch screens
}
) ;
2017-04-14 08:10:13 +02:00
2017-04-13 02:42:32 +02:00
$ ( '#members-btn' ) . sideNav ( {
menuWidth : 300 , // Default is 300
edge : 'right' , // Choose the horizontal origin
draggable : true // Choose whether you can drag to open on touch screens
}
) ;
2017-06-15 21:58:15 +02:00
// enter konami code into the embed page for some ponies action!
cheet ( '↑ ↑ ↓ ↓ ← → ← → b a' , function ( ) {
// basically copied and pasted of browser ponies bookmarklet
( function ( srcs , cfg ) { var cbcount = 1 ; var callback = function ( ) { -- cbcount ; if ( cbcount === 0 ) { BrowserPonies . setBaseUrl ( cfg . baseurl ) ; if ( ! BrowserPoniesBaseConfig . loaded ) { BrowserPonies . loadConfig ( BrowserPoniesBaseConfig ) ; BrowserPoniesBaseConfig . loaded = true ; } BrowserPonies . loadConfig ( cfg ) ; if ( ! BrowserPonies . running ( ) ) BrowserPonies . start ( ) ; } } ; if ( typeof ( BrowserPoniesConfig ) === "undefined" ) { window . BrowserPoniesConfig = { } ; } if ( typeof ( BrowserPoniesBaseConfig ) === "undefined" ) { ++ cbcount ; BrowserPoniesConfig . onbasecfg = callback ; } if ( typeof ( BrowserPonies ) === "undefined" ) { ++ cbcount ; BrowserPoniesConfig . oninit = callback ; } var node = ( document . body || document . documentElement || document . getElementsByTagName ( 'head' ) [ 0 ] ) ; for ( var id in srcs ) { if ( document . getElementById ( id ) ) continue ; if ( node ) { var s = document . createElement ( 'script' ) ; s . type = 'text/javascript' ; s . id = id ; s . src = srcs [ id ] ; node . appendChild ( s ) ; } else { document . write ( '\u003cscript type="text/javscript" src="' + srcs [ id ] + '" id="' + id + '"\u003e\u003c/script\u003e' ) ; } } callback ( ) ; } ) ( { "browser-ponies-script" : "https://panzi.github.io/Browser-Ponies/browserponies.js" , "browser-ponies-config" : "https://panzi.github.io/Browser-Ponies/basecfg.js" } , { "baseurl" : "https://panzi.github.io/Browser-Ponies/" , "fadeDuration" : 500 , "volume" : 1 , "fps" : 25 , "speed" : 3 , "audioEnabled" : false , "showFps" : false , "showLoadProgress" : true , "speakProbability" : 0.1 , "spawn" : { "applejack" : 1 , "fluttershy" : 1 , "pinkie pie" : 1 , "rainbow dash" : 1 , "rarity" : 1 , "twilight sparkle" : 1 } } ) ;
} ) ;
2017-08-20 21:56:54 +02:00
function initiate _websockets ( ) {
2017-08-21 06:26:51 +02:00
if ( socket ) {
return ;
}
socket = io . connect ( location . protocol + '//' + document . domain + ':' + location . port + "/gateway" , { path : '/gateway' , transports : [ 'websocket' ] } ) ;
socket . on ( 'connect' , function ( ) {
2017-08-22 08:57:30 +02:00
socket . emit ( 'identify' , { "guild_id" : guild _id , "visitor_mode" : visitor _mode } ) ;
2017-09-15 08:25:03 +02:00
process _message _users _cache ( ) ;
2017-08-20 21:56:54 +02:00
} ) ;
2017-08-21 06:26:51 +02:00
socket . on ( "disconnect" , function ( ) {
2017-09-02 06:06:15 +02:00
2017-08-21 06:26:51 +02:00
} ) ;
socket . on ( "revoke" , function ( ) {
2017-09-02 06:06:15 +02:00
socket . disconnect ( ) ;
socket = null ;
2017-08-21 06:26:51 +02:00
$ ( '#loginmodal' ) . modal ( 'open' ) ;
primeEmbed ( ) ;
Materialize . toast ( 'Authentication error! You have been disconnected by the server.' , 10000 ) ;
} ) ;
2017-08-22 08:57:30 +02:00
socket . on ( "embed_user_connect" , function ( msg ) {
if ( msg . unauthenticated ) {
for ( var i = 0 ; i < unauthenticated _users _list . length ; i ++ ) {
var item = unauthenticated _users _list [ i ] ;
if ( item . username == msg . username && item . discriminator == msg . discriminator ) {
return ;
}
}
unauthenticated _users _list . push ( msg ) ;
fill _unauthenticated _users ( unauthenticated _users _list ) ;
} else {
for ( var i = 0 ; i < authenticated _users _list . length ; i ++ ) {
var item = authenticated _users _list [ i ] ;
if ( item . id == msg . id ) {
return ;
}
}
authenticated _users _list . push ( msg ) ;
fill _authenticated _users ( authenticated _users _list ) ;
}
} ) ;
socket . on ( "embed_user_disconnect" , function ( msg ) {
if ( msg . unauthenticated ) {
for ( var i = 0 ; i < unauthenticated _users _list . length ; i ++ ) {
var item = unauthenticated _users _list [ i ] ;
if ( item . username == msg . username && item . discriminator == msg . discriminator ) {
unauthenticated _users _list . splice ( i , 1 ) ;
fill _unauthenticated _users ( unauthenticated _users _list ) ;
return ;
}
}
} else {
for ( var i = 0 ; i < authenticated _users _list . length ; i ++ ) {
var item = authenticated _users _list [ i ] ;
if ( item . id == msg . id ) {
authenticated _users _list . splice ( i , 1 ) ;
fill _authenticated _users ( authenticated _users _list ) ;
return ;
}
}
}
} ) ;
2017-08-21 06:26:51 +02:00
socket . on ( "MESSAGE_CREATE" , function ( msg ) {
var thismsgchan = msg . channel _id ;
if ( selected _channel != thismsgchan ) {
return ;
}
2017-11-05 06:59:06 +01:00
var jumpscroll = element _in _view ( $ ( '#discordmessage_' + last _message _id ) . parent ( ) ) ;
2017-08-21 06:26:51 +02:00
last _message _id = fill _discord _messages ( [ msg ] , jumpscroll ) ;
2017-08-20 21:56:54 +02:00
} ) ;
2017-08-22 08:57:30 +02:00
socket . on ( "MESSAGE_DELETE" , function ( msg ) {
var msgchan = msg . channel _id ;
if ( selected _channel != msgchan ) {
return ;
}
$ ( "#discordmessage_" + msg . id ) . parent ( ) . remove ( ) ;
last _message _id = $ ( "#chatcontent" ) . find ( "[id^=discordmessage_]" ) . last ( ) . attr ( 'id' ) . substring ( 15 ) ;
} ) ;
socket . on ( "MESSAGE_UPDATE" , function ( msg ) {
var msgelem = $ ( "#discordmessage_" + msg . id ) ;
if ( msgelem . length == 0 ) {
return ;
}
var msgelem _parent = msgelem . parent ( ) ;
fill _discord _messages ( [ msg ] , false , msgelem _parent ) ;
} ) ;
socket . on ( "GUILD_MEMBER_ADD" , function ( usr ) {
if ( usr . status != "offline" ) {
discord _users _list . push ( usr ) ;
fill _discord _members ( discord _users _list ) ;
}
} ) ;
socket . on ( "GUILD_MEMBER_UPDATE" , function ( usr ) {
2017-08-27 09:55:08 +02:00
if ( usr . id == current _user _discord _id ) {
update _socket _channels ( ) ;
socket . emit ( "current_user_info" , { "guild_id" : guild _id } ) ;
}
2017-08-22 08:57:30 +02:00
for ( var i = 0 ; i < discord _users _list . length ; i ++ ) {
if ( usr . id == discord _users _list [ i ] . id ) {
2017-08-22 09:53:41 +02:00
discord _users _list . splice ( i , 1 ) ;
if ( usr . status != "offline" ) {
discord _users _list . push ( usr ) ;
2017-08-22 08:57:30 +02:00
}
2017-08-22 09:53:41 +02:00
fill _discord _members ( discord _users _list ) ;
return ;
2017-08-22 08:57:30 +02:00
}
}
discord _users _list . push ( usr ) ;
fill _discord _members ( discord _users _list ) ;
} ) ;
socket . on ( "GUILD_MEMBER_REMOVE" , function ( usr ) {
for ( var i = 0 ; i < discord _users _list . length ; i ++ ) {
if ( usr . id == discord _users _list [ i ] . id ) {
discord _users _list . splice ( i , 1 ) ;
fill _discord _members ( discord _users _list ) ;
return ;
}
}
} ) ;
2017-08-22 09:53:41 +02:00
socket . on ( "GUILD_EMOJIS_UPDATE" , function ( emo ) {
emoji _store = emo ;
} ) ;
2017-08-25 08:37:14 +02:00
2017-08-27 10:04:50 +02:00
socket . on ( "GUILD_UPDATE" , function ( guil ) {
$ ( "#guild_name" ) . text ( guil . name ) ;
if ( guil . icon ) {
$ ( "#guild_icon" ) . attr ( "src" , guil . icon _url ) ;
$ ( "#guild_icon" ) . show ( ) ;
} else {
$ ( "#guild_icon" ) . hide ( ) ;
}
} ) ;
2017-08-25 08:37:14 +02:00
socket . on ( "CHANNEL_DELETE" , function ( chan ) {
for ( var i = 0 ; i < guild _channels _list . length ; i ++ ) {
var thatchannel = guild _channels _list [ i ] ;
if ( thatchannel . channel . id == chan . id ) {
guild _channels _list . splice ( i , 1 ) ;
fill _channels ( guild _channels _list ) ;
return ;
}
}
} ) ;
socket . on ( "CHANNEL_UPDATE" , function ( chan ) {
update _socket _channels ( ) ;
} ) ;
socket . on ( "CHANNEL_CREATE" , function ( chan ) {
update _socket _channels ( ) ;
} ) ;
socket . on ( "GUILD_ROLE_UPDATE" , function ( chan ) {
update _socket _channels ( ) ;
} ) ;
socket . on ( "GUILD_ROLE_DELETE" , function ( chan ) {
update _socket _channels ( ) ;
} ) ;
socket . on ( "channel_list" , function ( chans ) {
fill _channels ( chans ) ;
for ( var i = 0 ; i < chans . length ; i ++ ) {
var thischan = chans [ i ] ;
if ( thischan . channel . id == selected _channel ) {
$ ( "#channeltopic" ) . text ( thischan . channel . topic ) ;
}
}
} ) ;
2017-08-26 01:19:13 +02:00
socket . on ( "current_user_info" , function ( usr ) {
update _embed _userchip ( true , usr . avatar , usr . username , usr . nickname , usr . userid , usr . discriminator ) ;
} ) ;
2017-09-15 08:25:03 +02:00
socket . on ( "lookup_user_info" , function ( usr ) {
var key = usr . name + "#" + usr . discriminator ;
var cache = message _users _cache [ key ] ;
if ( ! cache ) {
return ;
}
cache [ "data" ] = usr ;
process _message _users _cache _helper ( key , usr ) ;
} ) ;
2017-09-24 06:17:06 +02:00
socket . on ( "guest_icon_change" , function ( icon ) {
global _guest _icon = icon . guest _icon ;
} ) ;
2017-08-20 21:56:54 +02:00
}
2017-08-21 06:26:51 +02:00
2017-08-25 08:37:14 +02:00
function update _socket _channels ( ) {
2017-08-21 06:26:51 +02:00
if ( ! socket ) {
return ;
}
2017-08-25 08:37:14 +02:00
socket . emit ( "channel_list" , { "guild_id" : guild _id , "visitor_mode" : visitor _mode } ) ;
}
function send _socket _heartbeat ( ) {
if ( socket ) {
socket . emit ( "heartbeat" , { "guild_id" : guild _id , "visitor_mode" : visitor _mode } ) ;
}
2017-08-21 06:26:51 +02:00
}
2017-04-13 02:42:32 +02:00
} ) ( ) ;
2017-09-21 09:12:49 +02:00
function submit _unauthenticated _captcha ( ) { // To be invoked when recaptcha is completed
$ ( '#recaptchamodal' ) . modal ( 'close' ) ;
$ ( "#submit-unauthenticated-captcha-btn" ) . click ( ) ;
}