diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 0c8fc84f06..81155638f8 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -91,12 +91,9 @@ var ajaxify = {}; ajaxify.enable(); }); + function exec_body_scripts(body_el) { - //http://stackoverflow.com/questions/2592092/executing-script-elements-inserted-with-innerhtml - // Finds and executes scripts in a newly added element's body. - // Needed since innerHTML does not run scripts. - // - // Argument body_el is an element in the dom. + // modified from http://stackoverflow.com/questions/2592092/executing-script-elements-inserted-with-innerhtml function nodeName(elem, name) { return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); @@ -110,35 +107,38 @@ var ajaxify = {}; script.type = "text/javascript"; try { - // doesn't work on ie... script.appendChild(document.createTextNode(data)); } catch(e) { - // IE has funky script nodes script.text = data; } + if (elem.src) { + script.src = elem.src; + } + head.insertBefore(script, head.firstChild); head.removeChild(script); }; - // main section of function var scripts = [], - script, - children_nodes = body_el.childNodes, - child, - i; + script, + children_nodes = body_el.childNodes, + child, + i; for (i = 0; children_nodes[i]; i++) { - child = children_nodes[i]; - if (nodeName(child, "script" ) && - (!child.type || child.type.toLowerCase() === "text/javascript")) { - scripts.push(child); - } + child = children_nodes[i]; + if (nodeName(child, "script" ) && + (!child.type || child.type.toLowerCase() === "text/javascript")) { + scripts.push(child); + } } for (i = 0; scripts[i]; i++) { script = scripts[i]; - if (script.parentNode) {script.parentNode.removeChild(script);} + if (script.parentNode) { + script.parentNode.removeChild(script); + } evalScript(scripts[i]); } }; diff --git a/public/src/forum/account.js b/public/src/forum/account.js new file mode 100644 index 0000000000..edc08ed60d --- /dev/null +++ b/public/src/forum/account.js @@ -0,0 +1,42 @@ +(function() { + var yourid = templates.get('yourid'), + theirid = templates.get('theirid'); + + var isFriend = {isFriend}; + + $(document).ready(function() { + + var rep = $('#reputation'); + rep.html(app.addCommas(rep.html())); + + var postcount = $('#postcount'); + postcount.html(app.addCommas(postcount.html())); + + var editLink = $('#editLink'); + var addFriendBtn = $('#add-friend-btn'); + + + if( yourid !== theirid) { + editLink.hide(); + if(isFriend) + addFriendBtn.hide(); + else + addFriendBtn.show(); + } + else { + addFriendBtn.hide(); + } + + addFriendBtn.on('click', function() { + $.post('/users/addfriend', {uid: theirid}, + function(data) { + addFriendBtn.remove(); + $('#user-action-alert').html('Friend Added!').show(); + } + ); + return false; + }); + + }); + +}()); \ No newline at end of file diff --git a/public/src/forum/accountedit.js b/public/src/forum/accountedit.js new file mode 100644 index 0000000000..2978ad5576 --- /dev/null +++ b/public/src/forum/accountedit.js @@ -0,0 +1,218 @@ + + +var gravatarPicture = templates.get('gravatarpicture'); +var uploadedPicture = templates.get('uploadedpicture'); + +$(document).ready(function() { + + + + $('#uploadForm').submit(function() { + status('uploading the file ...'); + + $('#upload-progress-bar').css('width', '0%'); + $('#upload-progress-box').show(); + + if(!$('#userPhotoInput').val()) { + error('select an image to upload!'); + return false; + } + + $(this).ajaxSubmit({ + + error: function(xhr) { + error('Error: ' + xhr.status); + }, + + uploadProgress : function(event, position, total, percent) { + $('#upload-progress-bar').css('width', percent+'%'); + }, + + + success: function(response) { + if(response.error) { + error(response.error); + return; + } + + var imageUrlOnServer = response.path; + + $('#user-current-picture').attr('src', imageUrlOnServer); + $('#user-uploaded-picture').attr('src', imageUrlOnServer); + + uploadedPicture = imageUrlOnServer; + + setTimeout(function() { + hideAlerts(); + $('#upload-picture-modal').modal('hide'); + }, 750); + + socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); + success('File uploaded successfully!'); + } + }); + + return false; + }); + + function hideAlerts() { + $('#alert-status').hide(); + $('#alert-success').hide(); + $('#alert-error').hide(); + $('#upload-progress-box').hide(); + } + + function status(message) { + hideAlerts(); + $('#alert-status').text(message).show(); + } + + function success(message) { + hideAlerts(); + $('#alert-success').text(message).show(); + } + + function error(message) { + hideAlerts(); + $('#alert-error').text(message).show(); + } + + function changeUserPicture(type) { + var userData = { + uid: $('#inputUID').val(), + type: type + }; + + $.post('/users/changepicture', + userData, + function(data) { + socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); + } + ); + } + + var selectedImageType = ''; + + $('#submitBtn').on('click',function(){ + + var userData = { + uid:$('#inputUID').val(), + email:$('#inputEmail').val(), + fullname:$('#inputFullname').val(), + website:$('#inputWebsite').val(), + birthday:$('#inputBirthday').val(), + location:$('#inputLocation').val(), + signature:$('#inputSignature').val(), + }; + + $.post('/users/doedit', + userData, + function(data) { + if(data.error) { + app.alert({ + 'alert_id': 'user_profile_updated', + type: 'error', + title: 'Profile Update Error', + message: data.error, + timeout: 2000 + }); + return; + } + + app.alert({ + 'alert_id': 'user_profile_updated', + type: 'success', + title: 'Profile Updated', + message: 'Your profile has been updated successfully', + timeout: 2000 + }); + } + ); + return false; + }); + + function updateImages() { + var currentPicture = $('#user-current-picture').attr('src'); + + if(gravatarPicture) { + $('#user-gravatar-picture').attr('src', gravatarPicture); + $('#gravatar-box').show(); + } + else + $('#gravatar-box').hide(); + + if(uploadedPicture) { + $('#user-uploaded-picture').attr('src', uploadedPicture); + $('#uploaded-box').show(); + } + else + $('#uploaded-box').hide(); + + + if(currentPicture == gravatarPicture) + $('#gravatar-box .icon-ok').show(); + else + $('#gravatar-box .icon-ok').hide(); + + if(currentPicture == uploadedPicture) + $('#uploaded-box .icon-ok').show(); + else + $('#uploaded-box .icon-ok').hide(); + } + + + $('#changePictureBtn').on('click', function() { + selectedImageType = ''; + updateImages(); + + $('#change-picture-modal').modal('show'); + + return false; + }); + + $('#gravatar-box').on('click', function(){ + $('#gravatar-box .icon-ok').show(); + $('#uploaded-box .icon-ok').hide(); + selectedImageType = 'gravatar'; + }); + + $('#uploaded-box').on('click', function(){ + $('#gravatar-box .icon-ok').hide(); + $('#uploaded-box .icon-ok').show(); + selectedImageType = 'uploaded'; + }); + + $('#savePictureChangesBtn').on('click', function() { + $('#change-picture-modal').modal('hide'); + + if(selectedImageType) { + changeUserPicture(selectedImageType); + + if(selectedImageType == 'gravatar') + $('#user-current-picture').attr('src', gravatarPicture); + else if(selectedImageType == 'uploaded') + $('#user-current-picture').attr('src', uploadedPicture); + } + + }); + + $('#upload-picture-modal').on('hide', function() { + $('#userPhotoInput').val(''); + }); + + $('#uploadPictureBtn').on('click', function(){ + + $('#change-picture-modal').modal('hide'); + $('#upload-picture-modal').modal('show'); + + hideAlerts(); + + return false; + }); + + $('#pictureUploadSubmitBtn').on('click', function() { + $('#uploadForm').submit(); + }); + + +}); \ No newline at end of file diff --git a/public/src/forum/category.js b/public/src/forum/category.js new file mode 100644 index 0000000000..74aa54b037 --- /dev/null +++ b/public/src/forum/category.js @@ -0,0 +1,78 @@ +(function() { + var cid = templates.get('category_id'), + room = 'category_' + cid; + + app.enter_room(room); + + var new_post = document.getElementById('new_post'); + new_post.onclick = function() { + app.open_post_window('topic', {category_id}); + } + + ajaxify.register_events([ + 'event:new_topic' + ]); + + if (jQuery('.category-item').length == 0) { + jQuery('#topics-container, .category-sidebar').hide(); + jQuery('#category-no-topics').show(); + } + + socket.on('event:new_topic', function(data) { + var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: [data] }), + topic = document.createElement('div'), + container = document.getElementById('topics-container'), + topics = document.querySelectorAll('#topics-container a'), + numTopics = topics.length, + x; + + jQuery('#topics-container, .category-sidebar').show(); + jQuery('#category-no-topics').hide(); + + topic.innerHTML = html; + if (numTopics > 0) { + for(x=0;x<numTopics;x++) { + if (topics[x].querySelector('.icon-pushpin')) continue; + container.insertBefore(topic.querySelector('a'), topics[x]); + $(topic).hide().fadeIn('slow'); + break; + } + } else { + container.insertBefore(topic.querySelector('a'), null); + $(topic).hide().fadeIn('slow'); + } + + // jQuery('<div></div>').appendTo("#topics-container").hide().append(html).fadeIn('slow'); + // set_up_posts(uniqueid); + }); + + + + socket.emit('api:categories.getRecentReplies', cid); + socket.on('api:categories.getRecentReplies', function(replies) { + if (replies === false) { + return; + } + + var users = replies.users, + posts = replies.posts, + recent_replies = document.getElementById('category_recent_replies'); + + recent_replies.innerHTML = ''; + for (var i=0, ii=posts.pids.length; i<ii; i++) { + var a = document.createElement('a'), + ul = document.createElement('ul'), + username = users[posts.uid[i]].username, + picture = users[posts.uid[i]].picture; + + //temp until design finalized + ul.innerHTML = '<li><img title="' + username + '" style="width: 48px; height: 48px; /*temporary*/" src="' + picture + '" class="" />' + + '<p><strong>' + username + '</strong>: ' + posts.content[i] + '</p><span>posted ' + utils.relativeTime(posts.timestamp[i]) + ' ago</span></li>'; + + a.appendChild(ul); + recent_replies.appendChild(a); + } + + }); + +})(); \ No newline at end of file diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js new file mode 100644 index 0000000000..79562a60f5 --- /dev/null +++ b/public/src/forum/footer.js @@ -0,0 +1,124 @@ +(function() { + var num_users = document.getElementById('number_of_users'), + latest_user = document.getElementById('latest_user'), + active_users = document.getElementById('active_users'), + user_label = document.getElementById('user_label'), + active_record = document.getElementById('active_record'), + right_menu = document.getElementById('right-menu'); + + socket.emit('user.count', {}); + socket.on('user.count', function(data) { + num_users.innerHTML = "We currently have <b>" + data.count + "</b> registered users."; + }); + socket.emit('user.latest', {}); + socket.on('user.latest', function(data) { + if (data.username == '') { + latest_user.innerHTML = ''; + } else { + latest_user.innerHTML = "The most recent user to register is <b><a href='/users/"+data.username+"'>" + data.username + "</a></b>."; + } + }); + socket.emit('api:user.active.get'); + socket.on('api:user.active.get', function(data) { + var plural_users = parseInt(data.users) !== 1, + plural_anon = parseInt(data.anon) !== 1; + + active_users.innerHTML = 'There ' + (plural_users ? 'are' : 'is') + ' <strong>' + data.users + '</strong> user' + (plural_users ? 's' : '') + ' and <strong>' + data.anon + '</strong> guest' + (plural_anon ? 's' : '') + ' online'; + }); + socket.emit('api:user.active.get_record'); + socket.on('api:user.active.get_record', function(data) { + active_record.innerHTML = "most users ever online was <strong>" + data.record + "</strong> on <strong>" + (new Date(parseInt(data.timestamp,10))).toUTCString() + "</strong>"; + }); + + socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); + + socket.on('api:updateHeader', function(data) { + var rightMenu = $('#right-menu'); + if (data.uid > 0) { + var userLabel = rightMenu.find('#user_label'); + userLabel.attr('href','/users/'+data['username']); + + userLabel.find('img').attr('src',data['picture']+"?s=24"); + userLabel.find('span').html(data['username']); + + } else { + + rightMenu.html(''); + + var registerEl = document.createElement('li'), + loginEl = document.createElement('li'); + + registerEl.innerHTML = '<a href="/register">Register</a>'; + loginEl.innerHTML = '<a href="/login">Login</a>'; + + right_menu.appendChild(registerEl); + right_menu.appendChild(loginEl); + } + }); + + // Post window events + var postWindowEl = document.getElementById('post_window'), + discardEl = document.getElementById('discard-post'); + discardEl.addEventListener('click', function() { + $(postWindowEl).slideToggle(250); + $(document.body).removeClass('composing'); + }, false); + + // Notifications dropdown + var notifContainer = document.getElementsByClassName('notifications')[0], + notifTrigger = notifContainer.querySelector('a'), + notifList = document.getElementById('notif-list'); + notifTrigger.addEventListener('click', function() { + if (notifContainer.className.indexOf('open') === -1) socket.emit('api:notifications.get'); + }); + notifList.addEventListener('click', function(e) { + var target; + switch(e.target.nodeName) { + case 'SPAN': target = e.target.parentNode.parentNode; break; + case 'A': target = e.target.parentNode; break; + case 'li': target = e.target; break; + } + if (target) { + var nid = parseInt(target.getAttribute('data-nid')); + if (nid > 0) socket.emit('api:notifications.mark_read', nid); + } + }) + socket.on('api:notifications.get', function(data) { + var notifFrag = document.createDocumentFragment(), + notifEl = document.createElement('li'), + numRead = data.read.length, + numUnread = data.unread.length, + x; + notifList.innerHTML = ''; + if (data.read.length + data.unread.length > 0) { + for(x=0;x<numUnread;x++) { + notifEl.setAttribute('data-nid', data.unread[x].nid); + notifEl.className = 'unread'; + notifEl.innerHTML = '<a href="' + data.unread[x].path + '"><span class="pull-right">' + utils.relativeTime(data.unread[x].datetime, true) + '</span>' + data.unread[x].text + '</a>'; + notifFrag.appendChild(notifEl.cloneNode(true)); + } + for(x=0;x<numRead;x++) { + notifEl.setAttribute('data-nid', data.read[x].nid); + notifEl.className = ''; + notifEl.innerHTML = '<a href="' + data.read[x].path + '"><span class="pull-right">' + utils.relativeTime(data.read[x].datetime, true) + '</span>' + data.read[x].text + '</a>'; + notifFrag.appendChild(notifEl.cloneNode(true)); + } + } else { + notifEl.innerHTML = '<a>You have no notifications</a>'; + notifFrag.appendChild(notifEl); + } + notifList.appendChild(notifFrag); + }); + socket.on('api:notifications.counts', function(counts) { + var notifIcon = document.querySelector('.notifications a i'); + if(notifIcon) { + if (counts.unread > 0) notifIcon.className = 'icon-circle active'; + else notifIcon.className = 'icon-circle-blank'; + } + }); + socket.on('event:new_notification', function() { + console.log('WOOT'); + document.querySelector('.notifications a i').className = 'icon-circle active'; + }); + socket.emit('api:notifications.counts'); +}()); \ No newline at end of file diff --git a/public/src/forum/friends.js b/public/src/forum/friends.js new file mode 100644 index 0000000000..7a34e83815 --- /dev/null +++ b/public/src/forum/friends.js @@ -0,0 +1,44 @@ +(function() { + + var yourid = templates.get('yourid'), + theirid = templates.get('theirid'), + friendCount = templates.get('friendCount'); + + $(document).ready(function() { + + if(parseInt(friendCount, 10) === 0) { + $('#no-friend-notice').show(); + } + var editLink = $('#editLink'); + + if(yourid !== theirid) { + editLink.hide(); + $('.remove-friend-btn').hide(); + } + else { + $('.remove-friend-btn').on('click',function(){ + + var removeBtn = $(this); + var friendid = $(this).attr('friendid'); + + $.post('/users/removefriend', {uid: friendid}, + function(data) { + removeBtn.parent().remove(); + } + ); + return false; + }); + } + + $('.reputation').each(function(index, element) { + $(element).html(app.addCommas($(element).html())); + }); + + $('.postcount').each(function(index, element) { + $(element).html(app.addCommas($(element).html())); + }); + + }); + + +}()); \ No newline at end of file diff --git a/public/src/forum/login.js b/public/src/forum/login.js new file mode 100644 index 0000000000..f63fc15c28 --- /dev/null +++ b/public/src/forum/login.js @@ -0,0 +1,9 @@ +(function() { + // Alternate Logins + var altLoginEl = document.querySelector('.alt-logins'); + altLoginEl.addEventListener('click', function(e) { + if (e.target.nodeName === 'LI') { + document.location.href = e.target.getAttribute('data-url'); + } + }); +}()); diff --git a/public/src/forum/register.js b/public/src/forum/register.js new file mode 100644 index 0000000000..90768919a5 --- /dev/null +++ b/public/src/forum/register.js @@ -0,0 +1,83 @@ +(function() { + var username = document.getElementById('username'), + password = document.getElementById('password'), + register = document.getElementById('register'), + emailEl = document.getElementById('email'), + username_notify = document.getElementById('username-notify'), + email_notify = document.getElementById('email-notify'), + password_notify = document.getElementById('password-notify'); + + username.onkeyup = function() { + if (username.value.length > 2) socket.emit('user.exists', {username: username.value}); + else { + username_notify.innerHTML = 'Username too short'; + username_notify.className = 'label label-important'; + } + } + emailEl.addEventListener('change', function() { + socket.emit('user.email.exists', { email: emailEl.value }); + }, false); + password.addEventListener('keyup', function() { + if (password.value.length < 5) { + password_notify.innerHTML = 'Password too short'; + } else { + password_notify.innerHTML = ''; + } + }, false); + + ajaxify.register_events(['user.exists', 'user.email.exists']); + + socket.on('user.exists', function(data) { + if (data.exists == true) { + username_notify.innerHTML = 'Username exists'; + username_notify.className = 'label label-important'; + } else { + username_notify.innerHTML = 'Not taken'; + username_notify.className = 'label label-success'; + } + }); + socket.on('user.email.exists', function(data) { + if (data.exists === true) { + email_notify.innerHTML = 'Email Address exists'; + } else { + email_notify.innerHTML = ''; + } + }); + + // Alternate Logins + var altLoginEl = document.querySelector('.alt-logins'); + altLoginEl.addEventListener('click', function(e) { + if (e.target.nodeName === 'LI') { + document.location.href = e.target.getAttribute('data-url'); + } + }); + + // Form Validation + function validateForm() { + var validated = true; + if (username.value.length < 2) { + username_notify.innerHTML = 'Invalid username'; + username_notify.className = 'label label-important'; + validated = false; + } + + if (password.value.length < 5) { + password_notify.innerHTML = 'Password too short'; + validated = false; + } else { + password_notify.innerHTML = ''; + } + + if (email.value.indexOf('@') === -1) { + email_notify.innerHTML = 'Invalid email address'; + validated = false; + } else { + email_notify.innerHTML = ''; + } + + return validated; + } + register.addEventListener('click', function(e) { + if (!validateForm()) e.preventDefault(); + }, false); +}()); \ No newline at end of file diff --git a/public/src/forum/reset.js b/public/src/forum/reset.js new file mode 100644 index 0000000000..053db42e43 --- /dev/null +++ b/public/src/forum/reset.js @@ -0,0 +1,39 @@ +(function() { + var inputEl = document.getElementById('email'), + errorEl = document.getElementById('error'), + errorTextEl = errorEl.querySelector('p'); + + document.getElementById('reset').onclick = function() { + if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { + socket.emit('user:reset.send', { email: inputEl.value }); + } else { + jQuery('#success').hide(); + jQuery(errorEl).show(); + errorTextEl.innerHTML = 'Please enter a valid email'; + } + }; + + ajaxify.register_events(['user.send_reset']); + + socket.on('user.send_reset', function(data) { + var submitEl = document.getElementById('reset'); + + if (data.status === 'ok') { + jQuery('#error').hide(); + jQuery('#success').show(); + jQuery('#success p').html('An email has been dispatched to "' + data.email + '" with instructions on setting a new password.'); + inputEl.value = ''; + } else { + jQuery('#success').hide(); + jQuery(errorEl).show(); + switch(data.message) { + case 'invalid-email': + errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.'; + break; + case 'send-failed': + errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.'; + break; + } + } + }); +}()); \ No newline at end of file diff --git a/public/src/forum/reset_code.js b/public/src/forum/reset_code.js new file mode 100644 index 0000000000..fffc3dadf3 --- /dev/null +++ b/public/src/forum/reset_code.js @@ -0,0 +1,42 @@ +(function() { + var reset_code = templates.get('reset_code'); + + var resetEl = document.getElementById('reset'), + password = document.getElementById('password'), + repeat = document.getElementById('repeat'), + noticeEl = document.getElementById('notice'); + + resetEl.addEventListener('click', function() { + if (password.value.length < 6) { + $('#error').hide(); + noticeEl.querySelector('strong').innerHTML = 'Invalid Password'; + noticeEl.querySelector('p').innerHTML = 'The password entered it too short, please pick a different password!'; + noticeEl.style.display = 'block'; + } else if (password.value === repeat.value) { + socket.emit('user:reset.commit', { code: reset_code, password: password.value }); + } + }, false); + + // Enable the form if the code is valid + socket.emit('user:reset.valid', { code: reset_code }); + + + ajaxify.register_events(['user:reset.valid', 'user:reset.commit']); + socket.on('user:reset.valid', function(data) { + if (!!data.valid) resetEl.disabled = false; + else { + var formEl = document.getElementById('reset-form'); + // Show error message + $('#error').show(); + formEl.parentNode.removeChild(formEl); + } + }) + + socket.on('user:reset.commit', function(data) { + if (data.status === 'ok') { + $('#error').hide(); + $('#notice').hide(); + $('#success').show(); + } + }); +}()); \ No newline at end of file diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js new file mode 100644 index 0000000000..c11128eb86 --- /dev/null +++ b/public/src/forum/topic.js @@ -0,0 +1,603 @@ +(function() { + var expose_tools = templates.get('expose_tools'), + tid = templates.get('topic_id'), + postListEl = document.getElementById('post-container'), + editBtns = document.querySelectorAll('#post-container .post-buttons .edit, #post-container .post-buttons .edit i'), + thread_state = { + locked: templates.get('locked'), + deleted: templates.get('deleted'), + pinned: templates.get('pinned') + }, + topic_name = templates.get('topic_name'); + + function addCommasToNumbers() { + $('.formatted-number').each(function(index, element) { + $(element).html(app.addCommas($(element).html())); + }); + } + + jQuery('document').ready(function() { + + addCommasToNumbers(); + + var room = 'topic_' + tid, + adminTools = document.getElementById('thread-tools'); + + app.enter_room(room); + set_up_posts(); + + if (thread_state.locked === '1') set_locked_state(true); + if (thread_state.deleted === '1') set_delete_state(true); + if (thread_state.pinned === '1') set_pinned_state(true); + + if (expose_tools === '1') { + var deleteThreadEl = document.getElementById('delete_thread'), + lockThreadEl = document.getElementById('lock_thread'), + pinThreadEl = document.getElementById('pin_thread'), + moveThreadEl = document.getElementById('move_thread'), + moveThreadModal = $('#move_thread_modal'); + + adminTools.style.visibility = 'inherit'; + + // Add events to the thread tools + deleteThreadEl.addEventListener('click', function(e) { + e.preventDefault(); + if (thread_state.deleted !== '1') { + if (confirm('really delete thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) { + socket.emit('api:topic.delete', { tid: tid }); + } + } else { + if (confirm('really restore thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) { + socket.emit('api:topic.restore', { tid: tid }); + } + } + }, false); + + lockThreadEl.addEventListener('click', function(e) { + e.preventDefault(); + if (thread_state.locked !== '1') { + socket.emit('api:topic.lock', { tid: tid }); + } else { + socket.emit('api:topic.unlock', { tid: tid }); + } + }, false); + + pinThreadEl.addEventListener('click', function(e) { + e.preventDefault(); + if (thread_state.pinned !== '1') { + socket.emit('api:topic.pin', { tid: tid }); + } else { + socket.emit('api:topic.unpin', { tid: tid }); + } + }, false); + + moveThreadEl.addEventListener('click', function(e) { + e.preventDefault(); + moveThreadModal.modal('show'); + }, false); + + moveThreadModal.on('shown', function() { + var loadingEl = document.getElementById('categories-loading'); + if (loadingEl) { + socket.once('api:categories.get', function(data) { + // Render categories + var categoriesFrag = document.createDocumentFragment(), + categoryEl = document.createElement('li'), + numCategories = data.categories.length, + modalBody = moveThreadModal.find('.modal-body'), + categoriesEl = modalBody[0].getElementsByTagName('ul')[0], + confirmDiv = document.getElementById('move-confirm'), + confirmCat = confirmDiv.getElementsByTagName('span')[0], + commitEl = document.getElementById('move_thread_commit'), + cancelEl = document.getElementById('move_thread_cancel'), + x, info, targetCid, targetCatLabel; + + categoriesEl.className = 'category-list'; + for(x=0;x<numCategories;x++) { + info = data.categories[x]; + categoryEl.className = info.blockclass; + categoryEl.innerHTML = '<i class="' + info.icon + '"></i> ' + info.name; + categoryEl.setAttribute('data-cid', info.cid); + categoriesFrag.appendChild(categoryEl.cloneNode(true)); + } + categoriesEl.appendChild(categoriesFrag); + modalBody[0].removeChild(loadingEl); + + categoriesEl.addEventListener('click', function(e) { + if (e.target.nodeName === 'LI') { + confirmCat.innerHTML = e.target.innerHTML; + confirmDiv.style.display = 'block'; + targetCid = e.target.getAttribute('data-cid'); + targetCatLabel = e.target.innerHTML; + commitEl.disabled = false; + } + }, false); + + commitEl.addEventListener('click', function() { + if (!commitEl.disabled && targetCid) { + commitEl.disabled = true; + $(cancelEl).fadeOut(250); + $(moveThreadModal).find('.modal-header button').fadeOut(250); + commitEl.innerHTML = 'Moving <i class="icon-spin icon-refresh"></i>'; + + socket.once('api:topic.move', function(data) { + moveThreadModal.modal('hide'); + if (data.status === 'ok') { + app.alert({ + 'alert_id': 'thread_move', + type: 'success', + title: 'Topic Successfully Moved', + message: 'This topic has been successfully moved to ' + targetCatLabel, + timeout: 5000 + }); + } else { + app.alert({ + 'alert_id': 'thread_move', + type: 'error', + title: 'Unable to Move Topic', + message: 'This topic could not be moved to ' + targetCatLabel + '.<br />Please try again later', + timeout: 5000 + }); + } + }); + socket.emit('api:topic.move', { tid: tid, cid: targetCid }); + } + }); + }); + socket.emit('api:categories.get'); + } + }); + } + + // Fix delete state for this thread's posts + var postEls = document.querySelectorAll('#post-container li[data-deleted]'); + for(var x=0,numPosts=postEls.length;x<numPosts;x++) { + if (postEls[x].getAttribute('data-deleted') === '1') toggle_post_delete_state(postEls[x].getAttribute('data-pid')); + postEls[x].removeAttribute('data-deleted'); + } + }); + + + $('.post-container').delegate('.edit', 'click', function(e) { + var pid = ($(this).attr('id') || $(this.parentNode).attr('id')).split('_')[1]; + + var main = $(this).parents('.main-post'); + if(main.length > 0) + app.open_post_window('edit', tid, topic_name, pid); + else + app.open_post_window('edit', tid, "", pid); + + }); + + $('.post-container').delegate('.delete', 'click', function(e) { + var pid = ($(this).attr('id') || $(this.parentNode).attr('id')).split('_')[1], + postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), + deleteAction = !postEl.hasClass('deleted') ? true : false, + confirmDel = confirm((deleteAction ? 'Delete' : 'Restore') + ' this post?'); + + if (confirmDel) { + deleteAction ? + socket.emit('api:posts.delete', { pid: pid }) : + socket.emit('api:posts.restore', { pid: pid }); + } + }); + + // CHAT, move to chat.js later? + + $('.post-container').delegate('.chat', 'click', function(e){ + + var username = $(this).parents('li').attr('data-username'); + var touid = $(this).parents('li').attr('data-uid'); + + var chatModal = createModalIfDoesntExist(username, touid); + + chatModal.show(); + bringModalToTop(chatModal); + + }); + + function bringModalToTop(chatModal) { + var topZ = 0; + $('.modal').each(function(){ + var thisZ = parseInt($(this).css('zIndex'), 10); + if (thisZ > topZ){ + topZ = thisZ; + } + }); + chatModal.css('zIndex', topZ+1); + } + + function createModalIfDoesntExist(username, touid) { + var chatModal = $('#chat-modal-'+touid); + + if(!chatModal.length) { + var chatModal = $('#chat-modal').clone(); + chatModal.attr('id','chat-modal-'+touid); + chatModal.appendTo($('body')); + chatModal.draggable({ + start:function(){ + bringModalToTop(chatModal); + } + }); + chatModal.find('#chat-with-name').html(username); + + chatModal.find('.close').on('click',function(e){ + chatModal.hide(); + }); + + chatModal.on('click', function(e){ + bringModalToTop(chatModal); + }); + + addSendHandler(chatModal, touid); + } + + return chatModal; + } + + function addSendHandler(chatModal, touid) { + chatModal.find('#chat-message-input').off('keypress'); + chatModal.find('#chat-message-input').on('keypress', function(e) { + if(e.which === 13) { + sendMessage(chatModal, touid); + } + }); + + chatModal.find('#chat-message-send-btn').off('click'); + chatModal.find('#chat-message-send-btn').on('click', function(e){ + sendMessage(chatModal, touid); + return false; + }); + } + + function sendMessage(chatModal, touid) { + var msg = app.strip_tags(chatModal.find('#chat-message-input').val()); + if(msg.length) { + msg = msg +'\n'; + socket.emit('sendChatMessage', { touid:touid, message:msg}); + chatModal.find('#chat-message-input').val(''); + appendChatMessage(chatModal, 'You : ' + msg); + } + } + + socket.on('chatMessage', function(data){ + var username = data.username; + var fromuid = data.fromuid; + var message = data.message; + + var chatModal = createModalIfDoesntExist(username, fromuid); + chatModal.show(); + bringModalToTop(chatModal); + + appendChatMessage(chatModal, message) + }); + + function appendChatMessage(chatModal, message){ + var chatContent = chatModal.find('#chat-content'); + chatContent.append(message); + chatContent.scrollTop( + chatContent[0].scrollHeight - chatContent.height() + ); + } + //end of chat + + + ajaxify.register_events([ + 'event:rep_up', 'event:rep_down', 'event:new_post', 'api:get_users_in_room', + 'event:topic_deleted', 'event:topic_restored', 'event:topic:locked', + 'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned', + 'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored', + 'api:posts.favourite', 'chatMessage' + ]); + + + socket.on('api:get_users_in_room', function(users) { + var anonymous = users.anonymous, + usernames = users.usernames, + usercount = usernames.length; + + for (var i = 0, ii=usercount; i<ii; i++) { + usernames[i] = '<strong>' + '<a href="/users/'+usernames[i]+'">' + usernames[i] + '</a></strong>'; + } + + // headexplosion.gif for fun, to see if I could do this in one line of code. feel free to refactor haha + var active = + ((usercount === 1) ? usernames[0] : '') + + ((usercount === 2 && anonymous === 0) ? usernames[0] + ' and ' + usernames[1] : '') + + ((usercount > 2 && anonymous === 0) ? usernames.join(', ').replace(/,([^,]*)$/, ", and$1") : '') + + (usercount > 1 && anonymous > 0 ? usernames.join(', ') : '') + + ((anonymous > 0) ? (usercount > 0 ? ' and ': '') + anonymous + ' guest' + (anonymous > 1 ? 's are': ' is') : '') + + (anonymous === 0 ? (usercount > 1 ? ' are' : ' is') : '') + ' browsing this thread'; + + document.getElementById('thread_active_users').innerHTML = active; + }); + + socket.on('event:rep_up', function(data) { + adjust_rep(1, data.pid, data.uid); + }); + + socket.on('event:rep_down', function(data) { + adjust_rep(-1, data.pid, data.uid); + }); + + socket.on('event:new_post', function(data) { + var html = templates.prepare(templates['topic'].blocks['posts']).parse(data), + uniqueid = new Date().getTime(); + + jQuery('<div id="' + uniqueid + '"></div>') + .appendTo("#post-container") + .hide() + .append(html) + .fadeIn('slow'); + + set_up_posts(uniqueid); + + addCommasToNumbers(); + }); + + socket.on('event:topic_deleted', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_locked_state(true); + set_delete_state(true); + } + }); + + socket.on('event:topic_restored', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_locked_state(false); + set_delete_state(false); + } + }); + + socket.on('event:topic_locked', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_locked_state(true, 1); + } + }); + + socket.on('event:topic_unlocked', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_locked_state(false, 1); + } + }); + + socket.on('event:topic_pinned', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_pinned_state(true, 1); + } + }); + + socket.on('event:topic_unpinned', function(data) { + if (data.tid === tid && data.status === 'ok') { + set_pinned_state(false, 1); + } + }); + + socket.on('event:topic_moved', function(data) { + if (data && data.tid > 0) ajaxify.go('topic/' + data.tid); + }); + + socket.on('event:post_edited', function(data) { + var editedPostEl = document.getElementById('content_' + data.pid); + + var editedPostTitle = $('#topic_title_'+data.pid); + + if(editedPostTitle.length > 0) { + editedPostTitle.fadeOut(250, function() { + editedPostTitle.html(data.title); + editedPostTitle.fadeIn(250); + }); + } + + $(editedPostEl).fadeOut(250, function() { + this.innerHTML = data.content; + $(this).fadeIn(250); + }); + }); + + socket.on('api:posts.favourite', function(data) { + if (data.status !== 'ok' && data.pid) { + var favEl = document.querySelector('.post_rep_' + data.pid).nextSibling; + if (favEl) favEl.className = 'icon-star-empty'; + } + }); + + socket.on('event:post_deleted', function(data) { + if (data.pid) toggle_post_delete_state(data.pid, true); + }); + + socket.on('event:post_restored', function(data) { + if (data.pid) toggle_post_delete_state(data.pid, true); + }); + + function adjust_rep(value, pid, uid) { + var post_rep = jQuery('.post_rep_' + pid), + user_rep = jQuery('.user_rep_' + uid); + + var ptotal = parseInt(post_rep.html(), 10), + utotal = parseInt(user_rep.html(), 10); + + ptotal += value; + utotal += value; + + post_rep.html(ptotal); + user_rep.html(utotal); + } + + + function set_up_posts(div) { + if (div == null) div = ''; + else div = '#' + div; + + jQuery(div + ' .post_reply').click(function() { + if (thread_state.locked !== '1') app.open_post_window('reply', tid, topic_name); + }); + + jQuery(div + ' .quote').click(function() { + if (thread_state.locked !== '1') app.open_post_window('quote', tid, topic_name); + + var pid = $(this).parents('li').attr('data-pid'); + + $('#post_content').val('> ' + $('#content_' + pid).html() + '\n'); + console.log("POST ID "+pid); + }); + + jQuery(div + ' .edit, ' + div + ' .delete').each(function() { + var ids = this.id.replace('ids_', '').split('_'), + pid = ids[0], + uid = ids[1]; + + }); + + jQuery(div + ' .favourite').click(function() { + var ids = this.id.replace('favs_', '').split('_'), + pid = ids[0], + uid = ids[1]; + + if (thread_state.locked !== '1') { + if (this.children[1].className == 'icon-star-empty') { + this.children[1].className = 'icon-star'; + socket.emit('api:posts.favourite', {pid: pid, room_id: app.current_room}); + } + else { + this.children[1].className = 'icon-star-empty'; + socket.emit('api:posts.unfavourite', {pid: pid, room_id: app.current_room}); + } + } + }); + } + + function set_locked_state(locked, alert) { + var threadReplyBtn = document.getElementById('post_reply'), + postReplyBtns = document.querySelectorAll('#post-container .post_reply'), + quoteBtns = document.querySelectorAll('#post-container .quote'), + editBtns = document.querySelectorAll('#post-container .edit'), + deleteBtns = document.querySelectorAll('#post-container .delete'), + numReplyBtns = postReplyBtns.length, + lockThreadEl = document.getElementById('lock_thread'), + x; + + if (locked === true) { + lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread'; + threadReplyBtn.disabled = true; + threadReplyBtn.innerHTML = 'Locked <i class="icon-lock"></i>'; + for(x=0;x<numReplyBtns;x++) { + postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>'; + quoteBtns[x].style.display = 'none'; + editBtns[x].style.display = 'none'; + deleteBtns[x].style.display = 'none'; + } + + if (alert) { + app.alert({ + 'alert_id': 'thread_lock', + type: 'success', + title: 'Thread Locked', + message: 'Thread has been successfully locked', + timeout: 5000 + }); + } + + thread_state.locked = '1'; + } else { + lockThreadEl.innerHTML = '<i class="icon-lock"></i> Lock Thread'; + threadReplyBtn.disabled = false; + threadReplyBtn.innerHTML = 'Reply'; + for(x=0;x<numReplyBtns;x++) { + postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>'; + quoteBtns[x].style.display = 'inline-block'; + editBtns[x].style.display = 'inline-block'; + deleteBtns[x].style.display = 'inline-block'; + } + + if (alert) { + app.alert({ + 'alert_id': 'thread_lock', + type: 'success', + title: 'Thread Unlocked', + message: 'Thread has been successfully unlocked', + timeout: 5000 + }); + } + + thread_state.locked = '0'; + } + } + + function set_delete_state(deleted) { + var deleteThreadEl = document.getElementById('delete_thread'), + deleteTextEl = deleteThreadEl.getElementsByTagName('span')[0], + threadEl = document.querySelector('.post-container'), + deleteNotice = document.getElementById('thread-deleted') || document.createElement('div'); + + if (deleted) { + deleteTextEl.innerHTML = '<i class="icon-comment"></i> Restore Thread'; + $(threadEl).addClass('deleted'); + + // Spawn a 'deleted' notice at the top of the page + deleteNotice.setAttribute('id', 'thread-deleted'); + deleteNotice.className = 'alert'; + deleteNotice.innerHTML = 'This thread has been deleted. Only users with thread management privileges can see it.'; + document.getElementById('content').insertBefore(deleteNotice, threadEl); + + thread_state.deleted = '1'; + } else { + deleteTextEl.innerHTML = '<i class="icon-trash"></i> Delete Thread'; + $(threadEl).removeClass('deleted'); + deleteNotice.parentNode.removeChild(deleteNotice); + + thread_state.deleted = '0'; + } + } + + function set_pinned_state(pinned, alert) { + var pinEl = document.getElementById('pin_thread'); + + if (pinned) { + pinEl.innerHTML = '<i class="icon-pushpin"></i> Unpin Thread'; + if (alert) { + app.alert({ + 'alert_id': 'thread_pin', + type: 'success', + title: 'Thread Pinned', + message: 'Thread has been successfully pinned', + timeout: 5000 + }); + } + + thread_state.pinned = '1'; + } else { + pinEl.innerHTML = '<i class="icon-pushpin"></i> Pin Thread'; + if (alert) { + app.alert({ + 'alert_id': 'thread_pin', + type: 'success', + title: 'Thread Unpinned', + message: 'Thread has been successfully unpinned', + timeout: 5000 + }); + } + + thread_state.pinned = '0'; + } + } + + function toggle_post_delete_state(pid) { + var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')); + quoteEl = $(postEl[0].querySelector('.quote')), + favEl = $(postEl[0].querySelector('.favourite')), + replyEl = $(postEl[0].querySelector('.post_reply')); + + if (!postEl.hasClass('deleted')) { + quoteEl.addClass('none'); + favEl.addClass('none'); + replyEl.addClass('none'); + } else { + quoteEl.removeClass('none'); + favEl.removeClass('none'); + replyEl.removeClass('none'); + } + + postEl.toggleClass('deleted'); + } +})(); \ No newline at end of file diff --git a/public/src/forum/users.js b/public/src/forum/users.js new file mode 100644 index 0000000000..3b33869b02 --- /dev/null +++ b/public/src/forum/users.js @@ -0,0 +1,15 @@ +(function() { + + $(document).ready(function() { + + $('.reputation').each(function(index, element) { + $(element).html(app.addCommas($(element).html())); + }); + + $('.postcount').each(function(index, element) { + $(element).html(app.addCommas($(element).html())); + }); + + }); + +}()); \ No newline at end of file diff --git a/public/templates/account.tpl b/public/templates/account.tpl index f269317b50..fc90419d9e 100644 --- a/public/templates/account.tpl +++ b/public/templates/account.tpl @@ -75,49 +75,4 @@ <input type="hidden" template-variable="yourid" value="{yourid}" /> <input type="hidden" template-variable="theirid" value="{theirid}" /> -<script type="text/javascript"> - -var yourid = templates.get('yourid'), - theirid = templates.get('theirid'); - -(function() { - - var isFriend = {isFriend}; - - $(document).ready(function() { - - var rep = $('#reputation'); - rep.html(app.addCommas(rep.html())); - - var postcount = $('#postcount'); - postcount.html(app.addCommas(postcount.html())); - - var editLink = $('#editLink'); - var addFriendBtn = $('#add-friend-btn'); - - - if( yourid !== theirid) { - editLink.hide(); - if(isFriend) - addFriendBtn.hide(); - else - addFriendBtn.show(); - } - else { - addFriendBtn.hide(); - } - - addFriendBtn.on('click', function() { - $.post('/users/addfriend', {uid: theirid}, - function(data) { - addFriendBtn.remove(); - $('#user-action-alert').html('Friend Added!').show(); - } - ); - return false; - }); - - }); - -}()); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/account.js"></script> \ No newline at end of file diff --git a/public/templates/accountedit.tpl b/public/templates/accountedit.tpl index 2625aa10df..3d727d5547 100644 --- a/public/templates/accountedit.tpl +++ b/public/templates/accountedit.tpl @@ -140,223 +140,4 @@ <input type="hidden" template-variable="gravatarpicture" value="{gravatarpicture}" /> <input type="hidden" template-variable="uploadedpicture" value="{uploadedpicture}" /> -<script type="text/javascript"> - - -var gravatarPicture = templates.get('gravatarpicture'); -var uploadedPicture = templates.get('uploadedpicture'); - -$(document).ready(function() { - - - - $('#uploadForm').submit(function() { - status('uploading the file ...'); - - $('#upload-progress-bar').css('width', '0%'); - $('#upload-progress-box').show(); - - if(!$('#userPhotoInput').val()) { - error('select an image to upload!'); - return false; - } - - $(this).ajaxSubmit({ - - error: function(xhr) { - error('Error: ' + xhr.status); - }, - - uploadProgress : function(event, position, total, percent) { - $('#upload-progress-bar').css('width', percent+'%'); - }, - - - success: function(response) { - if(response.error) { - error(response.error); - return; - } - - var imageUrlOnServer = response.path; - - $('#user-current-picture').attr('src', imageUrlOnServer); - $('#user-uploaded-picture').attr('src', imageUrlOnServer); - - uploadedPicture = imageUrlOnServer; - - setTimeout(function() { - hideAlerts(); - $('#upload-picture-modal').modal('hide'); - }, 750); - - socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); - success('File uploaded successfully!'); - } - }); - - return false; - }); - - function hideAlerts() { - $('#alert-status').hide(); - $('#alert-success').hide(); - $('#alert-error').hide(); - $('#upload-progress-box').hide(); - } - - function status(message) { - hideAlerts(); - $('#alert-status').text(message).show(); - } - - function success(message) { - hideAlerts(); - $('#alert-success').text(message).show(); - } - - function error(message) { - hideAlerts(); - $('#alert-error').text(message).show(); - } - - function changeUserPicture(type) { - var userData = { - uid: $('#inputUID').val(), - type: type - }; - - $.post('/users/changepicture', - userData, - function(data) { - socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); - } - ); - } - - var selectedImageType = ''; - - $('#submitBtn').on('click',function(){ - - var userData = { - uid:$('#inputUID').val(), - email:$('#inputEmail').val(), - fullname:$('#inputFullname').val(), - website:$('#inputWebsite').val(), - birthday:$('#inputBirthday').val(), - location:$('#inputLocation').val(), - signature:$('#inputSignature').val(), - }; - - $.post('/users/doedit', - userData, - function(data) { - if(data.error) { - app.alert({ - 'alert_id': 'user_profile_updated', - type: 'error', - title: 'Profile Update Error', - message: data.error, - timeout: 2000 - }); - return; - } - - app.alert({ - 'alert_id': 'user_profile_updated', - type: 'success', - title: 'Profile Updated', - message: 'Your profile has been updated successfully', - timeout: 2000 - }); - } - ); - return false; - }); - - function updateImages() { - var currentPicture = $('#user-current-picture').attr('src'); - - if(gravatarPicture) { - $('#user-gravatar-picture').attr('src', gravatarPicture); - $('#gravatar-box').show(); - } - else - $('#gravatar-box').hide(); - - if(uploadedPicture) { - $('#user-uploaded-picture').attr('src', uploadedPicture); - $('#uploaded-box').show(); - } - else - $('#uploaded-box').hide(); - - - if(currentPicture == gravatarPicture) - $('#gravatar-box .icon-ok').show(); - else - $('#gravatar-box .icon-ok').hide(); - - if(currentPicture == uploadedPicture) - $('#uploaded-box .icon-ok').show(); - else - $('#uploaded-box .icon-ok').hide(); - } - - - $('#changePictureBtn').on('click', function() { - selectedImageType = ''; - updateImages(); - - $('#change-picture-modal').modal('show'); - - return false; - }); - - $('#gravatar-box').on('click', function(){ - $('#gravatar-box .icon-ok').show(); - $('#uploaded-box .icon-ok').hide(); - selectedImageType = 'gravatar'; - }); - - $('#uploaded-box').on('click', function(){ - $('#gravatar-box .icon-ok').hide(); - $('#uploaded-box .icon-ok').show(); - selectedImageType = 'uploaded'; - }); - - $('#savePictureChangesBtn').on('click', function() { - $('#change-picture-modal').modal('hide'); - - if(selectedImageType) { - changeUserPicture(selectedImageType); - - if(selectedImageType == 'gravatar') - $('#user-current-picture').attr('src', gravatarPicture); - else if(selectedImageType == 'uploaded') - $('#user-current-picture').attr('src', uploadedPicture); - } - - }); - - $('#upload-picture-modal').on('hide', function() { - $('#userPhotoInput').val(''); - }); - - $('#uploadPictureBtn').on('click', function(){ - - $('#change-picture-modal').modal('hide'); - $('#upload-picture-modal').modal('show'); - - hideAlerts(); - - return false; - }); - - $('#pictureUploadSubmitBtn').on('click', function() { - $('#uploadForm').submit(); - }); - - -}); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/accountedit.js"></script> \ No newline at end of file diff --git a/public/templates/category.tpl b/public/templates/category.tpl index 320134ef11..89cc373aa7 100644 --- a/public/templates/category.tpl +++ b/public/templates/category.tpl @@ -82,84 +82,4 @@ <input type="hidden" template-variable="category_id" value="{category_id}" /> - -<script type="text/javascript"> -(function() { - var cid = templates.get('category_id'), - room = 'category_' + cid; - - app.enter_room(room); - - var new_post = document.getElementById('new_post'); - new_post.onclick = function() { - app.open_post_window('topic', {category_id}); - } - - ajaxify.register_events([ - 'event:new_topic' - ]); - - if (jQuery('.category-item').length == 0) { - jQuery('#topics-container, .category-sidebar').hide(); - jQuery('#category-no-topics').show(); - } - - socket.on('event:new_topic', function(data) { - var html = templates.prepare(templates['category'].blocks['topics']).parse({ topics: [data] }), - topic = document.createElement('div'), - container = document.getElementById('topics-container'), - topics = document.querySelectorAll('#topics-container a'), - numTopics = topics.length, - x; - - jQuery('#topics-container, .category-sidebar').show(); - jQuery('#category-no-topics').hide(); - - topic.innerHTML = html; - if (numTopics > 0) { - for(x=0;x<numTopics;x++) { - if (topics[x].querySelector('.icon-pushpin')) continue; - container.insertBefore(topic.querySelector('a'), topics[x]); - $(topic).hide().fadeIn('slow'); - break; - } - } else { - container.insertBefore(topic.querySelector('a'), null); - $(topic).hide().fadeIn('slow'); - } - - // jQuery('<div></div>').appendTo("#topics-container").hide().append(html).fadeIn('slow'); - // set_up_posts(uniqueid); - }); - - - - socket.emit('api:categories.getRecentReplies', cid); - socket.on('api:categories.getRecentReplies', function(replies) { - if (replies === false) { - return; - } - - var users = replies.users, - posts = replies.posts, - recent_replies = document.getElementById('category_recent_replies'); - - recent_replies.innerHTML = ''; - for (var i=0, ii=posts.pids.length; i<ii; i++) { - var a = document.createElement('a'), - ul = document.createElement('ul'), - username = users[posts.uid[i]].username, - picture = users[posts.uid[i]].picture; - - //temp until design finalized - ul.innerHTML = '<li><img title="' + username + '" style="width: 48px; height: 48px; /*temporary*/" src="' + picture + '" class="" />' - + '<p><strong>' + username + '</strong>: ' + posts.content[i] + '</p><span>posted ' + utils.relativeTime(posts.timestamp[i]) + ' ago</span></li>'; - - a.appendChild(ul); - recent_replies.appendChild(a); - } - - }); - -})(); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/category.js"></script> \ No newline at end of file diff --git a/public/templates/footer.tpl b/public/templates/footer.tpl index 133771bda6..276d9abaa2 100644 --- a/public/templates/footer.tpl +++ b/public/templates/footer.tpl @@ -11,132 +11,7 @@ <footer class="footer">Copyright © 2013 <a target="_blank" href="http://www.nodebb.com">NodeBB</a> by <a target="_blank" href="https://github.com/psychobunny">psychobunny</a>, <a href="https://github.com/julianlam" target="_blank">julianlam</a>, <a href="https://github.com/barisusakli" target="_blank">barisusakli</a> from <a target="_blank" href="http://www.designcreateplay.com">designcreateplay</a></footer> </div> - <script type="text/javascript"> - (function() { - var num_users = document.getElementById('number_of_users'), - latest_user = document.getElementById('latest_user'), - active_users = document.getElementById('active_users'), - user_label = document.getElementById('user_label'), - active_record = document.getElementById('active_record'), - right_menu = document.getElementById('right-menu'); - - socket.emit('user.count', {}); - socket.on('user.count', function(data) { - num_users.innerHTML = "We currently have <b>" + data.count + "</b> registered users."; - }); - socket.emit('user.latest', {}); - socket.on('user.latest', function(data) { - if (data.username == '') { - latest_user.innerHTML = ''; - } else { - latest_user.innerHTML = "The most recent user to register is <b><a href='/users/"+data.username+"'>" + data.username + "</a></b>."; - } - }); - socket.emit('api:user.active.get'); - socket.on('api:user.active.get', function(data) { - var plural_users = parseInt(data.users) !== 1, - plural_anon = parseInt(data.anon) !== 1; - - active_users.innerHTML = 'There ' + (plural_users ? 'are' : 'is') + ' <strong>' + data.users + '</strong> user' + (plural_users ? 's' : '') + ' and <strong>' + data.anon + '</strong> guest' + (plural_anon ? 's' : '') + ' online'; - }); - socket.emit('api:user.active.get_record'); - socket.on('api:user.active.get_record', function(data) { - active_record.innerHTML = "most users ever online was <strong>" + data.record + "</strong> on <strong>" + (new Date(parseInt(data.timestamp,10))).toUTCString() + "</strong>"; - }); - - socket.emit('api:updateHeader', { fields: ['username', 'picture'] }); - - socket.on('api:updateHeader', function(data) { - var rightMenu = $('#right-menu'); - if (data.uid > 0) { - var userLabel = rightMenu.find('#user_label'); - userLabel.attr('href','/users/'+data['username']); - - userLabel.find('img').attr('src',data['picture']+"?s=24"); - userLabel.find('span').html(data['username']); - - } else { - - rightMenu.html(''); - - var registerEl = document.createElement('li'), - loginEl = document.createElement('li'); - - registerEl.innerHTML = '<a href="/register">Register</a>'; - loginEl.innerHTML = '<a href="/login">Login</a>'; - - right_menu.appendChild(registerEl); - right_menu.appendChild(loginEl); - } - }); - - // Post window events - var postWindowEl = document.getElementById('post_window'), - discardEl = document.getElementById('discard-post'); - discardEl.addEventListener('click', function() { - $(postWindowEl).slideToggle(250); - $(document.body).removeClass('composing'); - }, false); - - // Notifications dropdown - var notifContainer = document.getElementsByClassName('notifications')[0], - notifTrigger = notifContainer.querySelector('a'), - notifList = document.getElementById('notif-list'); - notifTrigger.addEventListener('click', function() { - if (notifContainer.className.indexOf('open') === -1) socket.emit('api:notifications.get'); - }); - notifList.addEventListener('click', function(e) { - var target; - switch(e.target.nodeName) { - case 'SPAN': target = e.target.parentNode.parentNode; break; - case 'A': target = e.target.parentNode; break; - case 'li': target = e.target; break; - } - if (target) { - var nid = parseInt(target.getAttribute('data-nid')); - if (nid > 0) socket.emit('api:notifications.mark_read', nid); - } - }) - socket.on('api:notifications.get', function(data) { - var notifFrag = document.createDocumentFragment(), - notifEl = document.createElement('li'), - numRead = data.read.length, - numUnread = data.unread.length, - x; - notifList.innerHTML = ''; - if (data.read.length + data.unread.length > 0) { - for(x=0;x<numUnread;x++) { - notifEl.setAttribute('data-nid', data.unread[x].nid); - notifEl.className = 'unread'; - notifEl.innerHTML = '<a href="' + data.unread[x].path + '"><span class="pull-right">' + utils.relativeTime(data.unread[x].datetime, true) + '</span>' + data.unread[x].text + '</a>'; - notifFrag.appendChild(notifEl.cloneNode(true)); - } - for(x=0;x<numRead;x++) { - notifEl.setAttribute('data-nid', data.read[x].nid); - notifEl.className = ''; - notifEl.innerHTML = '<a href="' + data.read[x].path + '"><span class="pull-right">' + utils.relativeTime(data.read[x].datetime, true) + '</span>' + data.read[x].text + '</a>'; - notifFrag.appendChild(notifEl.cloneNode(true)); - } - } else { - notifEl.innerHTML = '<a>You have no notifications</a>'; - notifFrag.appendChild(notifEl); - } - notifList.appendChild(notifFrag); - }); - socket.on('api:notifications.counts', function(counts) { - var notifIcon = document.querySelector('.notifications a i'); - if(notifIcon) { - if (counts.unread > 0) notifIcon.className = 'icon-circle active'; - else notifIcon.className = 'icon-circle-blank'; - } - }); - socket.on('event:new_notification', function() { - console.log('WOOT'); - document.querySelector('.notifications a i').className = 'icon-circle active'; - }); - socket.emit('api:notifications.counts'); - }()); - </script> + <script type="text/javascript" src="src/forum/footer.js"></script> <!-- END Forum Info --> </body> </html> \ No newline at end of file diff --git a/public/templates/friends.tpl b/public/templates/friends.tpl index 37a899de38..aee731db35 100644 --- a/public/templates/friends.tpl +++ b/public/templates/friends.tpl @@ -44,50 +44,4 @@ <input type="hidden" template-variable="theirid" value="{theirid}" /> <input type="hidden" template-variable="friendCount" value="{friendCount}" /> -<script type="text/javascript"> - -var yourid = templates.get('yourid'), - theirid = templates.get('theirid'), - friendCount = templates.get('friendCount'); - -(function() { - - $(document).ready(function() { - - if(parseInt(friendCount, 10) === 0) { - $('#no-friend-notice').show(); - } - var editLink = $('#editLink'); - - if(yourid !== theirid) { - editLink.hide(); - $('.remove-friend-btn').hide(); - } - else { - $('.remove-friend-btn').on('click',function(){ - - var removeBtn = $(this); - var friendid = $(this).attr('friendid'); - - $.post('/users/removefriend', {uid: friendid}, - function(data) { - removeBtn.parent().remove(); - } - ); - return false; - }); - } - - $('.reputation').each(function(index, element) { - $(element).html(app.addCommas($(element).html())); - }); - - $('.postcount').each(function(index, element) { - $(element).html(app.addCommas($(element).html())); - }); - - }); - - -}()); -</script> +<script type="text/javascript" src="/src/forum/friends.js"></script> diff --git a/public/templates/login.tpl b/public/templates/login.tpl index 875e4760bd..c01517915f 100644 --- a/public/templates/login.tpl +++ b/public/templates/login.tpl @@ -22,12 +22,4 @@ </div> </div> -<script> - // Alternate Logins - var altLoginEl = document.querySelector('.alt-logins'); - altLoginEl.addEventListener('click', function(e) { - if (e.target.nodeName === 'LI') { - document.location.href = e.target.getAttribute('data-url'); - } - }); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/login.js"></script> \ No newline at end of file diff --git a/public/templates/register.tpl b/public/templates/register.tpl index 875b3bab8d..fdf65eb37b 100644 --- a/public/templates/register.tpl +++ b/public/templates/register.tpl @@ -17,88 +17,5 @@ </ul> </div> </div> -<script type="text/javascript"> -(function() { - var username = document.getElementById('username'), - password = document.getElementById('password'), - register = document.getElementById('register'), - emailEl = document.getElementById('email'), - username_notify = document.getElementById('username-notify'), - email_notify = document.getElementById('email-notify'), - password_notify = document.getElementById('password-notify'); - username.onkeyup = function() { - if (username.value.length > 2) socket.emit('user.exists', {username: username.value}); - else { - username_notify.innerHTML = 'Username too short'; - username_notify.className = 'label label-important'; - } - } - emailEl.addEventListener('change', function() { - socket.emit('user.email.exists', { email: emailEl.value }); - }, false); - password.addEventListener('keyup', function() { - if (password.value.length < 5) { - password_notify.innerHTML = 'Password too short'; - } else { - password_notify.innerHTML = ''; - } - }, false); - - ajaxify.register_events(['user.exists', 'user.email.exists']); - - socket.on('user.exists', function(data) { - if (data.exists == true) { - username_notify.innerHTML = 'Username exists'; - username_notify.className = 'label label-important'; - } else { - username_notify.innerHTML = 'Not taken'; - username_notify.className = 'label label-success'; - } - }); - socket.on('user.email.exists', function(data) { - if (data.exists === true) { - email_notify.innerHTML = 'Email Address exists'; - } else { - email_notify.innerHTML = ''; - } - }); - - // Alternate Logins - var altLoginEl = document.querySelector('.alt-logins'); - altLoginEl.addEventListener('click', function(e) { - if (e.target.nodeName === 'LI') { - document.location.href = e.target.getAttribute('data-url'); - } - }); - - // Form Validation - function validateForm() { - var validated = true; - if (username.value.length < 2) { - username_notify.innerHTML = 'Invalid username'; - username_notify.className = 'label label-important'; - validated = false; - } - - if (password.value.length < 5) { - password_notify.innerHTML = 'Password too short'; - validated = false; - } else { - password_notify.innerHTML = ''; - } - - if (email.value.indexOf('@') === -1) { - email_notify.innerHTML = 'Invalid email address'; - validated = false; - } else { - email_notify.innerHTML = ''; - } - - return validated; - } - register.addEventListener('click', function(e) { - if (!validateForm()) e.preventDefault(); - }, false); -}()); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/register.js"></script> \ No newline at end of file diff --git a/public/templates/reset.tpl b/public/templates/reset.tpl index 3dee8b302b..3a1857a4f4 100644 --- a/public/templates/reset.tpl +++ b/public/templates/reset.tpl @@ -13,44 +13,5 @@ <label for="email">Email Address</label><input type="text" placeholder="Enter Email Address" id="email" /><br /> <button class="btn btn-primary" id="reset" type="submit">Reset Password</button> </div> -<script type="text/javascript"> -(function() { - var inputEl = document.getElementById('email'), - errorEl = document.getElementById('error'), - errorTextEl = errorEl.querySelector('p'); - document.getElementById('reset').onclick = function() { - if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) { - socket.emit('user:reset.send', { email: inputEl.value }); - } else { - jQuery('#success').hide(); - jQuery(errorEl).show(); - errorTextEl.innerHTML = 'Please enter a valid email'; - } - }; - - ajaxify.register_events(['user.send_reset']); - - socket.on('user.send_reset', function(data) { - var submitEl = document.getElementById('reset'); - - if (data.status === 'ok') { - jQuery('#error').hide(); - jQuery('#success').show(); - jQuery('#success p').html('An email has been dispatched to "' + data.email + '" with instructions on setting a new password.'); - inputEl.value = ''; - } else { - jQuery('#success').hide(); - jQuery(errorEl).show(); - switch(data.message) { - case 'invalid-email': - errorTextEl.innerHTML = 'The email you put in (<span>' + data.email + '</span>) is not registered with us. Please try again.'; - break; - case 'send-failed': - errorTextEl.innerHTML = 'There was a problem sending the reset code. Please try again later.'; - break; - } - } - }); -}()); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/reset.js"></script> \ No newline at end of file diff --git a/public/templates/reset_code.tpl b/public/templates/reset_code.tpl index b791933bf6..a37d4534df 100644 --- a/public/templates/reset_code.tpl +++ b/public/templates/reset_code.tpl @@ -22,47 +22,4 @@ <input type="hidden" template-variable="reset_code" value="{reset_code}" /> -<script type="text/javascript"> -(function() { - var reset_code = templates.get('reset_code'); - - var resetEl = document.getElementById('reset'), - password = document.getElementById('password'), - repeat = document.getElementById('repeat'), - noticeEl = document.getElementById('notice'); - - resetEl.addEventListener('click', function() { - if (password.value.length < 6) { - $('#error').hide(); - noticeEl.querySelector('strong').innerHTML = 'Invalid Password'; - noticeEl.querySelector('p').innerHTML = 'The password entered it too short, please pick a different password!'; - noticeEl.style.display = 'block'; - } else if (password.value === repeat.value) { - socket.emit('user:reset.commit', { code: reset_code, password: password.value }); - } - }, false); - - // Enable the form if the code is valid - socket.emit('user:reset.valid', { code: reset_code }); - - - ajaxify.register_events(['user:reset.valid', 'user:reset.commit']); - socket.on('user:reset.valid', function(data) { - if (!!data.valid) resetEl.disabled = false; - else { - var formEl = document.getElementById('reset-form'); - // Show error message - $('#error').show(); - formEl.parentNode.removeChild(formEl); - } - }) - - socket.on('user:reset.commit', function(data) { - if (data.status === 'ok') { - $('#error').hide(); - $('#notice').hide(); - $('#success').show(); - } - }); -}()); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/reset_code.js"></script> \ No newline at end of file diff --git a/public/templates/topic.tpl b/public/templates/topic.tpl index 66bd53fb9f..90f628fdce 100644 --- a/public/templates/topic.tpl +++ b/public/templates/topic.tpl @@ -123,608 +123,4 @@ -<script type="text/javascript"> - (function() { - var expose_tools = templates.get('expose_tools'), - tid = templates.get('topic_id'), - postListEl = document.getElementById('post-container'), - editBtns = document.querySelectorAll('#post-container .post-buttons .edit, #post-container .post-buttons .edit i'), - thread_state = { - locked: templates.get('locked'), - deleted: templates.get('deleted'), - pinned: templates.get('pinned') - }, - topic_name = templates.get('topic_name'); - - function addCommasToNumbers() { - $('.formatted-number').each(function(index, element) { - $(element).html(app.addCommas($(element).html())); - }); - } - - jQuery('document').ready(function() { - - addCommasToNumbers(); - - var room = 'topic_' + tid, - adminTools = document.getElementById('thread-tools'); - - app.enter_room(room); - set_up_posts(); - - if (thread_state.locked === '1') set_locked_state(true); - if (thread_state.deleted === '1') set_delete_state(true); - if (thread_state.pinned === '1') set_pinned_state(true); - - if (expose_tools === '1') { - var deleteThreadEl = document.getElementById('delete_thread'), - lockThreadEl = document.getElementById('lock_thread'), - pinThreadEl = document.getElementById('pin_thread'), - moveThreadEl = document.getElementById('move_thread'), - moveThreadModal = $('#move_thread_modal'); - - adminTools.style.visibility = 'inherit'; - - // Add events to the thread tools - deleteThreadEl.addEventListener('click', function(e) { - e.preventDefault(); - if (thread_state.deleted !== '1') { - if (confirm('really delete thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) { - socket.emit('api:topic.delete', { tid: tid }); - } - } else { - if (confirm('really restore thread? (THIS DIALOG TO BE REPLACED WITH BOOTBOX)')) { - socket.emit('api:topic.restore', { tid: tid }); - } - } - }, false); - - lockThreadEl.addEventListener('click', function(e) { - e.preventDefault(); - if (thread_state.locked !== '1') { - socket.emit('api:topic.lock', { tid: tid }); - } else { - socket.emit('api:topic.unlock', { tid: tid }); - } - }, false); - - pinThreadEl.addEventListener('click', function(e) { - e.preventDefault(); - if (thread_state.pinned !== '1') { - socket.emit('api:topic.pin', { tid: tid }); - } else { - socket.emit('api:topic.unpin', { tid: tid }); - } - }, false); - - moveThreadEl.addEventListener('click', function(e) { - e.preventDefault(); - moveThreadModal.modal('show'); - }, false); - - moveThreadModal.on('shown', function() { - var loadingEl = document.getElementById('categories-loading'); - if (loadingEl) { - socket.once('api:categories.get', function(data) { - // Render categories - var categoriesFrag = document.createDocumentFragment(), - categoryEl = document.createElement('li'), - numCategories = data.categories.length, - modalBody = moveThreadModal.find('.modal-body'), - categoriesEl = modalBody[0].getElementsByTagName('ul')[0], - confirmDiv = document.getElementById('move-confirm'), - confirmCat = confirmDiv.getElementsByTagName('span')[0], - commitEl = document.getElementById('move_thread_commit'), - cancelEl = document.getElementById('move_thread_cancel'), - x, info, targetCid, targetCatLabel; - - categoriesEl.className = 'category-list'; - for(x=0;x<numCategories;x++) { - info = data.categories[x]; - categoryEl.className = info.blockclass; - categoryEl.innerHTML = '<i class="' + info.icon + '"></i> ' + info.name; - categoryEl.setAttribute('data-cid', info.cid); - categoriesFrag.appendChild(categoryEl.cloneNode(true)); - } - categoriesEl.appendChild(categoriesFrag); - modalBody[0].removeChild(loadingEl); - - categoriesEl.addEventListener('click', function(e) { - if (e.target.nodeName === 'LI') { - confirmCat.innerHTML = e.target.innerHTML; - confirmDiv.style.display = 'block'; - targetCid = e.target.getAttribute('data-cid'); - targetCatLabel = e.target.innerHTML; - commitEl.disabled = false; - } - }, false); - - commitEl.addEventListener('click', function() { - if (!commitEl.disabled && targetCid) { - commitEl.disabled = true; - $(cancelEl).fadeOut(250); - $(moveThreadModal).find('.modal-header button').fadeOut(250); - commitEl.innerHTML = 'Moving <i class="icon-spin icon-refresh"></i>'; - - socket.once('api:topic.move', function(data) { - moveThreadModal.modal('hide'); - if (data.status === 'ok') { - app.alert({ - 'alert_id': 'thread_move', - type: 'success', - title: 'Topic Successfully Moved', - message: 'This topic has been successfully moved to ' + targetCatLabel, - timeout: 5000 - }); - } else { - app.alert({ - 'alert_id': 'thread_move', - type: 'error', - title: 'Unable to Move Topic', - message: 'This topic could not be moved to ' + targetCatLabel + '.<br />Please try again later', - timeout: 5000 - }); - } - }); - socket.emit('api:topic.move', { tid: tid, cid: targetCid }); - } - }); - }); - socket.emit('api:categories.get'); - } - }); - } - - // Fix delete state for this thread's posts - var postEls = document.querySelectorAll('#post-container li[data-deleted]'); - for(var x=0,numPosts=postEls.length;x<numPosts;x++) { - if (postEls[x].getAttribute('data-deleted') === '1') toggle_post_delete_state(postEls[x].getAttribute('data-pid')); - postEls[x].removeAttribute('data-deleted'); - } - }); - - - $('.post-container').delegate('.edit', 'click', function(e) { - var pid = ($(this).attr('id') || $(this.parentNode).attr('id')).split('_')[1]; - - var main = $(this).parents('.main-post'); - if(main.length > 0) - app.open_post_window('edit', tid, topic_name, pid); - else - app.open_post_window('edit', tid, "", pid); - - }); - - $('.post-container').delegate('.delete', 'click', function(e) { - var pid = ($(this).attr('id') || $(this.parentNode).attr('id')).split('_')[1], - postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')), - deleteAction = !postEl.hasClass('deleted') ? true : false, - confirmDel = confirm((deleteAction ? 'Delete' : 'Restore') + ' this post?'); - - if (confirmDel) { - deleteAction ? - socket.emit('api:posts.delete', { pid: pid }) : - socket.emit('api:posts.restore', { pid: pid }); - } - }); - - // CHAT, move to chat.js later? - - $('.post-container').delegate('.chat', 'click', function(e){ - - var username = $(this).parents('li').attr('data-username'); - var touid = $(this).parents('li').attr('data-uid'); - - var chatModal = createModalIfDoesntExist(username, touid); - - chatModal.show(); - bringModalToTop(chatModal); - - }); - - function bringModalToTop(chatModal) { - var topZ = 0; - $('.modal').each(function(){ - var thisZ = parseInt($(this).css('zIndex'), 10); - if (thisZ > topZ){ - topZ = thisZ; - } - }); - chatModal.css('zIndex', topZ+1); - } - - function createModalIfDoesntExist(username, touid) { - var chatModal = $('#chat-modal-'+touid); - - if(!chatModal.length) { - var chatModal = $('#chat-modal').clone(); - chatModal.attr('id','chat-modal-'+touid); - chatModal.appendTo($('body')); - chatModal.draggable({ - start:function(){ - bringModalToTop(chatModal); - } - }); - chatModal.find('#chat-with-name').html(username); - - chatModal.find('.close').on('click',function(e){ - chatModal.hide(); - }); - - chatModal.on('click', function(e){ - bringModalToTop(chatModal); - }); - - addSendHandler(chatModal, touid); - } - - return chatModal; - } - - function addSendHandler(chatModal, touid) { - chatModal.find('#chat-message-input').off('keypress'); - chatModal.find('#chat-message-input').on('keypress', function(e) { - if(e.which === 13) { - sendMessage(chatModal, touid); - } - }); - - chatModal.find('#chat-message-send-btn').off('click'); - chatModal.find('#chat-message-send-btn').on('click', function(e){ - sendMessage(chatModal, touid); - return false; - }); - } - - function sendMessage(chatModal, touid) { - var msg = app.strip_tags(chatModal.find('#chat-message-input').val()); - if(msg.length) { - msg = msg +'\n'; - socket.emit('sendChatMessage', { touid:touid, message:msg}); - chatModal.find('#chat-message-input').val(''); - appendChatMessage(chatModal, 'You : ' + msg); - } - } - - socket.on('chatMessage', function(data){ - var username = data.username; - var fromuid = data.fromuid; - var message = data.message; - - var chatModal = createModalIfDoesntExist(username, fromuid); - chatModal.show(); - bringModalToTop(chatModal); - - appendChatMessage(chatModal, message) - }); - - function appendChatMessage(chatModal, message){ - var chatContent = chatModal.find('#chat-content'); - chatContent.append(message); - chatContent.scrollTop( - chatContent[0].scrollHeight - chatContent.height() - ); - } - //end of chat - - - ajaxify.register_events([ - 'event:rep_up', 'event:rep_down', 'event:new_post', 'api:get_users_in_room', - 'event:topic_deleted', 'event:topic_restored', 'event:topic:locked', - 'event:topic_unlocked', 'event:topic_pinned', 'event:topic_unpinned', - 'event:topic_moved', 'event:post_edited', 'event:post_deleted', 'event:post_restored', - 'api:posts.favourite', 'chatMessage' - ]); - - - socket.on('api:get_users_in_room', function(users) { - var anonymous = users.anonymous, - usernames = users.usernames, - usercount = usernames.length; - - for (var i = 0, ii=usercount; i<ii; i++) { - usernames[i] = '<strong>' + '<a href="/users/'+usernames[i]+'">' + usernames[i] + '</a></strong>'; - } - - // headexplosion.gif for fun, to see if I could do this in one line of code. feel free to refactor haha - var active = - ((usercount === 1) ? usernames[0] : '') - + ((usercount === 2 && anonymous === 0) ? usernames[0] + ' and ' + usernames[1] : '') - + ((usercount > 2 && anonymous === 0) ? usernames.join(', ').replace(/,([^,]*)$/, ", and$1") : '') - + (usercount > 1 && anonymous > 0 ? usernames.join(', ') : '') - + ((anonymous > 0) ? (usercount > 0 ? ' and ': '') + anonymous + ' guest' + (anonymous > 1 ? 's are': ' is') : '') - + (anonymous === 0 ? (usercount > 1 ? ' are' : ' is') : '') + ' browsing this thread'; - - document.getElementById('thread_active_users').innerHTML = active; - }); - - socket.on('event:rep_up', function(data) { - adjust_rep(1, data.pid, data.uid); - }); - - socket.on('event:rep_down', function(data) { - adjust_rep(-1, data.pid, data.uid); - }); - - socket.on('event:new_post', function(data) { - var html = templates.prepare(templates['topic'].blocks['posts']).parse(data), - uniqueid = new Date().getTime(); - - jQuery('<div id="' + uniqueid + '"></div>') - .appendTo("#post-container") - .hide() - .append(html) - .fadeIn('slow'); - - set_up_posts(uniqueid); - - addCommasToNumbers(); - }); - - socket.on('event:topic_deleted', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_locked_state(true); - set_delete_state(true); - } - }); - - socket.on('event:topic_restored', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_locked_state(false); - set_delete_state(false); - } - }); - - socket.on('event:topic_locked', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_locked_state(true, 1); - } - }); - - socket.on('event:topic_unlocked', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_locked_state(false, 1); - } - }); - - socket.on('event:topic_pinned', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_pinned_state(true, 1); - } - }); - - socket.on('event:topic_unpinned', function(data) { - if (data.tid === tid && data.status === 'ok') { - set_pinned_state(false, 1); - } - }); - - socket.on('event:topic_moved', function(data) { - if (data && data.tid > 0) ajaxify.go('topic/' + data.tid); - }); - - socket.on('event:post_edited', function(data) { - var editedPostEl = document.getElementById('content_' + data.pid); - - var editedPostTitle = $('#topic_title_'+data.pid); - - if(editedPostTitle.length > 0) { - editedPostTitle.fadeOut(250, function() { - editedPostTitle.html(data.title); - editedPostTitle.fadeIn(250); - }); - } - - $(editedPostEl).fadeOut(250, function() { - this.innerHTML = data.content; - $(this).fadeIn(250); - }); - }); - - socket.on('api:posts.favourite', function(data) { - if (data.status !== 'ok' && data.pid) { - var favEl = document.querySelector('.post_rep_' + data.pid).nextSibling; - if (favEl) favEl.className = 'icon-star-empty'; - } - }); - - socket.on('event:post_deleted', function(data) { - if (data.pid) toggle_post_delete_state(data.pid, true); - }); - - socket.on('event:post_restored', function(data) { - if (data.pid) toggle_post_delete_state(data.pid, true); - }); - - function adjust_rep(value, pid, uid) { - var post_rep = jQuery('.post_rep_' + pid), - user_rep = jQuery('.user_rep_' + uid); - - var ptotal = parseInt(post_rep.html(), 10), - utotal = parseInt(user_rep.html(), 10); - - ptotal += value; - utotal += value; - - post_rep.html(ptotal); - user_rep.html(utotal); - } - - - function set_up_posts(div) { - if (div == null) div = ''; - else div = '#' + div; - - jQuery(div + ' .post_reply').click(function() { - if (thread_state.locked !== '1') app.open_post_window('reply', tid, topic_name); - }); - - jQuery(div + ' .quote').click(function() { - if (thread_state.locked !== '1') app.open_post_window('quote', tid, topic_name); - - var pid = $(this).parents('li').attr('data-pid'); - - $('#post_content').val('> ' + $('#content_' + pid).html() + '\n'); - console.log("POST ID "+pid); - }); - - jQuery(div + ' .edit, ' + div + ' .delete').each(function() { - var ids = this.id.replace('ids_', '').split('_'), - pid = ids[0], - uid = ids[1]; - - }); - - jQuery(div + ' .favourite').click(function() { - var ids = this.id.replace('favs_', '').split('_'), - pid = ids[0], - uid = ids[1]; - - if (thread_state.locked !== '1') { - if (this.children[1].className == 'icon-star-empty') { - this.children[1].className = 'icon-star'; - socket.emit('api:posts.favourite', {pid: pid, room_id: app.current_room}); - } - else { - this.children[1].className = 'icon-star-empty'; - socket.emit('api:posts.unfavourite', {pid: pid, room_id: app.current_room}); - } - } - }); - } - - function set_locked_state(locked, alert) { - var threadReplyBtn = document.getElementById('post_reply'), - postReplyBtns = document.querySelectorAll('#post-container .post_reply'), - quoteBtns = document.querySelectorAll('#post-container .quote'), - editBtns = document.querySelectorAll('#post-container .edit'), - deleteBtns = document.querySelectorAll('#post-container .delete'), - numReplyBtns = postReplyBtns.length, - lockThreadEl = document.getElementById('lock_thread'), - x; - - if (locked === true) { - lockThreadEl.innerHTML = '<i class="icon-unlock"></i> Unlock Thread'; - threadReplyBtn.disabled = true; - threadReplyBtn.innerHTML = 'Locked <i class="icon-lock"></i>'; - for(x=0;x<numReplyBtns;x++) { - postReplyBtns[x].innerHTML = 'Locked <i class="icon-lock"></i>'; - quoteBtns[x].style.display = 'none'; - editBtns[x].style.display = 'none'; - deleteBtns[x].style.display = 'none'; - } - - if (alert) { - app.alert({ - 'alert_id': 'thread_lock', - type: 'success', - title: 'Thread Locked', - message: 'Thread has been successfully locked', - timeout: 5000 - }); - } - - thread_state.locked = '1'; - } else { - lockThreadEl.innerHTML = '<i class="icon-lock"></i> Lock Thread'; - threadReplyBtn.disabled = false; - threadReplyBtn.innerHTML = 'Reply'; - for(x=0;x<numReplyBtns;x++) { - postReplyBtns[x].innerHTML = 'Reply <i class="icon-reply"></i>'; - quoteBtns[x].style.display = 'inline-block'; - editBtns[x].style.display = 'inline-block'; - deleteBtns[x].style.display = 'inline-block'; - } - - if (alert) { - app.alert({ - 'alert_id': 'thread_lock', - type: 'success', - title: 'Thread Unlocked', - message: 'Thread has been successfully unlocked', - timeout: 5000 - }); - } - - thread_state.locked = '0'; - } - } - - function set_delete_state(deleted) { - var deleteThreadEl = document.getElementById('delete_thread'), - deleteTextEl = deleteThreadEl.getElementsByTagName('span')[0], - threadEl = document.querySelector('.post-container'), - deleteNotice = document.getElementById('thread-deleted') || document.createElement('div'); - - if (deleted) { - deleteTextEl.innerHTML = '<i class="icon-comment"></i> Restore Thread'; - $(threadEl).addClass('deleted'); - - // Spawn a 'deleted' notice at the top of the page - deleteNotice.setAttribute('id', 'thread-deleted'); - deleteNotice.className = 'alert'; - deleteNotice.innerHTML = 'This thread has been deleted. Only users with thread management privileges can see it.'; - document.getElementById('content').insertBefore(deleteNotice, threadEl); - - thread_state.deleted = '1'; - } else { - deleteTextEl.innerHTML = '<i class="icon-trash"></i> Delete Thread'; - $(threadEl).removeClass('deleted'); - deleteNotice.parentNode.removeChild(deleteNotice); - - thread_state.deleted = '0'; - } - } - - function set_pinned_state(pinned, alert) { - var pinEl = document.getElementById('pin_thread'); - - if (pinned) { - pinEl.innerHTML = '<i class="icon-pushpin"></i> Unpin Thread'; - if (alert) { - app.alert({ - 'alert_id': 'thread_pin', - type: 'success', - title: 'Thread Pinned', - message: 'Thread has been successfully pinned', - timeout: 5000 - }); - } - - thread_state.pinned = '1'; - } else { - pinEl.innerHTML = '<i class="icon-pushpin"></i> Pin Thread'; - if (alert) { - app.alert({ - 'alert_id': 'thread_pin', - type: 'success', - title: 'Thread Unpinned', - message: 'Thread has been successfully unpinned', - timeout: 5000 - }); - } - - thread_state.pinned = '0'; - } - } - - function toggle_post_delete_state(pid) { - var postEl = $(document.querySelector('#post-container li[data-pid="' + pid + '"]')); - quoteEl = $(postEl[0].querySelector('.quote')), - favEl = $(postEl[0].querySelector('.favourite')), - replyEl = $(postEl[0].querySelector('.post_reply')); - - if (!postEl.hasClass('deleted')) { - quoteEl.addClass('none'); - favEl.addClass('none'); - replyEl.addClass('none'); - } else { - quoteEl.removeClass('none'); - favEl.removeClass('none'); - replyEl.removeClass('none'); - } - - postEl.toggleClass('deleted'); - } - })(); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/topic.js"></script> \ No newline at end of file diff --git a/public/templates/users.tpl b/public/templates/users.tpl index 684a28a875..65d64dad22 100644 --- a/public/templates/users.tpl +++ b/public/templates/users.tpl @@ -20,23 +20,4 @@ <!-- END users --> </div> -<script> -(function() { - - - - $(document).ready(function() { - - $('.reputation').each(function(index, element) { - $(element).html(app.addCommas($(element).html())); - }); - - $('.postcount').each(function(index, element) { - $(element).html(app.addCommas($(element).html())); - }); - - }); - - -}()); -</script> \ No newline at end of file +<script type="text/javascript" src="/src/forum/users.js"></script> \ No newline at end of file