Merge pull request #3124 from ceruleandeep/feature/actuallyCompactContextMenus Filter out hidden items in context menus

8b7a14f895399764b7eda0cbab65a88def16fd1a

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
5 files changed, +26 -33Ignore whitespace
public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js+17 -3
@@ -38,7 +38,6 @@ export class ContextMenu {
38 label: qr.label,38 label: qr.label,
39 title: qr.title,39 title: qr.title,
40 message: (chainedMessage && qr.message ? `${chainedMessage} | ` : '') + qr.message,40 message: (chainedMessage && qr.message ? `${chainedMessage} | ` : '') + qr.message,
41 isHidden: qr.isHidden,
42 children: [],41 children: [],
43 };42 };
44 qr.contextList.forEach((cl) => {43 qr.contextList.forEach((cl) => {
@@ -47,7 +46,23 @@ export class ContextMenu {
47 const nextHierarchy = [...hierarchy, cl.set];46 const nextHierarchy = [...hierarchy, cl.set];
48 const nextLabelHierarchy = [...labelHierarchy, tree.label];47 const nextLabelHierarchy = [...labelHierarchy, tree.label];
49 tree.children.push(new MenuHeader(cl.set.name));48 tree.children.push(new MenuHeader(cl.set.name));
50 cl.set.qrList.forEach(subQr => {49
50 // If the Quick Reply's own set is added as a context menu,
51 // show only the sub-QRs that are Invisible but have an icon
52 // intent: allow a QR set to be assigned to one of its own QR buttons for a "burger" menu
53 // with "UI" QRs either in the bar or in the menu, and "library function" QRs still hidden.
54 // - QRs already visible on the bar are filtered out,
55 // - hidden QRs without an icon are filtered out,
56 // - hidden QRs **with an icon** are shown in the menu
57 // so everybody is happy
58 const qrsOwnSetAddedAsContextMenu = cl.set.qrList.includes(qr);
59 const visible = (subQr) => {
60 return qrsOwnSetAddedAsContextMenu
61 ? subQr.isHidden && !!subQr.icon // yes .isHidden gets inverted here
62 : !subQr.isHidden;
63 };
64
65 cl.set.qrList.filter(visible).forEach(subQr => {
51 const subTree = this.build(subQr, cl.isChained ? tree.message : null, nextHierarchy, nextLabelHierarchy);66 const subTree = this.build(subQr, cl.isChained ? tree.message : null, nextHierarchy, nextLabelHierarchy);
52 tree.children.push(new MenuItem(67 tree.children.push(new MenuItem(
53 subTree.icon,68 subTree.icon,
@@ -55,7 +70,6 @@ export class ContextMenu {
55 subTree.label,70 subTree.label,
56 subTree.title,71 subTree.title,
57 subTree.message,72 subTree.message,
58 subTree.isHidden,
59 (evt) => {73 (evt) => {
60 evt.stopPropagation();74 evt.stopPropagation();
61 const finalQr = Object.assign(new QuickReply(), subQr);75 const finalQr = Object.assign(new QuickReply(), subQr);
public/scripts/extensions/quick-reply/src/ui/ctx/MenuHeader.js+1 -1
@@ -2,7 +2,7 @@ import { MenuItem } from './MenuItem.js';
22
3export class MenuHeader extends MenuItem {3export class MenuHeader extends MenuItem {
4 constructor(/**@type {String}*/label) {4 constructor(/**@type {String}*/label) {
5 super(null, null, label, null, null, false, null, []);5 super(null, null, label, null, null, null, []);
6 }6 }
77
88
public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js+1 -29
@@ -6,7 +6,6 @@ export class MenuItem {
6 /**@type {string}*/ label;6 /**@type {string}*/ label;
7 /**@type {string}*/ title;7 /**@type {string}*/ title;
8 /**@type {object}*/ value;8 /**@type {object}*/ value;
9 /**@type {boolean}*/ isHidden = false;
10 /**@type {function}*/ callback;9 /**@type {function}*/ callback;
11 /**@type {MenuItem[]}*/ childList = [];10 /**@type {MenuItem[]}*/ childList = [];
12 /**@type {SubMenu}*/ subMenu;11 /**@type {SubMenu}*/ subMenu;
@@ -25,44 +24,20 @@ export class MenuItem {
25 * @param {string} label24 * @param {string} label
26 * @param {?string} title Tooltip25 * @param {?string} title Tooltip
27 * @param {object} value26 * @param {object} value
28 * @param {boolean} isHidden QR is Invisible (auto-execute only)
29 * @param {function} callback27 * @param {function} callback
30 * @param {MenuItem[]} children28 * @param {MenuItem[]} children
31 */29 */
32 constructor(icon, showLabel, label, title, value, isHidden, callback, children = []) {30 constructor(icon, showLabel, label, title, value, callback, children = []) {
33 this.icon = icon;31 this.icon = icon;
34 this.showLabel = showLabel;32 this.showLabel = showLabel;
35 this.label = label;33 this.label = label;
36 this.title = title;34 this.title = title;
37 this.value = value;35 this.value = value;
38 this.isHidden = isHidden;
39 this.callback = callback;36 this.callback = callback;
40 this.childList = children;37 this.childList = children;
41 }38 }
4239
4340
44 /**
45 * Renders the MenuItem
46 *
47 * A .qr--hidden class is added to:
48 * - the item if it is "Invisible (auto-execute only)"
49 * - the icon if no icon is set
50 * - the label if an icon is set and showLabel is false
51 *
52 * There is no .qr--hidden class defined in default CSS, since having items
53 * that are invisible on the QR bar but visible in the context menu,
54 * or icon-only on the QR bar but labelled in the context menu, is a valid use case.
55 *
56 * To hide optional labels when icons are present, add this user CSS:
57 * .ctx-menu .ctx-item .qr--button-label.qr--hidden {display: none;}
58 * To hide icons when no icon is present (removes unwanted padding):
59 * .ctx-menu .ctx-item .qr--button-icon.qr--hidden {display: none;}
60 * To hide items that are set "invisible":
61 * .ctx-menu .ctx-item.qr--hidden {display: none;}
62 * To target submenus only, use .ctx-menu .ctx-sub-menu .qr--hidden {display: none;}
63 *
64 * @returns {HTMLElement}
65 */
66 render() {41 render() {
67 if (!this.root) {42 if (!this.root) {
68 const item = document.createElement('li'); {43 const item = document.createElement('li'); {
@@ -70,9 +45,6 @@ export class MenuItem {
70 item.classList.add('list-group-item');45 item.classList.add('list-group-item');
71 item.classList.add('ctx-item');46 item.classList.add('ctx-item');
7247
73 // if this item is Invisible, add the hidden class
74 if (this.isHidden) item.classList.add('qr--hidden');
75
76 // if a title/tooltip is set, add it, otherwise use the QR content48 // if a title/tooltip is set, add it, otherwise use the QR content
77 // same as for the main QR list49 // same as for the main QR list
78 item.title = this.title || this.value;50 item.title = this.title || this.value;
public/scripts/extensions/quick-reply/style.css+3 -0
@@ -174,6 +174,9 @@
174 position: absolute;174 position: absolute;
175 overflow: visible;175 overflow: visible;
176}176}
177.ctx-menu .ctx-item .qr--hidden {
178 display: none;
179}
177.list-group .list-group-item.ctx-header {180.list-group .list-group-item.ctx-header {
178 font-weight: bold;181 font-weight: bold;
179 cursor: default;182 cursor: default;
public/scripts/extensions/quick-reply/style.less+4 -0
@@ -176,6 +176,10 @@
176 overflow: visible;176 overflow: visible;
177}177}
178178
179.ctx-menu .ctx-item .qr--hidden {
180 display: none;
181}
182
179.list-group .list-group-item.ctx-header {183.list-group .list-group-item.ctx-header {
180 font-weight: bold;184 font-weight: bold;
181 cursor: default;185 cursor: default;