From ecbe2f7d728e6dc65f447ab438af929e5296ac25 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Mon, 7 Apr 2025 22:52:52 +0200 Subject: [PATCH] add shortscuts add open/close action --- src/components/AppSearch.vue | 11 +- src/components/CloserButton.vue | 7 +- src/components/OpenerButton.vue | 5 + src/components/PageLoader.vue | 5 +- src/lib/search.js | 4 +- src/menu.js | 2 +- src/menus/MenuContainer.vue | 59 +++++- src/menus/SideMenuWithCategories.vue | 37 +++- src/menus/SimpleSideMenu.vue | 57 ++++-- src/menus/TopWideMenu.vue | 42 +++- src/scss/menu.scss | 296 ++++++++++++++------------- templates/js/script.php | 162 --------------- 12 files changed, 331 insertions(+), 356 deletions(-) diff --git a/src/components/AppSearch.vue b/src/components/AppSearch.vue index 7f7a17f..f7275b4 100644 --- a/src/components/AppSearch.vue +++ b/src/components/AppSearch.vue @@ -18,19 +18,12 @@ along with this program. If not, see . diff --git a/src/components/CloserButton.vue b/src/components/CloserButton.vue index bcee43f..efcb225 100644 --- a/src/components/CloserButton.vue +++ b/src/components/CloserButton.vue @@ -17,8 +17,13 @@ along with this program. If not, see . + + diff --git a/src/components/OpenerButton.vue b/src/components/OpenerButton.vue index 08cbcff..282b2d9 100644 --- a/src/components/OpenerButton.vue +++ b/src/components/OpenerButton.vue @@ -18,7 +18,12 @@ along with this program. If not, see . + + diff --git a/src/components/PageLoader.vue b/src/components/PageLoader.vue index 95ded5e..2c67902 100644 --- a/src/components/PageLoader.vue +++ b/src/components/PageLoader.vue @@ -1,6 +1,9 @@ diff --git a/src/lib/search.js b/src/lib/search.js index 4fee589..2e4f409 100644 --- a/src/lib/search.js +++ b/src/lib/search.js @@ -1,10 +1,10 @@ const containsAppsMatchingSearch = (values, search) => { - if (search.value.trim() === '') { + if (search.trim() === '') { return true } for (let key in values) { - if (isAppMatchingSearch(values[key].name)) { + if (isAppMatchingSearch(values[key], search)) { return true } } diff --git a/src/menu.js b/src/menu.js index b9842c0..99ab101 100644 --- a/src/menu.js +++ b/src/menu.js @@ -36,7 +36,7 @@ body.appendChild(container) const app = createApp(MenuContainer) app.use(pinia) -app.mixin({ methods: { t, n }}) +app.mixin({ methods: { t, n } }) app.mount(container) // waitContainer('#header .app-menu').then((selector) => { diff --git a/src/menus/MenuContainer.vue b/src/menus/MenuContainer.vue index 1a3137c..69d7acf 100644 --- a/src/menus/MenuContainer.vue +++ b/src/menus/MenuContainer.vue @@ -1,11 +1,22 @@ diff --git a/src/menus/SimpleSideMenu.vue b/src/menus/SimpleSideMenu.vue index cfe0ee1..2b36b0b 100644 --- a/src/menus/SimpleSideMenu.vue +++ b/src/menus/SimpleSideMenu.vue @@ -15,19 +15,26 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> diff --git a/src/menus/TopWideMenu.vue b/src/menus/TopWideMenu.vue index 41044a3..46a3682 100644 --- a/src/menus/TopWideMenu.vue +++ b/src/menus/TopWideMenu.vue @@ -18,17 +18,25 @@ along with this program. If not, see .
- + - - + +
@@ -56,7 +64,7 @@ along with this program. If not, see . :key="appId" > . diff --git a/src/scss/menu.scss b/src/scss/menu.scss index c1be903..9e8c749 100644 --- a/src/scss/menu.scss +++ b/src/scss/menu.scss @@ -29,19 +29,25 @@ rgba(0, 0, 0, 0.22) 0px 25.6px 57.6px 0px, rgba(0, 0, 0, 0.18) 0px 4.8px 14.4px 0px; display: none; + + a { + transition: 0.2s; + } + + &.open { + display: block; + + .side-menu-settings { + display: block; + } + } } -#side-menu a { - transition: 0.2s; -} - -#side-menu.open { - display: block; -} - -#header .side-menu-opener { - margin-left: 0px; - margin-top: -1px; +#header { + .side-menu-opener { + margin-left: 0px; + margin-top: -1px; + } } .side-menu-settings { @@ -51,29 +57,25 @@ line-height: 34px; height: 42px; display: none; -} -.side-menu-settings a { - color: var(--side-menu-text-color, #fff); - display: block; - padding: 4px 7px; -} + a { + color: var(--side-menu-text-color, #fff); + display: block; + padding: 4px 7px; + } -.side-menu-settings:hover a, -.side-menu-settings a:active, -.side-menu-settings a:focus { - background: var(--side-menu-current-app-background-color, #444); -} + &:hover a, + a:active, + a:focus { + background: var(--side-menu-current-app-background-color, #444); + } -.side-menu-settings img { - vertical-align: bottom; - margin-left: 3px; - width: 32px; - height: 32px; -} - -#side-menu.open .side-menu-settings { - display: block; + img { + vertical-align: bottom; + margin-left: 3px; + width: 32px; + height: 32px; + } } .side-menu-opener { @@ -88,20 +90,20 @@ margin-left: 5px !important; margin-left: 3px !important; overflow: hidden; -} -.side-menu-opener span { - position: relative; - left: 50px; - display: block; - width: 1px; - height: 1px; - overflow: hidden; -} + span { + position: relative; + left: 50px; + display: block; + width: 1px; + height: 1px; + overflow: hidden; + } -.side-menu-opener:active, -.side-menu-opener:focus { - background-color: var(--side-menu-current-app-background-color, #444) !important; + &:active, + &:focus { + background-color: var(--side-menu-current-app-background-color, #444) !important; + } } .side-menu-closer { @@ -134,39 +136,47 @@ opacity: var(--side-menu-icon-opacity, 1); } -.side-menu-app a { - line-height: 30px; - color: var(--side-menu-text-color, #fff); - display: block; - padding: 7px 0 5px 15px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} +.side-menu-app { + a { + line-height: 30px; + color: var(--side-menu-text-color, #fff); + display: block; + padding: 7px 0 5px 15px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } -.side-menu-app a:hover, -.side-menu-app.active, -.side-menu-app a:focus { - background: var(--side-menu-current-app-background-color, #444); + a:hover, + a:focus, + &:active { + background: var(--side-menu-current-app-background-color, #444); + } } .side-menu-logo { text-align: center; + clear: both; + + img { + max-width: 60%; + max-height: 100px; + } } -.side-menu-logo img { - max-width: 60%; - max-height: 100px; -} - -.enu-header { +.side-menu-header { height: 150px; width: 100%; z-index: 2300; max-width: 290px; - position: fixed; padding-top: 2px; top: 0; + + &::after { + content: ' '; + display: block; + clear: both; + } } #side-menu.side-menu-with-categories .side-menu-header { @@ -183,13 +193,13 @@ left: 0; width: 100%; z-index: 3001; -} -#side-menu-loader-bar { - height: 4px; - background: var(--side-menu-loader-color, #0e75ac); - width: 0; - transition-property: width; + #side-menu-loader-bar { + height: 4px; + background: var(--side-menu-loader-color, #0e75ac); + width: 0; + transition-property: width; + } } #side-menu.side-menu-big, @@ -261,64 +271,75 @@ margin-top: -2px; } -.side-menu-always-displayed body { - width: calc(100% - 50px) !important; - position: absolute; - left: 50px; -} +.side-menu-always-displayed { + body { + width: calc(100% - 50px) !important; + position: absolute; + left: 50px; + } -.side-menu-always-displayed #header { - position: absolute !important; -} + #header { + position: absolute !important; + } -.side-menu-always-displayed #side-menu { - display: block; -} + #side-menu { + display: block; + } -.side-menu-always-displayed .side-menu-apps-list { - height: 100vh; - top: 0; - overflow: hidden; -} + .side-menu-apps-list { + height: 100vh; + top: 0; + overflow: hidden; + } -.side-menu-always-displayed .side-menu-apps-list--with-settings { - height: calc(100vh - 49px); - top: 49px; -} + .side-menu-apps-list--with-settings { + height: calc(100vh - 49px); + top: 49px; + } -.side-menu-always-displayed .side-menu-apps-list:hover { - overflow: auto; -} + .side-menu-apps-list:hover { + overflow: auto; + } -.side-menu-always-displayed #side-menu, -.side-menu-always-displayed .side-menu-header, -.side-menu-always-displayed .side-menu-apps-list { - width: 50px; -} + #side-menu, + .side-menu-header, + .side-menu-apps-list { + width: 50px; + } -.side-menu-always-displayed #side-menu .side-menu-app-text, -.side-menu-always-displayed #header .side-menu-opener, -.side-menu-always-displayed .side-menu-logo { - display: none; -} + #side-menu .side-menu-app-text, + #header .side-menu-opener, + .side-menu-logo { + display: none; + } -.side-menu-always-displayed #side-menu .side-menu-header { - height: 49px; -} + #side-menu .side-menu-header { + height: 49px; + } -.side-menu-always-displayed #side-menu.open, -.side-menu-always-displayed #side-menu.open .side-menu-apps-list, -.side-menu-always-displayed #side-menu.open .side-menu-header { - width: 100%; -} + #side-menu.open, + #side-menu.open .side-menu-apps-list, + #side-menu.open .side-menu-header { + width: 100%; + } -.side-menu-always-displayed #side-menu.open .side-menu-app-text { - display: inline; -} + #side-menu.open .side-menu-app-text { + display: inline; + } -.side-menu-always-displayed .app-navigation-toggle-wrapper { - right: 0 !important; - margin-left: 0 !important; + .app-navigation-toggle-wrapper { + right: 0 !important; + margin-left: 0 !important; + } + + .side-menu-search { + display: none; + } + + #body-settings, + #body-settings.body-settings-side-menu { + overflow-x: visible; + } } #side-menu.side-menu-with-categories { @@ -326,19 +347,16 @@ height: 100vh; } -.side-menu-with-categories .side-menu-categories { - display: block; - padding: 0; - width: 100%; -} +.side-menu-with-categories { + .side-menu-categories { + display: block; + padding: 0; + width: 100%; + } -.side-menu-with-categories .side-menu-category { - padding: 10px 0; -} - -.side-menu-always-displayed #body-settings, -#body-settings.body-settings-side-menu { - overflow-x: visible; + .side-menu-category { + padding: 10px 0; + } } .app-menu { @@ -353,19 +371,17 @@ float: right; } -.side-menu-search input { - background: none; - border: 0; - border-radius: 0; - color: var(--side-menu-text-color); -} +.side-menu-search { + input { + background: none; + border: 0; + border-radius: 0; + color: var(--side-menu-text-color); -.side-menu-search input::placeholder { - color: var(--side-menu-text-color); -} - -.side-menu-always-displayed .side-menu-search { - display: none; + &::placeholder { + color: var(--side-menu-text-color); + } + } } @media screen and (max-width: 1024px) { diff --git a/templates/js/script.php b/templates/js/script.php index 406c672..6550507 100644 --- a/templates/js/script.php +++ b/templates/js/script.php @@ -1,65 +1,12 @@ - -const SMcreateElement = (tagName, attributes) => { - const element = document.createElement(tagName) - - if (typeof attributes === 'object') { - for (let i in attributes) { - if (i === 'text') { - element.textContent = attributes[i] - } else if (i === 'html') { - element.innerHTML = attributes[i] - } else { - element.setAttribute(i, attributes[i]) - } - } - } - - return element -} - (function() { - const sideMenuContainer = SMcreateElement('div', {id: 'side-menu-container'}) - const sideMenuOpener = SMcreateElement('button', { - 'class': 'side-menu-opener', - 'arial-label': t('side_menu', 'Toggle the menu'), - 'html': `${t('side_menu', 'Toggle the menu')}` - }) - const sideMenu = SMcreateElement('div', {id: 'side-menu'}) - const body = document.querySelector('body') const html = document.querySelector('html') const nextcloud = document.querySelector('#nextcloud') const logo = document.querySelector('.header-left .logo') - const isTouchDevice = window.matchMedia("(pointer: coarse)").matches - window.targetBlankApps = - window.topMenuApps = - window.topSideMenuApps = - window.menuAppsOrder = - window.topMenuAppsMouseOverHiddenLabel = - - - sideMenu.setAttribute('data-bigmenu', '1') - - sideMenu.setAttribute('data-sidewithcategories', '1') - - const sideMenuFocus = () => { let a = document.querySelector('#side-menu .side-menu-app.active a') || document.querySelector('#side-menu .side-menu-app a') @@ -71,101 +18,11 @@ const SMcreateElement = (tagName, attributes) => { document.querySelector('body').addEventListener('side-menu.apps', (e) => { const apps = e.detail.apps; - - - const sideMenu = document.querySelector('#side-menu') - - if (apps.length === 0) { - sideMenu.classList.remove('open') - sideMenu.classList.add('hide') - sideMenuOpener.classList.add('hide') - } else { - sideMenu.classList.remove('hide') - sideMenuOpener.classList.remove('hide') - } - - - if (apps.length === 0) { - html.classList.remove('side-menu-always-displayed') - } else { - html.classList.add('side-menu-always-displayed') - } - - - - if (apps.length === 0) { - html.classList.remove('side-menu-always-displayed') - } else { - html.classList.add('side-menu-always-displayed') - } - - }) body.addEventListener('side-menu.ready', () => { const sideMenu = document.querySelector('#side-menu') - const headerMenuOpener = document.querySelector('#header .side-menu-opener') - const sideMenuOpener = document.querySelectorAll('#side-menu .side-menu-opener') - if (!headerMenuOpener) { - return - } - - - const sideMenuMouseLeave = () => { - sideMenu.classList.remove('open') - sideMenu.removeEventListener('mouseleave', sideMenuMouseLeave) - } - - const sideMenuMouseEnter = () => { - sideMenu.addEventListener('mouseleave', sideMenuMouseLeave) - } - - const sideMenuOpenerMouseEnter = () => { - sideMenu.classList.add('open') - sideMenu.addEventListener('mouseenter', sideMenuMouseEnter) - - sideMenuFocus() - } - - if (!isTouchDevice) { - - headerMenuOpener.addEventListener('mouseenter', sideMenuOpenerMouseEnter) - - sideMenu.classList.add('hide-opener') - - - sideMenu.addEventListener('mouseleave', sideMenuMouseLeave) - sideMenu.addEventListener('mouseenter', sideMenuOpenerMouseEnter) - } - - - headerMenuOpener.addEventListener('click', () => { - sideMenu.classList.add('open') - headerMenuOpener.blur() - sideMenuFocus() - }) - - for (let opener of sideMenuOpener) { - opener.addEventListener('click', () => { - - sideMenu.classList.toggle('open') - - sideMenu.classList.remove('open') - - }) - } - - document.addEventListener('keydown', (e) => { - var key = e.key || e.keyCode - - if ((key === 'o' || key === 79) && e.ctrlKey === true) { - e.preventDefault() - - sideMenu.classList.toggle('open') - sideMenuFocus() - } - }) const sideMenuObserver = new MutationObserver((e) => { if (body.getAttribute('id') !== 'body-settings') { @@ -182,23 +39,4 @@ const SMcreateElement = (tagName, attributes) => { characterData: false }) }) - - body.appendChild(sideMenuContainer) - sideMenuContainer.appendChild(sideMenu) - - - // PageLoader() - - - if (nextcloud) { - if (logo && logo.parentNode !== nextcloud) { - nextcloud.appendChild(logo) - } - - - nextcloud.parentNode.insertBefore(sideMenuOpener, nextcloud) - - nextcloud.parentNode.insertBefore(sideMenuOpener, nextcloud.nextSibling) - - } })();