mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Merge pull request #1848 from cryptpad/notification-page
Improve notification page accessibility, responsiveness and UI
This commit is contained in:
commit
f3b4bbcbc7
@ -141,6 +141,8 @@ define(req, function(AppConfig, Default, Language) {
|
||||
Messages.badges_premium = "Premium user";
|
||||
Messages.badges_error = "Error while validating this user's data";
|
||||
Messages.profile_badges = "Badges";
|
||||
Messages.user_profile = 'Go to user profile';
|
||||
Messages.add_password = "Add your document password";
|
||||
Messages.show_password = "Show password";
|
||||
Messages.hide_password = "Hide password";
|
||||
Messages.page_next = "Next page";
|
||||
|
||||
@ -4469,5 +4469,61 @@ define([
|
||||
return container;
|
||||
};
|
||||
|
||||
UIElements.reorderDOM = function ($content, isDrawer) {
|
||||
var reorderDOM = Util.throttle(function ($content, observer) {
|
||||
if (!$content.length) { return; }
|
||||
|
||||
// List all children based on their "order" property
|
||||
var map = {};
|
||||
$content[0].childNodes.forEach((node) => {
|
||||
try {
|
||||
if (!node.attributes) { return; }
|
||||
let nodeWithOrder;
|
||||
if (isDrawer) { // HACK: the order is set on their inner "a" tag
|
||||
let $n = $(node);
|
||||
if (!$n.attr('class') &&
|
||||
($n.find('.fa').length || $n.find('.cptools').length)) {
|
||||
nodeWithOrder = $n.find('.fa')[0] || $n.find('.cptools')[0];
|
||||
}
|
||||
}
|
||||
var order = getComputedStyle(nodeWithOrder || node).getPropertyValue("order");
|
||||
var a = map[order] = map[order] || [];
|
||||
a.push(node);
|
||||
} catch (e) { console.error(e, node); }
|
||||
});
|
||||
|
||||
// Disconnect the observer while we're reordering to avoid infinite loop
|
||||
observer.disconnect();
|
||||
Object.keys(map).sort(function (a, b) {
|
||||
return Number(a) - Number(b);
|
||||
}).forEach(function (k) {
|
||||
var arr = map[k];
|
||||
if (!Number(k)) { return; } // No need to "append" if order is -1
|
||||
// Reorder
|
||||
arr.forEach(function (node) {
|
||||
$content.append(node);
|
||||
});
|
||||
});
|
||||
observer.start();
|
||||
}, 100);
|
||||
|
||||
let observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.addedNodes.length) {
|
||||
reorderDOM($content, observer);
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.start = function () {
|
||||
if (!$content.length) { return; }
|
||||
observer.observe($content[0], {
|
||||
childList: true
|
||||
});
|
||||
};
|
||||
observer.start();
|
||||
};
|
||||
|
||||
|
||||
|
||||
return UIElements;
|
||||
});
|
||||
|
||||
@ -81,17 +81,22 @@ define([
|
||||
Common.openURL(Hash.hashToHref('', 'calendar'));
|
||||
});
|
||||
} else if (userData && typeof(userData) === "object" && userData.profile) {
|
||||
avatar = h('span.cp-avatar');
|
||||
avatar = h('span.cp-avatar',{
|
||||
tabindex: 0,
|
||||
title: Messages.user_profile,
|
||||
'aria-label': Messages.user_profile,
|
||||
role: 'button'
|
||||
});
|
||||
Common.displayAvatar($(avatar), userData.avatar, userData.displayName || userData.name);
|
||||
$(avatar).click(function (e) {
|
||||
const handler = function (e) {
|
||||
e.stopPropagation();
|
||||
Common.openURL(Hash.hashToHref(userData.profile, 'profile'));
|
||||
});
|
||||
};
|
||||
Util.onClickEnter($(avatar), handler, { space: true });
|
||||
} else if (userData && userData.supportTeam) {
|
||||
avatar = h('span.cp-avatar-image', h('img', { src:'/customize/CryptPad_logo.svg' }));
|
||||
}
|
||||
var order = -Math.floor((Util.find(data, ['content', 'msg', 'ctime']) || 0) / 1000);
|
||||
const tabIndexValue = undefined;//data.content.isDismissible ? undefined : '0';
|
||||
notif = h('li.cp-notification', {
|
||||
role: 'menuitem',
|
||||
tabindex: '0',
|
||||
@ -100,7 +105,7 @@ define([
|
||||
}, [
|
||||
avatar,
|
||||
h('div.cp-notification-content', {
|
||||
tabindex: tabIndexValue
|
||||
tabindex: 0
|
||||
}, [
|
||||
h('p', data.content.msg.type + ' - ' +formatData(data))
|
||||
])
|
||||
@ -119,15 +124,19 @@ define([
|
||||
$(notif).find('.cp-notification-content p').html(data.content.getFormatText());
|
||||
}, 60000);
|
||||
}
|
||||
const label = $(notif).find('.cp-notification-content p').text();
|
||||
$(notif).find('.cp-notification-content').attr('aria-label', label);
|
||||
}
|
||||
|
||||
$(notif).mouseenter((e) => {
|
||||
e.stopPropagation();
|
||||
$(notif).focus();
|
||||
if($(notif).find('li[tabindex="0"]').length) {
|
||||
$(notif).focus();
|
||||
};
|
||||
});
|
||||
|
||||
if (data.content.isClickable) {
|
||||
$(notif).find('.cp-notification-content').addClass("cp-clickable").on('click keypress', function (event) {
|
||||
$(notif).find('.cp-notification-content').addClass("cp-clickable").attr('role', 'link').on('click keypress', function (event) {
|
||||
if (event.type === 'click' || (event.type === 'keypress' && event.which === 13)) {
|
||||
data.content.handler();
|
||||
}
|
||||
@ -136,7 +145,10 @@ define([
|
||||
if (data.content.isDismissible) {
|
||||
var dismissIcon = h('span.fa.fa-times');
|
||||
var dismiss = h('div.cp-notification-dismiss', {
|
||||
tabindex: 0,
|
||||
title: Messages.notifications_dismiss,
|
||||
'aria-label': Messages.notifications_dismiss,
|
||||
role: 'button'
|
||||
}, dismissIcon);
|
||||
$(dismiss).addClass("cp-clickable")
|
||||
.on('click keypress', function (event) {
|
||||
|
||||
@ -65,60 +65,6 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
return 'cp-toolbar-uid-' + String(Math.random()).substring(2);
|
||||
};
|
||||
|
||||
var observeChildren = function ($content, isDrawer) {
|
||||
var reorderDOM = Util.throttle(function ($content, observer) {
|
||||
if (!$content.length) { return; }
|
||||
|
||||
// List all children based on their "order" property
|
||||
var map = {};
|
||||
$content[0].childNodes.forEach((node) => {
|
||||
try {
|
||||
if (!node.attributes) { return; }
|
||||
let nodeWithOrder;
|
||||
if (isDrawer) { // HACK: the order is set on their inner "a" tag
|
||||
let $n = $(node);
|
||||
if (!$n.attr('class') &&
|
||||
($n.find('.fa').length || $n.find('.cptools').length)) {
|
||||
nodeWithOrder = $n.find('.fa')[0] || $n.find('.cptools')[0];
|
||||
}
|
||||
}
|
||||
var order = getComputedStyle(nodeWithOrder || node).getPropertyValue("order");
|
||||
var a = map[order] = map[order] || [];
|
||||
a.push(node);
|
||||
} catch (e) { console.error(e, node); }
|
||||
});
|
||||
|
||||
// Disconnect the observer while we're reordering to avoid infinite loop
|
||||
observer.disconnect();
|
||||
Object.keys(map).sort(function (a, b) {
|
||||
return Number(a) - Number(b);
|
||||
}).forEach(function (k) {
|
||||
var arr = map[k];
|
||||
if (!Number(k)) { return; } // No need to "append" if order is 0
|
||||
// Reorder
|
||||
arr.forEach(function (node) {
|
||||
$content.append(node);
|
||||
});
|
||||
});
|
||||
observer.start();
|
||||
}, 100);
|
||||
|
||||
let observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.addedNodes.length) {
|
||||
reorderDOM($content, observer);
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.start = function () {
|
||||
if (!$content.length) { return; }
|
||||
observer.observe($content[0], {
|
||||
childList: true
|
||||
});
|
||||
};
|
||||
observer.start();
|
||||
};
|
||||
|
||||
var createRealtimeToolbar = function (config) {
|
||||
if (!config.$container) { return; }
|
||||
var $container = config.$container;
|
||||
@ -1231,7 +1177,7 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
$button.attr('aria-label', Messages.notificationsPage);
|
||||
var $n = $button.find('.cp-dropdown-button-title').hide();
|
||||
var $empty = $(div).find('.cp-notifications-empty');
|
||||
observeChildren($(div));
|
||||
UIElements.reorderDOM($(div));
|
||||
|
||||
var refresh = function () {
|
||||
updateUserList(toolbar, config);
|
||||
@ -1457,14 +1403,14 @@ MessengerUI, Messages, Pages, PadTypes) {
|
||||
toolbar.$history = $toolbar.find('.'+Bar.constants.history);
|
||||
toolbar.$user = $toolbar.find('.'+Bar.constants.userAdmin);
|
||||
|
||||
observeChildren(toolbar.$drawer, true);
|
||||
observeChildren(toolbar.$bottomL);
|
||||
observeChildren(toolbar.$bottomM);
|
||||
observeChildren(toolbar.$bottomR);
|
||||
observeChildren(toolbar.$top);
|
||||
observeChildren(toolbar.$user);
|
||||
UIElements.reorderDOM(toolbar.$drawer, true);
|
||||
UIElements.reorderDOM(toolbar.$bottomL);
|
||||
UIElements.reorderDOM(toolbar.$bottomM);
|
||||
UIElements.reorderDOM(toolbar.$bottomR);
|
||||
UIElements.reorderDOM(toolbar.$top);
|
||||
UIElements.reorderDOM(toolbar.$user);
|
||||
if (config.$contentContainer) {
|
||||
observeChildren(config.$contentContainer);
|
||||
UIElements.reorderDOM(config.$contentContainer);
|
||||
}
|
||||
|
||||
toolbar.$userAdmin = $toolbar.find('.'+Bar.constants.userAdmin);
|
||||
|
||||
@ -21,6 +21,10 @@
|
||||
&:hover {
|
||||
background-color: @cp_notif-hover;
|
||||
}
|
||||
&:focus-visible {
|
||||
outline: @variables_focus_style;
|
||||
border-radius: @variables_radius;
|
||||
}
|
||||
}
|
||||
|
||||
.cp-app-notifications-panel {
|
||||
@ -59,6 +63,8 @@
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 3rem;
|
||||
border-radius: @variables_radius;
|
||||
margin: 0.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,16 +96,20 @@
|
||||
}
|
||||
.cp-avatar {
|
||||
.avatar_main(48px);
|
||||
padding: 0 10px;
|
||||
padding: 5px;
|
||||
margin: 0.2rem;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background-color: @cp_notif-hover;
|
||||
}
|
||||
&:focus-visible {
|
||||
outline: @variables_focus_style;
|
||||
border-radius: @variables_radius;
|
||||
}
|
||||
}
|
||||
.cp-avatar-calendar {
|
||||
font-size: 45px;
|
||||
padding: 0 12px;
|
||||
overflow: hidden;
|
||||
padding: 12px;
|
||||
}
|
||||
&.cp-app-notification-archived {
|
||||
background-color: @cp_notif-bg;
|
||||
@ -114,16 +124,18 @@
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin: 0.1rem;
|
||||
&:focus-visible {
|
||||
outline: @variables_focus_style;
|
||||
border-radius: @variables_radius;
|
||||
}
|
||||
p {
|
||||
display: inline-block;
|
||||
margin: 1rem 1rem;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.notification-time {
|
||||
margin: 1rem 1rem;
|
||||
color: grey;
|
||||
margin-left: auto;
|
||||
margin: 1rem 1rem 1rem auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +148,10 @@
|
||||
align-items: center;
|
||||
border-left: 1px solid @cp_notif-table-border;
|
||||
width: 3rem;
|
||||
margin: 0.2rem;
|
||||
&:focus-visible{
|
||||
border-radius: @variables_radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,9 @@ define([
|
||||
'/common/hyperscript.js',
|
||||
'/customize/messages.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/notifications.js',
|
||||
'/common/common-util.js',
|
||||
|
||||
'css!/components/bootstrap/dist/css/bootstrap.min.css',
|
||||
'css!/components/components-font-awesome/css/font-awesome.min.css',
|
||||
@ -27,7 +29,9 @@ define([
|
||||
h,
|
||||
Messages,
|
||||
UI,
|
||||
Notifications
|
||||
UIElements,
|
||||
Notifications,
|
||||
Util,
|
||||
)
|
||||
{
|
||||
var APP = {};
|
||||
@ -74,14 +78,16 @@ define([
|
||||
h("h5.cp-app-notifications-panel-title",
|
||||
(Messages.notificationsPage || "Notifications") + " - " + categoryName),
|
||||
h("div.cp-app-notifications-panel-titlebar-buttons", [
|
||||
dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { title: Messages.notifications_dismissAll || "Dismiss All" }, h("span.fa.fa-trash")),
|
||||
dismissAll = h("div.cp-app-notifications-dismissall.cp-clickable", { tabindex: 0, title: Messages.notifications_dismissAll || "Dismiss All", 'aria-label': Messages.notifications_dismissAll || "Dismiss All", role: 'button' }, h("span.fa.fa-trash")),
|
||||
]),
|
||||
]),
|
||||
notifsList = h("div.cp-app-notifications-panel-list", [
|
||||
notifsList = h("div.cp-app-notifications-panel-list", {'role': 'list', 'aria-label': (Messages.notificationsPage || "Notifications") + " " + categoryName }, [
|
||||
h("div.cp-notification.no-notifications", Messages.notifications_empty),
|
||||
]),
|
||||
]);
|
||||
|
||||
UIElements.reorderDOM($(notifsList));
|
||||
|
||||
// add notification
|
||||
var addNotification = function (data, el) {
|
||||
// if the type of notification correspond
|
||||
@ -89,6 +95,8 @@ define([
|
||||
notifsData.push(data);
|
||||
var icon = $(el).find(".cp-reminder");
|
||||
$(icon).addClass('cp-avatar-calendar');
|
||||
$(el).attr('tabindex', -1);
|
||||
$(el).attr('role', 'listitem');
|
||||
$(notifsList).prepend(el);
|
||||
}
|
||||
};
|
||||
@ -107,6 +115,7 @@ define([
|
||||
var time = new Date(data.content.time);
|
||||
$(el).find(".cp-notification-content").append(h("span.notification-time", time.toLocaleString()));
|
||||
$(el).addClass("cp-app-notification-archived");
|
||||
$(el).attr('tabindex', -1);
|
||||
if (isDataUnread) {
|
||||
$(el).hide();
|
||||
} else {
|
||||
@ -122,7 +131,7 @@ define([
|
||||
var loadmore;
|
||||
var lastKnownHash;
|
||||
$(dismissAll).remove();
|
||||
loadmore = h("div.cp-app-notification-loadmore.cp-clickable", Messages.history_loadMore);
|
||||
loadmore = h("button.cp-app-notification-loadmore.cp-clickable", Messages.history_loadMore);
|
||||
$(loadmore).click(function () {
|
||||
common.mailbox.getNotificationsHistory('notifications', 10, lastKnownHash, function (err, messages, end) {
|
||||
if (!Array.isArray(messages)) { return; }
|
||||
@ -153,14 +162,17 @@ define([
|
||||
$('.cp-app-notification-archived[data-hash="' + data.hash + '"]').css('display', 'flex');
|
||||
}
|
||||
});
|
||||
|
||||
$(dismissAll).click(function () {
|
||||
const handler = function (e) {
|
||||
if (!notifsData) {
|
||||
return;
|
||||
}
|
||||
notifsData.forEach(function (data) {
|
||||
if (data.content.isDismissible) {
|
||||
data.content.dismissHandler();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
Util.onClickEnter($(dismissAll), handler, { space: true });
|
||||
|
||||
return $div;
|
||||
};
|
||||
@ -198,18 +210,18 @@ define([
|
||||
});
|
||||
};
|
||||
var createLeftside = function () {
|
||||
var $categories = $('<div>', {'class': 'cp-sidebarlayout-categories'})
|
||||
var $categories = $('<div>', {'class': 'cp-sidebarlayout-categories', 'role': 'menu' })
|
||||
.appendTo(APP.$leftside);
|
||||
var metadataMgr = common.getMetadataMgr();
|
||||
var privateData = metadataMgr.getPrivateData();
|
||||
var active = privateData.category || 'all';
|
||||
common.setHash(active);
|
||||
Object.keys(categories).forEach(function (key) {
|
||||
var $category = $('<div>', {'class': 'cp-sidebarlayout-category', 'tabindex': 0}).appendTo($categories);
|
||||
if (key === 'all') { $category.append($('<span>', {'class': 'fa fa-bars'})); }
|
||||
if (key === 'friends') { $category.append($('<span>', {'class': 'fa fa-user'})); }
|
||||
if (key === 'pads') { $category.append($('<span>', {'class': 'cptools cptools-richtext'})); }
|
||||
if (key === 'archived') { $category.append($('<span>', {'class': 'fa fa-archive'})); }
|
||||
var $category = $('<div>', {'class': 'cp-sidebarlayout-category', 'tabindex': 0, 'role': 'menuitem'}).appendTo($categories);
|
||||
if (key === 'all') { $category.append($('<span>', {'class': 'fa fa-bars', 'aria-hidden': 'true'})); }
|
||||
if (key === 'friends') { $category.append($('<span>', {'class': 'fa fa-user', 'aria-hidden': 'true'})); }
|
||||
if (key === 'pads') { $category.append($('<span>', {'class': 'cptools cptools-richtext', 'aria-hidden': 'true'})); }
|
||||
if (key === 'archived') { $category.append($('<span>', {'class': 'fa fa-archive', 'aria-hidden': 'true'})); }
|
||||
|
||||
if (key === active) {
|
||||
$category.addClass('cp-leftside-active');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user