diff --git a/README.md b/README.md index 8ddc2cccc8..a957c41380 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,11 @@ Please support NodeBB development! Check out our IndieGoGo campaign and like, sh ## Requirements -NodeBB requires a version of Node.js at least 0.8 or greater, and a Redis version 2.6 or greater. +NodeBB requires the following software to be installed: + +* A version of Node.js at least 0.8 or greater +* Redis, version 2.6 or greater. +* nginx, version 1.3.13 or greater ## Installation diff --git a/public/css/home.less b/public/css/home.less index 4ebc7335bf..47b90048cb 100644 --- a/public/css/home.less +++ b/public/css/home.less @@ -101,69 +101,87 @@ @-webkit-keyframes scroll-2 /* Safari and Chrome */ { - 0% {top: 0px;} - 25% {top: -90px;} - 50% {top: -180px;} - 75% {top: -270px;} + 0% {top: 0px;} + 3% {top:-90px;} + 25% {top: -90px;} + 28% {top:-180px;} + 50% {top: -180px;} + 53% {top: -270px;}; + 75% {top: -270px;} + 78% {top: -360px;} 100% {top: -360px;} } @keyframes scroll-2 { - 0% {top: 0px;} - 25% {top: -90px;} - 50% {top: -180px;} - 75% {top: -270px;} + 0% {top: 0px;} + 3% {top:-90px;} + 25% {top: -90px;} + 28% {top:-180px;} + 50% {top: -180px;} + 53% {top: -270px;}; + 75% {top: -270px;} + 78% {top: -360px;} 100% {top: -360px;} } @-webkit-keyframes scroll-1 /* Safari and Chrome */ { - 0% {top: 0px;} - 33% {top: -90px;} - 66% {top: -180px;} - 100% {top: -270px;} + 0% {top: 0px;} + 3% {top:-90px;} + 33% {top: -90px;} + 36% {top: -180px;} + 66% {top: -180px;} + 69% {top: -270px;} + 100% {top: -270px;} } @keyframes scroll-1 { - 0% {top: 0px;} - 33% {top: -90px;} - 66% {top: -180px;} - 100% {top: -270px;} + 0% {top: 0px;} + 3% {top:-90px;} + 33% {top: -90px;} + 36% {top: -180px;} + 66% {top: -180px;} + 69% {top: -270px;} + 100% {top: -270px;} } @-webkit-keyframes scroll-0 /* Safari and Chrome */ { - 0% {top: 0px;} - 50% {top: -90px;} - 100% {top: -180px;} + 0% {top: 0px;} + 3% {top:-90px;} + 50% {top: -90px;} + 53% {top: -180px;} + 100% {top: -180px;} } @keyframes scroll-0 { - 0% {top: 0px;} - 50% {top: -90px;} - 100% {top: -180px;} + 0% {top: 0px;} + 3% {top:-90px;} + 50% {top: -90px;} + 53% {top: -180px;} + 100% {top: -180px;} } .category-slider-2:hover { position:relative; - -webkit-animation: scroll-2 10s ease 0.5s infinite normal; - animation: scroll-2 10s ease 0.5s infinite normal;/* Safari and Chrome: */ + -webkit-animation: scroll-2 10s ease-in 0.5s infinite normal; + animation: scroll-2 10s ease-in 0.5s infinite normal;/* Safari and Chrome: */ } .category-slider-1:hover { position:relative; - -webkit-animation: scroll-1 8s ease 0.5s infinite normal; - animation: scroll-1 8s ease 0.5s infinite normal;/* Safari and Chrome: */ + -webkit-animation: scroll-1 8s ease-in 0.5s infinite normal; + animation: scroll-1 8s ease-in 0.5s infinite normal;/* Safari and Chrome: */ } .category-slider-0:hover { position:relative; - -webkit-animation: scroll-0 6s ease 0.5s infinite normal; - animation: scroll-0 6s ease 0.5s infinite normal;/* Safari and Chrome: */ + -webkit-animation: scroll-0 6s ease-in 0.5s infinite normal; + animation: scroll-0 6s ease-in 0.5s infinite normal;/* Safari and Chrome: */ } diff --git a/public/css/style.less b/public/css/style.less index d3697fdb95..63d77b030a 100644 --- a/public/css/style.less +++ b/public/css/style.less @@ -136,10 +136,6 @@ footer.footer { } } -#right-menu{ - float:right; -} - #chat-content { height:200px; resize:none; @@ -257,6 +253,11 @@ footer.footer { /* END: post-window needs to go in its own plugin area */ +//theme +#search-form .btn-link { + color: white; +} + //START: FIXES FOR BS3, may need to remove these when we get out of the RC releases @media (max-width: 979px) { @@ -266,9 +267,11 @@ footer.footer { } } -.container > .navbar-header, .container > .navbar-collapse { - padding-right: 0; - margin-right: -11px; +@media (min-width: 760px) { + .container > .navbar-header, .container > .navbar-collapse { + padding-right: 0; + margin-right: -11px; + } } .badge { diff --git a/public/css/topic.less b/public/css/topic.less index 0b80dc8ee8..b70772e9af 100644 --- a/public/css/topic.less +++ b/public/css/topic.less @@ -152,36 +152,38 @@ } .main-post { - h3 { - margin: 0; - - .topic-title { - width: auto; - overflow: hidden; - margin: 0 0 -5px 0; - padding: 0 0 5px 0 + .main-post-buttons { + h3 { + margin: 0; + + .topic-title { + width: auto; + overflow: hidden; + margin: 0 0 -5px 0; + padding: 0 0 5px 0 + } } - } - .main-avatar { - color: white; - position: relative; - float: left; - margin: 0 10px 0 0; - padding-bottom: 0px; - text-align: center; - width:100px; + .main-avatar { + color: white; + position: relative; + float: left; + margin: 0 10px 0 0; + padding-bottom: 0px; + text-align: center; + width:100px; + + @media (max-width: 767px) { + display: none; + } - @media (max-width: 767px) { - display: none; + .img-thumbnail { + padding: 2px; + border-radius: 0; + } } } - .img-thumbnail { - padding: 2px; - border-radius: 0; - } - .post-content { min-height: 80px; } diff --git a/public/src/app.js b/public/src/app.js index 11341a9c78..a462e53b6f 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -15,7 +15,7 @@ var socket, API_URL = data.api_url; config = data; - socket = io.connect(config.socket.address + (config.socket.port ? ':' + config.socket.port : '')); + socket = io.connect(config.socket.address); var reconnecting = false; var reconnectTries = 0; @@ -314,6 +314,18 @@ var socket, }); } + app.openChat = function(username, touid) { + require(['chat'], function(chat) { + var chatModal; + if(!chat.modalExists(touid)) { + chatModal = chat.createModal(username, touid); + } else { + chatModal = chat.getModal(touid); + } + chat.load(chatModal.attr('UUID')); + }); + } + app.createNewPosts = function(data) { data.posts[0].display_moderator_tools = 'none'; var html = templates.prepare(templates['topic'].blocks['posts']).parse(data), diff --git a/public/src/forum/account.js b/public/src/forum/account.js index aba3eb33a1..516d9196f3 100644 --- a/public/src/forum/account.js +++ b/public/src/forum/account.js @@ -6,7 +6,7 @@ $(document).ready(function() { app.addCommasToNumbers(); - + var followBtn = $('#follow-btn'); var unfollowBtn = $('#unfollow-btn'); @@ -18,6 +18,9 @@ followBtn.show(); unfollowBtn.hide(); } + } else { + followBtn.hide(); + unfollowBtn.hide(); } followBtn.on('click', function() { @@ -51,20 +54,22 @@ $('.user-recent-posts .topic-row').on('click', function() { ajaxify.go($(this).attr('topic-url')); }); - + var onlineStatus = $('.account-online-status'); - - socket.on('api:user.isOnline', function(online) { - if(online) { + + function handleUserOnline(data) { + if(data.online) { onlineStatus.find('span span').text('online'); onlineStatus.find('i').attr('class', 'icon-circle'); } else { onlineStatus.find('span span').text('offline'); onlineStatus.find('i').attr('class', 'icon-circle-blank'); } - }); - - socket.emit('api:user.isOnline', theirid); + } + + socket.on('api:user.isOnline', handleUserOnline); + + socket.emit('api:user.isOnline', theirid, handleUserOnline); }); diff --git a/public/src/forum/followers.js b/public/src/forum/followers.js index 5e4ec7a00d..9093dcbd1e 100644 --- a/public/src/forum/followers.js +++ b/public/src/forum/followers.js @@ -5,14 +5,14 @@ followersCount = templates.get('followersCount'); $(document).ready(function() { - + if(parseInt(followersCount, 10) === 0) { - $('#no-followers-notice').show(); + $('#no-followers-notice').removeClass('hide'); } - + app.addCommasToNumbers(); - + }); - + }()); \ No newline at end of file diff --git a/public/src/forum/following.js b/public/src/forum/following.js index 836fc274ca..0353b72236 100644 --- a/public/src/forum/following.js +++ b/public/src/forum/following.js @@ -5,9 +5,9 @@ followingCount = templates.get('followingCount'); $(document).ready(function() { - + if(parseInt(followingCount, 10) === 0) { - $('#no-following-notice').show(); + $('#no-following-notice').removeClass('hide'); } @@ -18,7 +18,7 @@ $('.unfollow-btn').on('click',function() { var unfollowBtn = $(this); var followingUid = $(this).attr('followingUid'); - + socket.emit('api:user.unfollow', {uid: followingUid}, function(success) { var username = unfollowBtn.attr('data-username'); if(success) { @@ -34,6 +34,6 @@ app.addCommasToNumbers(); }); - + }()); \ No newline at end of file diff --git a/public/src/forum/footer.js b/public/src/forum/footer.js index c892b300eb..a67b349118 100644 --- a/public/src/forum/footer.js +++ b/public/src/forum/footer.js @@ -44,6 +44,16 @@ socket.on('api:updateHeader', function(data) { + jQuery('#search-button').on('click', function() { + jQuery('#search-fields').removeClass('hide').show(); + jQuery(this).hide(); + jQuery('#search-fields input').focus() + + jQuery('#search-form').on('submit', function() { + jQuery('#search-fields').hide(); + jQuery('#search-button').show(); + }); + }); var rightMenu = $('#right-menu'), isLoggedIn = data.uid > 0; @@ -162,25 +172,18 @@ socket.on('chatMessage', function(data) { require(['chat'], function(chat) { - var chatModal = chat.createModalIfDoesntExist(data.username, data.fromuid, function(created, modal) { - if(!created) - chat.appendChatMessage(modal, data.message, data.timestamp); - }); + var modal = null; + if(chat.modalExists(data.fromuid)) { + modal = chat.getModal(data.fromuid); + chat.appendChatMessage(modal, data.message, data.timestamp); + } else { + modal = chat.createModal(data.username, data.fromuid); + } - chatModal.show(); - chat.bringModalToTop(chatModal); + chat.load(modal.attr('UUID')); }); }); - socket.on('chatGoOffline', function(data) { - require(['chat'], function(chat) { - if(chat.modalOpen(data.uid)) { - var modal = chat.getModal(data.uid); - chat.appendChatMessage(modal, data.username + ' went offline\n', data.timestamp); - } - }); - }) - require(['mobileMenu'], function(mobileMenu) { mobileMenu.init(); }); diff --git a/public/src/forum/reset_code.js b/public/src/forum/reset_code.js index fffc3dadf3..3bc8906777 100644 --- a/public/src/forum/reset_code.js +++ b/public/src/forum/reset_code.js @@ -10,9 +10,14 @@ 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.querySelector('p').innerHTML = 'The password entered is too short, please pick a different password.'; noticeEl.style.display = 'block'; - } else if (password.value === repeat.value) { + } else if (password.value !== repeat.value) { + $('#error').hide(); + noticeEl.querySelector('strong').innerHTML = 'Invalid Password'; + noticeEl.querySelector('p').innerHTML = 'The two passwords you\'ve entered do not match.'; + noticeEl.style.display = 'block'; + } else { socket.emit('user:reset.commit', { code: reset_code, password: password.value }); } }, false); diff --git a/public/src/forum/topic.js b/public/src/forum/topic.js index 500cab3e84..752d703f87 100644 --- a/public/src/forum/topic.js +++ b/public/src/forum/topic.js @@ -67,7 +67,8 @@ return false; }); - moveThreadModal.on('shown', function() { + moveThreadModal.on('shown.bs.modal', function() { + var loadingEl = document.getElementById('categories-loading'); if (loadingEl) { socket.once('api:categories.get', function(data) { @@ -287,11 +288,7 @@ if(username === app.username || !app.username) return; - require(['chat'], function(chat) { - var chatModal = chat.createModalIfDoesntExist(username, touid); - chatModal.modal(); - chat.bringModalToTop(chatModal); // I don't think this is necessary - }); + app.openChat(username, touid); }); ajaxify.register_events([ @@ -379,6 +376,18 @@ this.innerHTML = data.content; $(this).fadeIn(250); }); + + if(data.uploadedImages && data.uploadedImages.length) { + $('#images_'+data.pid).html(''); + for(var i=0; i< data.uploadedImages.length; ++i) { + var img = $(' '+data.uploadedImages[i].name+'
'); + $('#images_' + data.pid).append(img); + } + } else { + $('#images_'+data.pid).html(''); + } + + console.log('time to recreate images', data); }); socket.on('api:posts.favourite', function(data) { diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 704bf16b5a..3c67a6e170 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -17,46 +17,74 @@ define(['taskbar'], function(taskbar) { return $('#chat-modal-' + touid); } - module.modalOpen = function(touid) { + module.modalExists = function(touid) { return $('#chat-modal-' + touid).length !== 0; } - module.createModalIfDoesntExist = function(username, touid, callback) { - var chatModal = $('#chat-modal-' + touid); - - if(!chatModal.length) { - var chatModal = $('#chat-modal').clone(); - chatModal.attr('id','chat-modal-' + touid); - var uuid = utils.generateUUID(); - chatModal.attr('UUID', uuid); - chatModal.appendTo($('body')); - chatModal.draggable({ - start:function(){ - module.bringModalToTop(chatModal); + + function checkStatus(chatModal, callback) { + socket.emit('api:user.isOnline', chatModal.touid, function(data) { + if(data.online !== chatModal.online) { + if(data.online) { + module.appendChatMessage(chatModal, chatModal.username + ' has come online.\n', data.timestamp); + } else { + module.appendChatMessage(chatModal, chatModal.username + ' has gone offline.\n', data.timestamp); } - }); - chatModal.find('#chat-with-name').html(username); - - chatModal.find('.close').on('click', function(e) { - chatModal.hide(); - taskbar.discard('chat', uuid); - }); - - chatModal.on('click', function(e) { + chatModal.online = data.online; + } + if(callback) + callback(data.online); + }); + } + + function checkOnlineStatus(chatModal) { + if(chatModal.intervalId === 0) { + chatModal.intervalId = setInterval(function(){ + checkStatus(chatModal); + }, 1000); + } + } + + module.createModal = function(username, touid, callback) { + + var chatModal = $('#chat-modal').clone(), + uuid = utils.generateUUID(); + + chatModal.intervalId = 0; + chatModal.touid = touid; + chatModal.username = username; + + chatModal.attr('id', 'chat-modal-' + touid); + chatModal.attr('UUID', uuid); + chatModal.appendTo($('body')); + chatModal.draggable({ + start:function() { module.bringModalToTop(chatModal); - }); - - addSendHandler(chatModal, touid); - - getChatMessages(chatModal, touid, callback); + } + }); + + chatModal.find('#chat-with-name').html(username); + + chatModal.find('.close').on('click', function(e) { + clearInterval(chatModal.intervalId); + chatModal.intervalId = 0; + chatModal.hide(); + taskbar.discard('chat', uuid); + }); - taskbar.push('chat', chatModal.attr('UUID'), {title:'chat with '+username}); - return chatModal; - } + chatModal.on('click', function(e) { + module.bringModalToTop(chatModal); + }); + + addSendHandler(chatModal); - if(callback) - callback(false, chatModal); + checkStatus(chatModal, function(online) { + chatModal.online = online; + getChatMessages(chatModal, function() { + checkOnlineStatus(chatModal); + }); + }); - taskbar.push('chat', chatModal.attr('UUID'), {title:'chat with '+username}); + taskbar.push('chat', chatModal.attr('UUID'), {title:'chat with ' + username}); return chatModal; } @@ -64,45 +92,46 @@ define(['taskbar'], function(taskbar) { var chatModal = $('div[UUID="'+uuid+'"]'); chatModal.show(); module.bringModalToTop(chatModal); + checkOnlineStatus(chatModal); } module.minimize = function(uuid) { var chatModal = $('div[UUID="'+uuid+'"]'); chatModal.hide(); taskbar.minimize('chat', uuid); + clearInterval(chatModal.intervalId); + chatModal.intervalId = 0; } - function getChatMessages(chatModal, touid, callback) { - socket.emit('getChatMessages', {touid:touid}, function(messages) { + function getChatMessages(chatModal, callback) { + socket.emit('getChatMessages', {touid:chatModal.touid}, function(messages) { for(var i = 0; i'+ img.name +''); + var imageLabel = $('' + img.name +''); var closeButton = $(''); closeButton.on('click', function(e) { @@ -152,7 +152,7 @@ define(['taskbar'], function(taskbar) { pid: threadData.pid, title: threadData.title || '', body: threadData.body || '', - images: [] + images: threadData.uploadedImages }; composer.load(uuid); } else { diff --git a/public/templates/account.tpl b/public/templates/account.tpl index 16e87313c6..aa9bfd8ccb 100644 --- a/public/templates/account.tpl +++ b/public/templates/account.tpl @@ -19,8 +19,8 @@ banned
- Follow - Unfollow + Follow + Unfollow
diff --git a/public/templates/following.tpl b/public/templates/following.tpl index c713b7a6a6..cbdc3d7911 100644 --- a/public/templates/following.tpl +++ b/public/templates/following.tpl @@ -25,7 +25,7 @@ {following.postcount} - Unfollow + Unfollow diff --git a/public/templates/footer.tpl b/public/templates/footer.tpl index 11b04261b9..85e9938b84 100644 --- a/public/templates/footer.tpl +++ b/public/templates/footer.tpl @@ -18,7 +18,7 @@ -