Introducing Pillar Framework
Refactor of pillar-server and pillar-web into a single python package. This simplifies the overall architecture of pillar applications. Special thanks @sybren and @venomgfx
This commit is contained in:
70
src/scripts/tutti/0_navbar.js
Normal file
70
src/scripts/tutti/0_navbar.js
Normal file
@@ -0,0 +1,70 @@
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip({'delay' : {'show': 1250, 'hide': 250}});
|
||||
$('[data-toggle="popover"]').popover();
|
||||
})
|
||||
|
||||
function NavbarTransparent() {
|
||||
|
||||
var startingpoint = 50;
|
||||
|
||||
$(window).on("load scroll", function () {
|
||||
|
||||
if ($(this).scrollTop() > startingpoint) {
|
||||
$('.navbar-overlay, .navbar-transparent').addClass('is-active');
|
||||
if(document.getElementById("project_context-header") !== null) {
|
||||
$('#project_context-header').addClass('is-offset');
|
||||
}
|
||||
} else {
|
||||
$('.navbar-overlay, .navbar-transparent').removeClass('is-active');
|
||||
if(document.getElementById("project_context-header") !== null) {
|
||||
$('#project_context-header').removeClass('is-offset');
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
NavbarTransparent();
|
||||
|
||||
|
||||
/* Status Bar */
|
||||
function statusBarSet(classes, html, icon_name, time){
|
||||
/* Utility to notify the user by temporarily flashing text on the project header
|
||||
Usage:
|
||||
'classes' can be: success, error, warning, info, default
|
||||
'html': the text to display, can contain html tags
|
||||
(in case of errors, it's better to use data.status + data.statusText instead )
|
||||
'icon_name': optional, sets a custom icon (otherwise an icon based on the class will be used)
|
||||
'time': optional, custom time in milliseconds for the text to be displayed
|
||||
*/
|
||||
|
||||
var icon = '';
|
||||
|
||||
if (!time) { time = 3000 };
|
||||
|
||||
if (!icon_name) {
|
||||
if (classes == 'error') {
|
||||
icon_name = 'pi-attention';
|
||||
} else if (classes == 'success') {
|
||||
icon_name = 'pi-check';
|
||||
} else if (classes == 'warning') {
|
||||
icon_name = 'pi-warning';
|
||||
} else if (classes == 'info') {
|
||||
icon_name = 'pi-info';
|
||||
} else {
|
||||
icon = '<i class="' + icon_name + '"></i>';
|
||||
};
|
||||
} else {
|
||||
icon = '<i class="' + icon_name + '"></i>';
|
||||
};
|
||||
|
||||
var text = icon + html;
|
||||
$("#project-statusbar").addClass('active ' + classes);
|
||||
$("#project-statusbar").html(text);
|
||||
|
||||
/* Back to normal */
|
||||
setTimeout(function(){
|
||||
$("#project-statusbar").removeAttr('class');
|
||||
$("#project-statusbar").html();
|
||||
}, time);
|
||||
};
|
||||
|
182
src/scripts/tutti/1_project-navigation.js
Normal file
182
src/scripts/tutti/1_project-navigation.js
Normal file
@@ -0,0 +1,182 @@
|
||||
function projectNavCollapse() {
|
||||
|
||||
$("#project-side-container").addClass('collapsed');
|
||||
$("ul.breadcrumb.context").addClass('active');
|
||||
|
||||
if (typeof Ps !== 'undefined'){
|
||||
Ps.destroy(document.getElementById('project_tree'));
|
||||
};
|
||||
};
|
||||
|
||||
function projectNavExpand() {
|
||||
|
||||
$("#project-side-container").removeClass('collapsed');
|
||||
$("ul.breadcrumb.context").removeAttr('class');
|
||||
|
||||
if (typeof Ps !== 'undefined'){
|
||||
Ps.initialize(document.getElementById('project_tree'), {suppressScrollX: true});
|
||||
}
|
||||
};
|
||||
|
||||
function projectNavCheck(){
|
||||
|
||||
/* Only run if there is a tree */
|
||||
if(document.getElementById("project_tree") !== null) {
|
||||
|
||||
var nav_status = Cookies.getJSON('bcloud_ui');
|
||||
|
||||
if (nav_status && nav_status.nav_collapsed) {
|
||||
if (nav_status.nav_collapsed == 'expanded') {
|
||||
projectNavExpand();
|
||||
|
||||
} else if ( nav_status.nav_collapsed == 'collapsed' ) {
|
||||
projectNavCollapse();
|
||||
}
|
||||
} else {
|
||||
projectNavExpand();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function projectNavToggle(){
|
||||
|
||||
var nav_status = Cookies.getJSON('bcloud_ui');
|
||||
|
||||
if (nav_status && nav_status.nav_collapsed) {
|
||||
if (nav_status.nav_collapsed == 'expanded') {
|
||||
|
||||
projectNavCollapse();
|
||||
setJSONCookie('bcloud_ui', 'nav_collapsed', 'collapsed');
|
||||
|
||||
} else if ( nav_status.nav_collapsed == 'collapsed' ) {
|
||||
|
||||
projectNavExpand();
|
||||
setJSONCookie('bcloud_ui', 'nav_collapsed', 'expanded');
|
||||
|
||||
}
|
||||
} else {
|
||||
projectNavCollapse();
|
||||
setJSONCookie('bcloud_ui', 'nav_collapsed', 'collapsed');
|
||||
}
|
||||
|
||||
$('#project_context-header').width($('#project_context-container').width());
|
||||
}
|
||||
|
||||
$(function () {
|
||||
|
||||
/* Check on first load */
|
||||
projectNavCheck();
|
||||
|
||||
$('.project_split, .project_nav-toggle-btn').on('click', function (e) {
|
||||
projectNavToggle();
|
||||
});
|
||||
|
||||
/* Only run if there is a tree */
|
||||
if(document.getElementById("project_tree") !== null) {
|
||||
|
||||
$(document).keypress(function(e) {
|
||||
var tag = e.target.tagName.toLowerCase();
|
||||
|
||||
/* Toggle when pressing [T] key */
|
||||
if(e.which == 116 && tag != 'input' && tag != 'textarea' && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
||||
projectNavToggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* Small utility to enable specific node_types under the Add New dropdown */
|
||||
/* It takes:
|
||||
* empty: Enable every item
|
||||
* false: Disable every item
|
||||
* array: Disable every item except a list of node_types, e.g: ['asset', 'group']
|
||||
*/
|
||||
function addMenuEnable(node_types){
|
||||
$("#item_add").parent().removeClass('disabled');
|
||||
$("ul.add_new-menu li[class^='button-']").hide().addClass('disabled');
|
||||
|
||||
if (node_types === undefined) {
|
||||
$("ul.add_new-menu li[class^='button-']").show().removeClass('disabled');
|
||||
} else if (node_types == false) {
|
||||
$("#item_add").parent().addClass('disabled');
|
||||
} else {
|
||||
$.each(node_types, function(index, value) {
|
||||
$("ul.add_new-menu li[class*='button-" + value +"']").show().removeClass('disabled');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addMenuDisable(node_types){
|
||||
$.each(node_types, function(index, value) {
|
||||
$("ul.add_new-menu li[class*='button-" + value +"']").addClass('disabled');
|
||||
});
|
||||
}
|
||||
|
||||
/* Completely hide specific items (like Texture when on project root) */
|
||||
function addMenuHide(node_types){
|
||||
$.each(node_types, function(index, value) {
|
||||
$("ul.add_new-menu li[class*='button-" + value +"']").hide().addClass('disabled');
|
||||
});
|
||||
}
|
||||
|
||||
/* Jump to the top of the page! */
|
||||
function hopToTop(limit){
|
||||
if (limit == null) {
|
||||
limit = 500;
|
||||
}
|
||||
|
||||
document.getElementById("hop").onclick = function(e){ window.scrollTo(0, 0);}
|
||||
|
||||
$(window).scroll(function() {
|
||||
if ($(window).scrollTop() >= limit) {$("#hop").addClass("active")} else {$("#hop").removeAttr("class")}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* Utility to replace a single item on a JSON cookie */
|
||||
function setJSONCookie(cookieToChange, cookieItem, cookieData){
|
||||
|
||||
/* Get cookie to change, and its list if it has any */
|
||||
var cookieList = Cookies.getJSON(cookieToChange);
|
||||
|
||||
/* Create an empty list if there's no cookie */
|
||||
if (!cookieList){ cookieList = {}; }
|
||||
|
||||
cookieList[cookieItem] = cookieData;
|
||||
|
||||
/* Set (or create) cookie */
|
||||
Cookies.set(cookieToChange, cookieList);
|
||||
}
|
||||
|
||||
|
||||
function containerResizeY(window_height){
|
||||
|
||||
var container_offset = $('#project-container').offset();
|
||||
var container_height = window_height - container_offset.top;
|
||||
var container_height_wheader = window_height - container_offset.top - $('#project_nav-header').height();
|
||||
var window_height_minus_nav = $('#project_nav').height() - $('#project_nav-header').height();
|
||||
|
||||
$('#project_context-header').width($('#project_context-container').width());
|
||||
|
||||
$('#project_nav-container, .project_split').css(
|
||||
{'max-height': window_height_minus_nav + 'px',
|
||||
'height': window_height_minus_nav + 'px'}
|
||||
);
|
||||
|
||||
if ($(window).width() > 768) {
|
||||
if (container_height > parseInt($('#project-container').css("min-height"))) {
|
||||
if (projectTree){
|
||||
$(projectTree).css(
|
||||
{'max-height': container_height_wheader + 'px',
|
||||
'height': container_height_wheader + 'px'}
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (projectTree){ Ps.update(projectTree) }
|
||||
|
||||
};
|
109
src/scripts/tutti/2_comments.js
Normal file
109
src/scripts/tutti/2_comments.js
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
/* Reply */
|
||||
$(document).on('click','body .comment-action-reply',function(e){
|
||||
e.preventDefault();
|
||||
|
||||
// container of the comment we are replying to
|
||||
var parentDiv = $(this).parent().parent();
|
||||
|
||||
// container of the first-level comment in the thread
|
||||
var parentDivFirst = $(this).parent().parent().prevAll('.is-first:first');
|
||||
|
||||
// Get the id of the comment
|
||||
if (parentDiv.hasClass('is-reply')) {
|
||||
parentNodeId = parentDivFirst.data('node_id');
|
||||
} else {
|
||||
parentNodeId = parentDiv.data('node_id');
|
||||
}
|
||||
|
||||
// Get the textarea and set its parent_id data
|
||||
var commentField = document.getElementById('comment_field');
|
||||
commentField.setAttribute('data-parent_id', parentNodeId);
|
||||
|
||||
// Start the comment field with @authorname:
|
||||
var replyAuthor = $(this).parent().parent().find('.comment-author:first').html();
|
||||
$(commentField).val("**@" + replyAuthor + ":** ");
|
||||
|
||||
// Add class for styling
|
||||
$('.comment-container').removeClass('is-replying');
|
||||
parentDiv.addClass('is-replying');
|
||||
|
||||
// Rename Post Comment button to Reply
|
||||
var commentSubmitButton = document.getElementById('comment_submit');
|
||||
$(commentSubmitButton).text('Post Reply');
|
||||
|
||||
// Move comment-reply container field after the parent container
|
||||
var commentForm = $('.comment-reply-container').detach();
|
||||
parentDiv.after(commentForm);
|
||||
// document.getElementById('comment_field').focus();
|
||||
$(commentField).focus();
|
||||
|
||||
// Convert Markdown
|
||||
var convert = new Markdown.getSanitizingConverter().makeHtml;
|
||||
var preview = $('.comment-reply-preview');
|
||||
preview.html(convert($(commentField).val()));
|
||||
$('.comment-reply-form').addClass('filled');
|
||||
});
|
||||
|
||||
|
||||
/* Cancel Reply */
|
||||
$(document).on('click','body .comment-action-cancel',function(e){
|
||||
e.preventDefault();
|
||||
|
||||
$('.comment-reply-container').detach().prependTo('#comments-list');
|
||||
var commentField = document.getElementById('comment_field');
|
||||
$(commentField).val('');
|
||||
// Convert Markdown
|
||||
var convert = new Markdown.getSanitizingConverter().makeHtml;
|
||||
var preview = $('.comment-reply-preview');
|
||||
preview.html(convert($(commentField).val()));
|
||||
|
||||
var commentSubmitButton = document.getElementById('comment_submit');
|
||||
$(commentSubmitButton).text('Post Comment');
|
||||
|
||||
$('.comment-reply-form').removeClass('filled');
|
||||
$('.comment-container').removeClass('is-replying');
|
||||
});
|
||||
|
||||
|
||||
/* Rate */
|
||||
$(document).on('click','body .comment-action-rating',function(e){
|
||||
e.preventDefault();
|
||||
|
||||
var $this = $(this);
|
||||
var nodeId = $this.parent().parent().parent().data('node_id');
|
||||
var is_positive = !$this.hasClass('down');
|
||||
var parentDiv = $this.parent();
|
||||
var rated_positive = parentDiv.hasClass('positive');
|
||||
|
||||
var op;
|
||||
if (parentDiv.hasClass('rated') && is_positive == rated_positive) {
|
||||
op = 'revoke';
|
||||
} else if (is_positive) {
|
||||
op = 'upvote';
|
||||
} else {
|
||||
op = 'downvote';
|
||||
}
|
||||
|
||||
$.post("/nodes/comments/" + nodeId + "/rate/" + op)
|
||||
.done(function(data){
|
||||
|
||||
// Add/remove styles for rated statuses
|
||||
switch(op) {
|
||||
case 'revoke':
|
||||
parentDiv.removeClass('rated');
|
||||
break;
|
||||
case 'upvote':
|
||||
parentDiv.addClass('rated');
|
||||
parentDiv.addClass('positive');
|
||||
break;
|
||||
case 'downvote':
|
||||
parentDiv.addClass('rated');
|
||||
parentDiv.removeClass('positive');
|
||||
break;
|
||||
}
|
||||
|
||||
var rating = data['data']['rating_positive'] - data['data']['rating_negative'];
|
||||
$this.siblings('.comment-rating-value').text(rating);
|
||||
});
|
||||
});
|
15
src/scripts/tutti/3_project-utils.js
Normal file
15
src/scripts/tutti/3_project-utils.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// Util to handle project, node and parent properties
|
||||
ProjectUtils = {
|
||||
nodeId: function() { return document.body.dataset.nodeId; },
|
||||
parentNodeId: function() { return document.body.dataset.parentNodeId; },
|
||||
projectId: function() { return document.body.dataset.projectId; },
|
||||
isProject: function() { return document.body.dataset.isProject === 'true'; },
|
||||
nodeType: function() { return document.body.dataset.nodeType; },
|
||||
isModified: function() { return document.body.dataset.isModified === 'true'; },
|
||||
setProjectAttributes: function(props) {
|
||||
for (var key in props) {
|
||||
if (!props.hasOwnProperty(key)) continue;
|
||||
document.body.dataset[key] = props[key];
|
||||
}
|
||||
}
|
||||
};
|
100
src/scripts/tutti/4_search.js
Normal file
100
src/scripts/tutti/4_search.js
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* == Search ==
|
||||
* index and algolia settings are defined in layout.jade
|
||||
*/
|
||||
|
||||
$(document).ready(function() {
|
||||
var searchInput = $('#cloud-search');
|
||||
|
||||
var tu = searchInput.typeahead({hint: true}, {
|
||||
source: index.ttAdapter(),
|
||||
displayKey: 'name',
|
||||
limit: 10,
|
||||
minLength: 0,
|
||||
templates: {
|
||||
suggestion: function(hit) {
|
||||
|
||||
var hitMedia = (hit.media ? ' · <span class="media">'+hit.media+'</span>' : '');
|
||||
var hitFree = (hit.is_free ? '<div class="search-hit-ribbon"><span>free</span></div>' : '');
|
||||
var hitPicture;
|
||||
|
||||
if (hit.picture){
|
||||
hitPicture = '<img src="' + hit.picture + '"/>';
|
||||
} else {
|
||||
hitPicture = '<div class="search-hit-thumbnail-icon">';
|
||||
hitPicture += (hit.media ? '<i class="pi-' + hit.media + '"></i>' : '<i class="dark pi-'+ hit.node_type + '"></i>');
|
||||
hitPicture += '</div>';
|
||||
};
|
||||
|
||||
return '' +
|
||||
'<a href="/nodes/'+ hit.objectID + '/redir" class="search-site-result" id="'+ hit.objectID + '">' +
|
||||
'<div class="search-hit">' +
|
||||
'<div class="search-hit-thumbnail">' +
|
||||
hitPicture +
|
||||
hitFree +
|
||||
'</div>' +
|
||||
'<div class="search-hit-name" title="' + hit.name + '">' +
|
||||
hit._highlightResult.name.value + ' ' +
|
||||
'</div>' +
|
||||
'<div class="search-hit-meta">' +
|
||||
'<span class="project">' + hit._highlightResult.project.name.value + '</span> · ' +
|
||||
'<span class="node_type">' + hit.node_type + '</span>' +
|
||||
hitMedia +
|
||||
'</div>' +
|
||||
'</div>'+
|
||||
'</a>';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('.search-site-result.advanced, .search-icon').on('click', function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
window.location.href = '/search#q='+ $("#cloud-search").val() + '&page=1';
|
||||
});
|
||||
|
||||
|
||||
searchInput.bind('typeahead:select', function(ev, hit) {
|
||||
$('.search-icon').removeClass('pi-search').addClass('pi-spin spin');
|
||||
|
||||
window.location.href = '/nodes/'+ hit.objectID + '/redir';
|
||||
});
|
||||
|
||||
searchInput.bind('typeahead:active', function() {
|
||||
$('#search-overlay').addClass('active');
|
||||
$('.page-body').addClass('blur');
|
||||
});
|
||||
|
||||
searchInput.bind('typeahead:close', function() {
|
||||
$('#search-overlay').removeClass('active');
|
||||
$('.page-body').removeClass('blur');
|
||||
});
|
||||
|
||||
searchInput.keyup(function(e) {
|
||||
if ( $('.tt-dataset').is(':empty') ){
|
||||
if(e.keyCode == 13){
|
||||
window.location.href = '/search#q='+ $("#cloud-search").val() + '&page=1';
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
searchInput.bind('typeahead:render', function(event, suggestions, async, dataset) {
|
||||
if( suggestions != undefined && $('.tt-all-results').length <= 0){
|
||||
$('.tt-dataset').append(
|
||||
'<a id="search-advanced" href="/search#q='+ $("#cloud-search").val() + '&page=1" class="search-site-result advanced tt-suggestion">' +
|
||||
'<div class="search-hit">' +
|
||||
'<div class="search-hit-thumbnail">' +
|
||||
'<div class="search-hit-thumbnail-icon">' +
|
||||
'<i class="pi-search"></i>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="search-hit-name">' +
|
||||
'Use Advanced Search' +
|
||||
'</div>' +
|
||||
'</div>'+
|
||||
'</a>');
|
||||
};
|
||||
});
|
||||
|
||||
});
|
329
src/scripts/tutti/5_notifications.js
Normal file
329
src/scripts/tutti/5_notifications.js
Normal file
@@ -0,0 +1,329 @@
|
||||
|
||||
// Store the title, to later append notifications count
|
||||
var page_title = document.title;
|
||||
|
||||
var unread_on_load = 0;
|
||||
var unread_new = 0;
|
||||
var first_load = false;
|
||||
|
||||
// getNotifications by fetching json every X seconds
|
||||
function getNotifications(){
|
||||
$.getJSON( "/notifications/", function( data ) {
|
||||
|
||||
if (!first_load) {
|
||||
unread_on_load = data['items'].length;
|
||||
first_load = true;
|
||||
}
|
||||
|
||||
var items = [];
|
||||
unread_new = 0;
|
||||
|
||||
// Only if there's actual data
|
||||
if (data['items'][0]){
|
||||
|
||||
// Loop through each item
|
||||
$.each(data['items'], function(i, no){
|
||||
|
||||
// Increase the unread_new counter
|
||||
if (!no['is_read']){ unread_new++ };
|
||||
|
||||
// Check if the current item has been read, to style it
|
||||
var is_read = no['is_read'] ? 'is_read' : '';
|
||||
|
||||
var read_info = 'data-id="'+ no['_id'] + '" data-read="' + no['is_read'] + '"';
|
||||
|
||||
// Notification list item
|
||||
var content = '<li class="nc-item ' + is_read +'" data-id="'+ no['_id'] + '">';
|
||||
|
||||
// User's avatar
|
||||
content += '<div class="nc-avatar">';
|
||||
content += '<img ' + read_info + ' src="' + no['username_avatar'] + '"/> ';
|
||||
content += '</div>';
|
||||
|
||||
// Text of the notification
|
||||
content += '<div class="nc-text">';
|
||||
|
||||
// Username and action
|
||||
content += no['username'] + ' ' + no['action'] + ' ';
|
||||
|
||||
// Object
|
||||
content += '<a '+read_info+'" href="'+no['object_url']+'" class="nc-a">';
|
||||
content += no['context_object_name'] + ' ';
|
||||
content += '</a> ';
|
||||
|
||||
// Date
|
||||
content += '<span class="nc-date">';
|
||||
content += '<a '+read_info+'" href="'+no['object_url']+'" class="nc-a">';
|
||||
content += no['date'];
|
||||
content += '</a>';
|
||||
content += '</span>';
|
||||
|
||||
// Read Toggle
|
||||
content += '<a id="'+no['_id']+'" href="/notifications/' + no['_id'] + '/read-toggle" class="nc-button nc-read_toggle">';
|
||||
if (no['is_read']){
|
||||
content += '<i title="Mark as Unread" class="pi pi-circle-dot"></i>';
|
||||
} else {
|
||||
content += '<i title="Mark as Read" class="pi pi-circle"></i>';
|
||||
};
|
||||
content += '</a>';
|
||||
|
||||
// Subscription Toggle
|
||||
content += '<a href="/notifications/' + no['_id'] + '/subscription-toggle" class="nc-button nc-subscription_toggle">';
|
||||
if (no['is_subscribed']){
|
||||
content += '<i title="Turn Off Notifications" class="pi-toggle-on"></i>';
|
||||
} else {
|
||||
content += '<i title="Turn On Notifications" class="pi-toggle-off"></i>';
|
||||
};
|
||||
content += '</a>';
|
||||
|
||||
content += '</div>';
|
||||
content += '</li>';
|
||||
|
||||
items.push(content);
|
||||
}); // each
|
||||
|
||||
if (unread_new > 0) {
|
||||
// Set page title, display notifications and set counter
|
||||
document.title = '(' + unread_new + ') ' + page_title;
|
||||
$('#notifications-count').addClass('bloom');
|
||||
$('#notifications-count').html('<span>' + unread_new + '</span>');
|
||||
$('#notifications-toggle i').removeClass('pi-notifications-none').addClass('pi-notifications-active');
|
||||
} else {
|
||||
document.title = page_title;
|
||||
$('#notifications-count').removeAttr('class');
|
||||
$('#notifications-toggle i').removeClass('pi-notifications-active').addClass('pi-notifications-none');
|
||||
};
|
||||
|
||||
checkPopNotification(
|
||||
data['items'][0]['_id'],
|
||||
data['items'][0]['username'],
|
||||
data['items'][0]['username_avatar'],
|
||||
data['items'][0]['action'],
|
||||
data['items'][0]['date'],
|
||||
data['items'][0]['context_object_name'],
|
||||
data['items'][0]['object_url']);
|
||||
|
||||
} else {
|
||||
var content = '<li class="nc-item nc-item-empty">';
|
||||
content += 'No notifications... yet.';
|
||||
content += '</li>';
|
||||
|
||||
items.push(content);
|
||||
}; // if items
|
||||
|
||||
// Populate the list
|
||||
$('ul#notifications-list').html( items.join(''));
|
||||
})
|
||||
.done(function(){
|
||||
// clear the counter
|
||||
unread_on_load = unread_new;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Used when we click somewhere in the page
|
||||
function hideNotifications(){
|
||||
$('#notifications').hide();
|
||||
$('#notifications-toggle').removeClass('active');
|
||||
};
|
||||
|
||||
function popNotification(){
|
||||
|
||||
// pop in!
|
||||
$("#notification-pop").addClass('in');
|
||||
|
||||
// After 10s, add a class to make it pop out
|
||||
setTimeout(function(){
|
||||
$("#notification-pop").addClass('out');
|
||||
|
||||
// And a second later, remove all classes
|
||||
setTimeout(function(){
|
||||
$("#notification-pop").removeAttr('class');
|
||||
}, 1000);
|
||||
|
||||
}, 10000);
|
||||
|
||||
// Set them the same so it doesn't pop up again
|
||||
unread_on_load = unread_new;
|
||||
};
|
||||
|
||||
|
||||
function checkPopNotification(id,username,username_avatar,action,date,context_object_name,object_url)
|
||||
{
|
||||
// If there's new content
|
||||
if (unread_new > unread_on_load){
|
||||
// Fill in the urls for redirect on click, and mark-read
|
||||
$("#notification-pop").attr('data-url', object_url);
|
||||
$("#notification-pop").attr('data-read-toggle', '/notifications/' + id + '/read-toggle');
|
||||
// The text in the pop
|
||||
var text = '<span class="nc-author">' + username + '</span> ';
|
||||
text += action + ' ';
|
||||
text += context_object_name + ' ';
|
||||
text += '<span class="nc-date">' + date + '</span>';
|
||||
|
||||
// Fill the html
|
||||
$('#notification-pop .nc-text').html(text);
|
||||
$('#notification-pop .nc-avatar img').attr('src', username_avatar);
|
||||
|
||||
// pop in!
|
||||
popNotification();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Function to set #notifications flyout height and resize if needed
|
||||
function notificationsResize(){
|
||||
var height = $(window).height() - 80;
|
||||
|
||||
if ($('#notifications').height() > height){
|
||||
$('#notifications').css({
|
||||
'max-height' : height / 2,
|
||||
'overflow-y' : 'scroll'
|
||||
}
|
||||
);
|
||||
} else {
|
||||
$('#notifications').css({
|
||||
'max-height' : '1000%',
|
||||
'overflow-y' : 'initial'
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
$(function() {
|
||||
// Click anywhere in the page to hide #notifications
|
||||
$(document).click(function () {
|
||||
hideNotifications();
|
||||
});
|
||||
// ...but clicking inside #notifications shouldn't hide itself
|
||||
$('#notifications').on('click', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// Toggle the #notifications flyout
|
||||
$('#notifications-toggle').on('click', function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
$('#notifications').toggle();
|
||||
$(this).toggleClass("active");
|
||||
|
||||
notificationsResize();
|
||||
|
||||
// Hide other dropdowns
|
||||
$('nav .dropdown').removeClass('open');
|
||||
|
||||
var navbarCollapse = $('nav.navbar-collapse');
|
||||
|
||||
if ($(navbarCollapse).hasClass('in')){
|
||||
$(navbarCollapse).addClass('show-notifications').removeClass('in');
|
||||
$('.nav-notifications-icon').removeClass('pi-notifications-none').addClass('pi-cancel');
|
||||
} else {
|
||||
$(navbarCollapse).removeClass('show-notifications');
|
||||
$('.nav-notifications-icon').addClass('pi-notifications-none').removeClass('pi-cancel');
|
||||
}
|
||||
});
|
||||
|
||||
// Hide flyout when clicking other dropdowns
|
||||
$('nav').on('click', '.dropdown', function (e) {
|
||||
$('#notifications').hide();
|
||||
$('#notifications-toggle').removeClass('active');
|
||||
});
|
||||
|
||||
|
||||
$('#notification-pop').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
var link_url = $(this).data('url');
|
||||
var read_url = $(this).data('read-toggle');
|
||||
|
||||
$.get(read_url)
|
||||
.done(function () {
|
||||
window.location.href = link_url;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Read/Subscription Toggles
|
||||
$('ul#notifications-list').on('click', '.nc-button', function (e) {
|
||||
e.preventDefault();
|
||||
var nc = $(this);
|
||||
|
||||
// Swap to spin icon while we wait for the response
|
||||
$('i', nc).addClass('spin');
|
||||
|
||||
$.get($(nc).attr('href'))
|
||||
.done(function (data) {
|
||||
|
||||
if ($(nc).hasClass('nc-read_toggle')) {
|
||||
if (data.data.is_read) {
|
||||
$('i', nc).removeClass('pi-circle').addClass('pi-circle-dot');
|
||||
$(nc).closest('.nc-item').addClass('is_read');
|
||||
} else {
|
||||
$('i', nc).removeClass('pi-circle-dot').addClass('pi-circle');
|
||||
$(nc).closest('.nc-item').removeClass('is_read');
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
if ($(nc).hasClass('nc-subscription_toggle')) {
|
||||
if (data.data.is_subscribed) {
|
||||
$('i', nc).removeClass('pi-toggle-on').addClass('pi-toggle-off');
|
||||
} else {
|
||||
$('i', nc).removeClass('pi-toggle-off').addClass('pi-toggle-on');
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
$('i', nc).removeClass('spin');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// When clicking on links, toggle as read
|
||||
$('ul#notifications-list').on('click', '.nc-a', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var is_read = $(this).data('read');
|
||||
var link_url = $(this).attr('href');
|
||||
var read_url = '/notifications/' + $(this).data('id') + '/read-toggle';
|
||||
|
||||
if (is_read) {
|
||||
window.location.href = link_url;
|
||||
} else {
|
||||
$.get(read_url)
|
||||
.done(function () {
|
||||
window.location.href = link_url;
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Mark All as Read
|
||||
$('#notifications-markallread').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
$.get("/notifications/read-all");
|
||||
|
||||
$('ul#notifications-list li.nc-item:not(.is_read)').each(function () {
|
||||
$(this).addClass('is_read');
|
||||
});
|
||||
|
||||
document.title = page_title;
|
||||
$('#notifications-count').removeAttr('class');
|
||||
$('#notifications-toggle i').removeClass('pi-notifications-active').addClass('pi-notifications-none');
|
||||
|
||||
unread_on_load = unread_new;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function getNotificationsLoop() {
|
||||
getNotifications();
|
||||
|
||||
var getLoop = setTimeout(function () {
|
||||
getNotificationsLoop();
|
||||
}, 30000);
|
||||
}
|
Reference in New Issue
Block a user