diff --git a/Workshop/01. HTTP & AJAX Workshop - Forum/bower.json b/Workshop/01. HTTP & AJAX Workshop - Forum/bower.json index 70af7f17..ba0ad0be 100644 --- a/Workshop/01. HTTP & AJAX Workshop - Forum/bower.json +++ b/Workshop/01. HTTP & AJAX Workshop - Forum/bower.json @@ -14,6 +14,7 @@ ], "dependencies": { "bootstrap": "~3.3.5", - "jquery": "~2.1.4" + "jquery": "~2.1.4", + "moment": "^2.15.1" } } diff --git a/Workshop/01. HTTP & AJAX Workshop - Forum/public/index.html b/Workshop/01. HTTP & AJAX Workshop - Forum/public/index.html index ee129181..56e23051 100644 --- a/Workshop/01. HTTP & AJAX Workshop - Forum/public/index.html +++ b/Workshop/01. HTTP & AJAX Workshop - Forum/public/index.html @@ -75,7 +75,7 @@

Threads

- Created on + Created by

@@ -114,18 +114,18 @@

+ + diff --git a/Workshop/01. HTTP & AJAX Workshop - Forum/public/scripts/main.js b/Workshop/01. HTTP & AJAX Workshop - Forum/public/scripts/main.js index daa3fe32..4572fea0 100644 --- a/Workshop/01. HTTP & AJAX Workshop - Forum/public/scripts/main.js +++ b/Workshop/01. HTTP & AJAX Workshop - Forum/public/scripts/main.js @@ -1,31 +1,31 @@ $(() => { // on document ready const GLYPH_UP = 'glyphicon-chevron-up', - GLYPH_DOWN = 'glyphicon-chevron-down', - root = $('#root'), - navbar = root.find('nav.navbar'), - mainNav = navbar.find('#main-nav'), - contentContainer = $('#root #content'), - loginForm = $('#login'), - logoutForm = $('#logout'), - usernameSpan = $('#span-username'), - usernameInput = $('#login input'), - alertTemplate = $($('#alert-template').text()); + GLYPH_DOWN = 'glyphicon-chevron-down', + root = $('#root'), + navbar = root.find('nav.navbar'), + mainNav = navbar.find('#main-nav'), + contentContainer = root.find('#content'), + loginForm = $('#login'), + logoutForm = $('#logout'), + usernameSpan = $('#span-username'), + usernameInput = loginForm.find('input'), + alertTemplate = $($('#alert-template').text()); (function checkForLoggedUser() { data.users.current() - .then((user) => { - if (user) { - usernameSpan.text(user); - loginForm.addClass('hidden'); - logoutForm.removeClass('hidden'); - } - }); + .then((user) => { + if (user) { + usernameSpan.text(user); + loginForm.addClass('hidden'); + logoutForm.removeClass('hidden'); + } + }); })(); function showMsg(msg, type, cssClass, delay) { let container = alertTemplate.clone(true) - .addClass(cssClass).text(`${type}: ${msg}`) - .appendTo(root); + .addClass(cssClass).text(`${type}: ${msg}`) + .appendTo(root); setTimeout(() => { container.remove(); @@ -33,62 +33,91 @@ } // start threads - function loadThreadsContent(threads) { + function loadThreadsContent() { let container = $($('#threads-container-template').text()), threadsContainer = container.find('#threads'); - function getThreadUI(title, id, creator, date) { - let template = $($('#thread-template').text()).attr('data-id', id), - threadTitle = template.find('.thread-title').text(title), - threadCreator = template.find('.thread-creator').text(creator || 'anonymous'), - threadDate = template.find('.thread-date').text(date || 'unknown'); + getThreads() + .then((threads) => threads.forEach((thread) => { + let currentThreadUI = getThreadUI(thread); + threadsContainer.append(currentThreadUI); + })); + + function getThreads() { + return data.threads.get() + .then((response) => response.result); + } + + function getThreadUI(thread) { + let dateString = getDateTimeAgoString(thread.postDate); + + let template = $($('#thread-template').text()).attr('data-id', thread.id), + threadTitle = template.find('.thread-title').text(thread.title), + threadCreator = template.find('.thread-creator') + .text(thread.username || 'anonymous'), + threadDate = template.find('.thread-date').text(dateString); return template.clone(true); } + + threadsContainer.append(getAddNewThreadUI()); + function getAddNewThreadUI() { let template = $($('#thread-new-template').html()); return template.clone(true); } - threads.forEach((th) => { - let currentThreadUI = getThreadUI(th.title, th.id, th.username, th.date); - threadsContainer.append(currentThreadUI); - }) - threadsContainer.append(getAddNewThreadUI()); - contentContainer.find('#container-thraeds').remove(); contentContainer.html('').prepend(container); } - function loadMessagesContent(data) { - let container = $($('#messages-container-template').text()), - messagesContainer = container.find('.panel-body'); - container.attr('data-thread-id', data.result.id); + function loadMessagesContent(threadId) { + let container = $($('#messages-container-template').text()); + let messagesContainer = container.find('.panel-body'); + container.attr('data-thread-id', threadId); - function getMsgUI(msg, author, date) { - let template = $($('#messages-template').text()); - template.find('.message-content').text(msg); - template.find('.message-creator').text(author || 'anonymous'); - template.find('.message-date').text(date || 'unknown'); - return template.clone(true); + getThread(threadId) + .then(loadThreadMessages); + + function getThread(threadId) { + return data.threads.getById(threadId) + .then((response) => response.result) + .catch((err) => showMsg(err, 'Error', 'alert-danger')); + } + + function loadThreadMessages(thread) { + container.find('.thread-title').text(thread.title); + messagesContainer.append(getAddNewMsgUI()); + + if (thread.messages && thread.messages.length > 0) { + thread.messages.forEach((msg) => { + appendNewMessage(messagesContainer, msg); + + }); + } + + contentContainer.append(container); } + function getAddNewMsgUI() { let template = $($('#message-new-template').html()); return template.clone(true); } + } - if (data.result.messages && data.result.messages.length > 0) { - data.result.messages.forEach((msg) => { - messagesContainer.append(getMsgUI(msg)) - }) - } else { - messagesContainer.append(getMsgUI('No messages!')) - } + function appendNewMessage(messagesContainer, message) { + messagesContainer.find('.add-message') + .before(getMsgUI(message)); + } - messagesContainer.append(getAddNewMsgUI()); + function getMsgUI(message) { + let dateString = getDateTimeAgoString(message.postDate); - container.find('.thread-title').text(data.result.title); - contentContainer.append(container); + let template = $($('#messages-template').text()); + template.find('.message-content').text(message.content); + template.find('.message-creator').text(message.username || 'anonymous'); + template.find('.message-date').text(dateString); + return template.clone(true); } function loadGalleryContent(data) { @@ -109,6 +138,16 @@ contentContainer.html('').append(containerGallery); } + function getDateTimeAgoString(date) { + let momentDate = moment(date, 'YYYY-MM-DD HH:mm Z'); + if (momentDate.isValid()) { + return momentDate.fromNow(); + } + else { + return 'on unknown date'; + } + } + navbar.on('click', 'li', (ev) => { let $target = $(ev.target); $target.parents('nav').find('li').removeClass('active'); @@ -116,28 +155,23 @@ }); navbar.on('click', '#btn-threads', (ev) => { - data.threads.get() - .then((data) => { - loadThreadsContent(data.result) - }) + loadThreadsContent(); }); contentContainer.on('click', '#btn-add-thread', (ev) => { let title = $(ev.target).parents('form').find('input#input-add-thread').val() || null; data.threads.add(title) - .then(/* add to UI */) - .then(showMsg('Successfuly added the new thread', 'Success', 'alert-success')) + .then(loadThreadsContent) + .then(showMsg('Successfully added the new thread', 'Success', 'alert-success')) .catch((err) => showMsg(JSON.parse(err.responseText).err, 'Error', 'alert-danger')); - }) + }); contentContainer.on('click', 'a.thread-title', (ev) => { let $target = $(ev.target), threadId = $target.parents('.thread').attr('data-id'); - data.threads.getById(threadId) - .then(loadMessagesContent) - .catch((err) => showMsg(err, 'Error', 'alert-danger')) - }) + loadMessagesContent(threadId); + }); contentContainer.on('click', '.btn-add-message', (ev) => { let $target = $(ev.target), @@ -146,20 +180,28 @@ msg = $container.find('.input-add-message').val(); data.threads.addMessage(thId, msg) - .then(/* add to UI */) - .then(showMsg('Successfuly added the new mssagee', 'Success', 'alert-success')) + .then(appendMessage) + .then(showMsg('Successfully added the new message', 'Success', 'alert-success')) .catch((err) => showMsg(JSON.parse(err.responseText).err, 'Error', 'alert-danger')); - }) + + function appendMessage(result) { + let last = result.messages.length - 1; + let message = result.messages[last]; + + appendNewMessage($(`[data-thread-id="${thId}"] .panel-body`), message); + } + }); contentContainer.on('click', '.btn-close-msg', (ev) => { - let msgContainer = $(ev.target).parents('.container-messages').remove(); + $(ev.target).parents('.container-messages').remove(); }); contentContainer.on('click', '.btn-collapse-msg', (ev) => { let $target = $(ev.target); if ($target.hasClass(GLYPH_UP)) { $target.removeClass(GLYPH_UP).addClass(GLYPH_DOWN); - } else { + } + else { $target.removeClass(GLYPH_DOWN).addClass(GLYPH_UP); } @@ -170,29 +212,29 @@ // start gallery navbar.on('click', '#btn-gallery', (ev) => { data.gallery.get() - .then(loadGalleryContent) - .catch(console.log) - }) + .then(loadGalleryContent) + .catch(console.log) + }); // end gallery // start login/logout navbar.on('click', '#btn-login', (ev) => { let username = usernameInput.val() || 'anonymous'; data.users.login(username) - .then((user) => { - usernameInput.val('') - usernameSpan.text(user); - loginForm.addClass('hidden'); - logoutForm.removeClass('hidden'); - }) + .then((user) => { + usernameInput.val(''); + usernameSpan.text(user); + loginForm.addClass('hidden'); + logoutForm.removeClass('hidden'); + }) }); navbar.on('click', '#btn-logout', (ev) => { data.users.logout() - .then(() => { - usernameSpan.text(''); - loginForm.removeClass('hidden'); - logoutForm.addClass('hidden'); - }) + .then(() => { + usernameSpan.text(''); + loginForm.removeClass('hidden'); + logoutForm.addClass('hidden'); + }) }); // end login/logout }); \ No newline at end of file