/* global $ */ /* global Materialize */ /* global Mustache */ /* global guild_id */ /* global bot_client_id */ /* global moment */ var logintimer; // timer to keep track of user inactivity after hitting login var fetchtimeout; // fetch routine timer var last_message_id; // last message tracked var selected_channel = guild_id; // user selected channel, defaults to #general channel 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(); if (fullyInView === true) { return ((pageTop < elementTop) && (pageBottom > elementBottom)); } else { return ((elementTop <= pageBottom) && (elementBottom >= pageTop)); } } function query_guild() { var funct = $.ajax({ dataType: "json", url: "/api/query_guild", data: {"guild_id": guild_id} }); return funct.promise(); } function create_authenticated_user() { var funct = $.ajax({ method: "POST", dataType: "json", url: "/api/create_authenticated_user", data: {"guild_id": guild_id} }); return funct.promise(); } function create_unauthenticated_user(username) { var funct = $.ajax({ method: "POST", dataType: "json", url: "/api/create_unauthenticated_user", data: {"username": username, "guild_id": guild_id} }); return funct.promise(); } function fetch(channel_id, after=null) { var funct = $.ajax({ method: "GET", dataType: "json", url: "/api/fetch", data: {"guild_id": guild_id,"channel_id": channel_id, "after": after} }); return funct.promise(); } 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(); } $(function(){ $("#loginmodal").modal({ dismissible: false, // 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 } ); var guild = query_guild(); guild.fail(function() { $('#loginmodal').modal('open'); }); guild.done(function(data) { initialize_embed(data); //$('#loginmodal').modal('open'); }); }); function lock_login_fields() { $("#loginProgress").show(); $("#discordlogin_btn").attr("disabled",true); $("#custom_username_field").prop("disabled",true); logintimer = setTimeout(function() { unlock_login_fields(); }, 60000); } function unlock_login_fields() { $("#loginProgress").hide(); $("#discordlogin_btn").attr("disabled",false); $("#custom_username_field").prop("disabled",false); clearTimeout(logintimer); } function initialize_embed(guildobj) { $('#loginmodal').modal('close'); unlock_login_fields(); if (guildobj === undefined) { var guild = query_guild(); guild.done(function(data) { prepare_guild(data); }); } else { prepare_guild(guildobj); } } function prepare_guild(guildobj) { fill_channels(guildobj.channels); fill_discord_members(guildobj.discordmembers); fill_authenticated_users(guildobj.embedmembers.authenticated); fill_unauthenticated_users(guildobj.embedmembers.unauthenticated); run_fetch_routine(); } function fill_channels(channels) { var template = $('#mustache_channellistings').html(); Mustache.parse(template); $("#channels-list").empty(); for (var i = 0; i < channels.length; i++) { var chan = channels[i]; if (chan.read) { var rendered = Mustache.render(template, {"channelid": chan.channel.id, "channelname": chan.channel.name}); $("#channels-list").append(rendered); if (chan.channel.id == selected_channel) { if (chan.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(chan.channel.topic); } } } $("#channel-"+selected_channel).parent().addClass("active"); } function fill_discord_members(discordmembers) { var template = $('#mustache_authedusers').html(); Mustache.parse(template); $("#discord-members").empty(); for (var i = 0; i < discordmembers.length; i++) { var member = discordmembers[i]; var rendered = Mustache.render(template, {"id": member.id, "username": member.username, "avatar": member.avatar_url}); $("#discord-members").append(rendered); } } function fill_authenticated_users(users) { var template = $('#mustache_authedusers').html(); Mustache.parse(template); $("#embed-discord-members").empty(); for (var i = 0; i < users.length; i++) { var member = users[i]; var rendered = Mustache.render(template, {"id": member.id, "username": member.username, "avatar": member.avatar_url}); $("#embed-discord-members").append(rendered); } } function fill_unauthenticated_users(users) { var template = $('#mustache_unauthedusers').html(); Mustache.parse(template); $("#embed-unauth-users").empty(); 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); } } function wait_for_discord_login() { _wait_for_discord_login(0); } function _wait_for_discord_login(index) { setTimeout(function() { var usr = create_authenticated_user(); usr.done(function(data) { initialize_embed(); return; }); usr.fail(function(data) { if (data.status == 403) { Materialize.toast('Authentication error! You have been banned.', 10000); } else if (index < 10) { _wait_for_discord_login(index + 1); } }); }, 5000); } function select_channel(channel_id) { if (selected_channel != channel_id) { selected_channel = channel_id; last_message_id = null; $("#channels-list > li.active").removeClass("active"); $("#channel-"+selected_channel).parent().addClass("active"); clearTimeout(fetchtimeout); run_fetch_routine(); } } function replace_message_mentions(message) { var mentions = message.mentions; for (var i = 0; i < mentions.length; i++) { var mention = mentions[i]; message.content = message.content.replace(new RegExp("<@" + mention.id + ">", 'g'), "@" + mention.username + "#" + mention.discriminator); message.content = message.content.replace(new RegExp("<@!" + mention.id + ">", 'g'), "@" + mention.username + "#" + mention.discriminator); } return message; } function getPosition(string, subString, index) { return string.split(subString, index).join(subString).length; } 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); message.content = message.content.substring(usernamefield.length+7); message.author.username = usernamefield.split("#")[0]; message.author.discriminator = usernamefield.split("#")[1]; } return message; } function parse_message_time(message) { var mome = moment(message.timestamp); message.formatted_timestamp = mome.toDate().toString(); message.formatted_time = mome.format("h:mm A"); return message; } function parse_message_attachments(message) { for (var i = 0; i < message.attachments.length; i++) { var attach = ""; if (message.content.length != 0) { attach = " "; } attach += message.attachments[i].url; message.content += attach; } return message; } function fill_discord_messages(messages, jumpscroll) { 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]; message = replace_message_mentions(message); message = format_bot_message(message); message = parse_message_time(message); message = parse_message_attachments(message); var rendered = Mustache.render(template, {"id": message.id, "full_timestamp": message.formatted_timestamp, "time": message.formatted_time, "username": message.author.username, "discriminator": message.author.discriminator, "content": message.content}); $("#chatcontent").append(rendered); last = message.id; } $("html, body").animate({ scrollTop: $(document).height() }, "slow"); return last; } 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); jumpscroll = element_in_view($('#discordmessage_'+last_message_id), true); } fet.done(function(data) { var status = data.status; update_embed_userchip(status.authenticated, status.avatar, status.username, status.user_id); last_message_id = fill_discord_messages(data.messages, jumpscroll); if (status.manage_embed) { $("#administrate_link").show(); } else { $("#administrate_link").hide(); } 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); fetchtimeout = setTimeout(run_fetch_routine, 10000); }); }); 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); } }); fet.catch(function(data) { if (!(data.status != 403 || data.status != 401)) { fetchtimeout = setTimeout(run_fetch_routine, 10000); } }); } function update_embed_userchip(authenticated, avatar, username, userid) { if (authenticated) { $("#currentuserimage").show(); $("#currentuserimage").attr("src", avatar); $("#currentusername").text(username); } else { $("#currentuserimage").hide(); $("#currentusername").text(username + "#" + userid); } } $("#discordlogin_btn").click(function() { lock_login_fields(); wait_for_discord_login(); }); $("#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) { lock_login_fields(); var usr = create_unauthenticated_user($(this).val()); usr.done(function(data) { initialize_embed(); }); usr.fail(function(data) { if (data.status == 429) { Materialize.toast('Sorry! You are allowed to log in as a guest once every 15 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); } unlock_login_fields(); }) } } }); $("#messagebox").keyup(function(event){ if ($(this).val().length == 1) { $(this).val($.trim($(this).val())); } if(event.keyCode == 13 && $(this).val().length >= 1 && $(this).val().length <= 350) { $(this).val($.trim($(this).val())); $(this).blur(); $("#messagebox").attr('readonly', true); var funct = post(selected_channel, $(this).val()); funct.done(function(data) { $("#messagebox").val(""); clearTimeout(fetchtimeout); run_fetch_routine(); }); funct.fail(function(data) { Materialize.toast('Failed to send message.', 10000); }); funct.catch(function(data) { if (data.status == 429) { Materialize.toast('You are sending messages too fast! 1 message per 10 seconds', 10000); } }); funct.always(function() { $("#messagebox").attr('readonly', false); }) } }); $('#guild-btn').sideNav({ menuWidth: 300, // Default is 300 edge: 'left', // Choose the horizontal origin closeOnClick: true, // Closes side-nav on clicks, useful for Angular/Meteor draggable: true // Choose whether you can drag to open on touch screens } ); $('#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 } );