diff --git a/.eslintrc.js b/.eslintrc.js index ff00609..df432eb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,14 @@ module.exports = { - rules: { - 'no-console': 'off', - }, -}; + env: { + node: true, + }, + extends: [ + "eslint:recommended", + "plugin:vue/vue3-recommended", + "prettier", + ], + rules: { + // override/add rules settings here, such as: + // 'vue/no-unused-vars': 'error' + } +} diff --git a/.gitignore b/.gitignore index d10e458..7cadaec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ /package-lock.json !/l10n/.gitkeep /yarn*.log +/src/admin.js.bk +/templates/settings/admin-form.php.bk diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..a2065a9 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "bracketSpacing": true, + "bracketSameLine": false, + "semi": false, + "singleQuote": true, + "singleAttributePerLine": true, + "printWidth": 160 +} diff --git a/.woodpecker/.publish.yml b/.woodpecker/.publish.yml index d369dcf..c42146a 100644 --- a/.woodpecker/.publish.yml +++ b/.woodpecker/.publish.yml @@ -62,5 +62,5 @@ steps: api_key: from_secret: gitnet_api_key base_url: https://gitnet.fr - note: ${CI_COMMIT_MESSAGE} + # note: ${CI_COMMIT_MESSAGE} files: /var/www/html/artifacts/deblan/side_menu/${CI_COMMIT_TAG/v//}/* diff --git a/CHANGELOG.md b/CHANGELOG.md index d55690a..54b00a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ ## [Unreleased] +## 5.0.0 +### Fixed +* fix apps's order in the standard menu +### Added +* add new translations +* add route `/apps/side_menu/user/config` +* add new UI for admin and personals settings +### Changed +* migrate to Vue 3 and so add/update or remove dependencies +* replace CSS with SCSS +* remove route `/apps/side_menu/js/script` +* remove generated Javascript using PHP +* rewrite the standard menu of Nextcloud +### Security +* fix CVE-2023-44270 +* fix CVE-2024-9506 +* fix CVE-2024-6783 + ## 4.1.1 ### Fixed * fix(CssController): add missing NoCSRFRequired import (#397) @@ -47,9 +65,9 @@ ### Added * update translations * update ci steps names +* fully apply Nextcloud AppMenu.vue updates ### Fixed * add accessibility to open and close buttons (#311) -* fully apply Nextcloud AppMenu.vue updated (#326) * add missing label on the 'save' button in personal settings (fix #318) ### Changed * upgrade axios diff --git a/Makefile b/Makefile index e5b6267..7803a58 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ watch: dep dep: npm i - npm link @nextcloud/vue || sudo npm link @nextcloud/vue .ONESHELL: release: diff --git a/appinfo/info.xml b/appinfo/info.xml index d6a0f5f..f98f716 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -10,14 +10,13 @@ This application is rather suitable for instances that activate a lot of applica Use the shortcut `Ctrl`+`o` to open and to hide the side menu. Use `tab` to navigate. -You can customize colors depending of the theme (Dark theme and Breeze Dark). +You can customize colors depending of the theme. -You can report a bug or request a feature by opening an issue. +To report a bug or request a feature, please open an issue. Requirements: * PHP >= 8.1 -* App `theming` enabled If you like this application and if you want to support the development: @@ -31,7 +30,7 @@ Notice Because I believe in a free and decentralized Internet, [Gitnet](https://gitnet.fr) is **self-hosted at home**. In case of downtime, you can download **Custom Menu** from [here](https://kim.deblan.fr/~side_menu/). ]]> - 4.1.1 + 5.0.0 agpl Simon Vieille SideMenu @@ -54,7 +53,7 @@ In case of downtime, you can download **Custom Menu** from [here](https://kim.de - + OCA\SideMenu\Settings\Admin diff --git a/bin/generate_l10n.php b/bin/generate_l10n.php index e8e666b..146afad 100644 --- a/bin/generate_l10n.php +++ b/bin/generate_l10n.php @@ -31,6 +31,7 @@ function generateJsonContent($translations) chdir(__DIR__.'/../'); foreach (glob('src/l10n/fixtures/*.yaml') as $file) { + echo "$file\n"; $lang = str_replace('.yaml', '', basename($file)); $translations = yaml_parse(file_get_contents($file)); diff --git a/css/admin.css b/css/admin.css deleted file mode 100644 index b3d0b7c..0000000 --- a/css/admin.css +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#side-menu-section input[type="color"] { - width: 100px; - margin: 10px 0 10px 0; - padding: 0; - border-radius: 0; -} - -#-dropside-menu-section input[type="checkbox"] { - vertical-align: middle; -} - -#side-menu-section input[type="range"] { - vertical-align: middle; -} - -#side-menu-section select { - margin: 10px 0 10px 0; -} - -.keyboard-key { - padding: 1px 9px; - margin: 0 2px; - background: #eee; - border: 1px solid #aaa; - color: #555; - border-radius: 3px; -} - -.side-menu-display { - padding: 10px; - border: 2px solid transparent; - max-width: 100%; - cursor: pointer; -} - -.side-menu-display.is-active { - border: 2px solid #91cb7f; -} - -.info { - margin-top: 8px; - padding: 5px; - background: #91cb7f; - color: #fff; - border-radius: var(--border-radius); -} - -#side-menu-section h2 small { - font-size: 11px; - font-weight: normal; -} - -.side-menu-toggler { - cursor: pointer; -} - -.side-menu-setting-list { - margin: 10px 4px 4px 0px; - border: 2px solid var(--color-border-dark); - border-radius: 15px; -} - -.side-menu-setting-list-item { - padding: 5px 10px; - border-bottom: 1px solid var(--color-border-dark); - max-width: 300px; - margin: -1px 0 0 0; - cursor: pointer; - line-height: 32px; -} - -.side-menu-setting-list-item:last-child { - border-bottom: 0; -} - -.side-menu-setting-list-drop { - background: yellow; - border-color: yellow; - height: 34px; -} - -.side-menu-setting.arrow { - color: #ccc; - padding-right: 5px; -} - -.side-menu-setting-list-item input { - margin-top: 0; - height: 21px !important; - min-height: auto !important; -} - -#apps-categories-custom-list select { - width: 100%; -} - -.side-menu-setting-table { - display: table; - width: 100%; -} - -.side-menu-setting-row { - display: table; - margin-bottom: 10px; -} - -.side-menu-setting-row code { - margin-left: 2px; - margin-bottom: 1px; - padding: 3px 10px; - border-radius: 5px; - display: inline-block; - right: 2px; - border: 1px solid var(--color-border-dark); -} - -.side-menu-setting-label { - display: table-cell; - width: 430px; - padding-right: 20px; -} - -.side-menu-setting-label--top { - vertical-align: top; -} - -.side-menu-setting-form { - display: table-cell; - min-width: 300px; -} - -.side-menu-setting-label-short { - width: 300px; -} - -.side-menu-setting-form-long { - width: 400px; -} - -#side-menu-save-progress { - display: inline-block; - width: 0; - height: 15px; - background: #fff; -} - -.btn-reset { - display: inline-block; - cursor: pointer; - position: relative; - top: -8px; - left: 5px; - transition-duration: 0.8s; - transition-property: transform; - transform: rotate(360deg); -} - -.btn-reset--down { - top: 2px; -} - -.btn-reset--progress { - transform: rotate(-359deg); -} - -.badges { - margin-bottom: 14px; - margin-top: 4px; -} - -.badge { - border-width: 1px; - padding: 2px 8px; - margin-right: 2px; - margin-bottom: 5px; - display: inline-block; - border-radius: 4px; - font-size: 13px; -} - -.badge-1 { - background: #d4ce14; - border-color: #cad413; - color: #373a05; -} - -.badge-2 { - background: #96d47f; - border-color: #7ed49b; - color: #333; -} - -.badge-3 { - background: #d4540a; - border-color: #d4700c; - color: #fff; -} - -.badge-4 { - background: #9d81d4; - border-color: #c681d4; - color: #fff; -} diff --git a/css/sideMenu.css b/css/sideMenu.css deleted file mode 100644 index 66a1a8c..0000000 --- a/css/sideMenu.css +++ /dev/null @@ -1,386 +0,0 @@ -/** - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#side-menu { - position: fixed; - top: 0; - left: 0; - height: 100vh; - width: 100%; - max-width: 290px; - background: linear-gradient(90deg, var(--side-menu-background-color, #333) 0%, var(--side-menu-background-color-to, #333) 100%); - z-index: 3000; - color: var(--side-menu-text-color, #fff); - box-shadow: 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; -} - -#side-menu a { - transition: 0.2s; -} - -#side-menu.open { - display: block; -} - -#header .side-menu-opener { - margin-left: 0px; - margin-top: -1px; -} - -.side-menu-settings { - margin-right: 9px; - margin-top: 2px; - float: right; - line-height: 34px; - height: 42px; - display: none; -} - -.side-menu-settings 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); -} - -.side-menu-settings img { - vertical-align: bottom; - margin-left: 3px; - width: 32px; - height: 32px; -} - -#side-menu.open .side-menu-settings { - display: block; -} - -.side-menu-opener { - background: var(--side-menu-opener, url('../img/side-menu-opener.svg')); - background-color: transparent !important; - height: 40px !important; - width: 40px !important; - border-radius: 0 !important; - border: 0 !important; - padding-right: 12px !important; - padding-left: 12px !important; - 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; -} - -.side-menu-opener:active, .side-menu-opener:focus { - background-color: var(--side-menu-current-app-background-color, #444) !important; -} - -.side-menu-closer { - background: url('../img/side-menu-opener-closer.svg'); - display: none; -} - -#side-menu.hide-opener .side-menu-opener, .side-menu-opener.hide, #side-menu.hide { - display: none !important; -} - -.side-menu-apps-list { - height: calc(100vh - 150px); - z-index: 2200; - position: fixed; - top: 150px; - width: 100%; - max-width: 290px; - overflow: auto; -} - -.side-menu-app-icon { - width: 20px; - vertical-align: middle; - margin-top: -4px; - margin-right: 10px; - filter: invert(var(--side-menu-icon-invert-filter, 0%)); - 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:hover, .side-menu-app.active, .side-menu-app a:focus { - background: var(--side-menu-current-app-background-color, #444); -} - -.side-menu-logo { - text-align: center; -} - -.side-menu-logo img { - max-width: 60%; - max-height: 100px; -} - -.enu-header { - height: 150px; - width: 100%; - z-index: 2300; - max-width: 290px; - position: fixed; - padding-top: 2px; - top: 0; -} - -#side-menu.side-menu-with-categories .side-menu-header { - max-width: 295px; -} - -#side-menu.hide-opener .side-menu-logo { - margin-top: 10px; -} - -#side-menu-loader { - position: fixed; - top: 0; - 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.side-menu-big, #side-menu.side-menu-with-categories { - max-width: 100%; - height: auto; -} - -.side-menu-big .side-menu-header, .side-menu-with-categories .side-menu-header { - height: auto; -} - -.side-menu-big .side-menu-apps-list, .side-menu-with-categories .side-menu-apps-list { - height: auto; - position: static; - max-width: 100vw; - overflow: auto; -} - -.side-menu-big .side-menu-app a, .side-menu-with-categories .side-menu-app a { - padding: 7px 0 7px 7px; -} - -.side-menu-categories-wrapper { - padding-bottom: 70px; -} - -.side-menu-categories { - max-height: calc(100vh - 55px); - overflow: auto; - position: relative; - display: flex; - flex-wrap: wrap; - justify-content: center; - padding: 0 10% 0 10%; -} - -.side-menu-category { - padding: 10px 20px; - flex: 1 1 auto; -} - -.side-menu-category-title { - padding-left: 10px; - color: var(--side-menu-text-color, #fff); - font-weight: bold; - font-size: 20px; - margin-bottom: 12px; - line-height: 30px; - margin-top: 0; -} - -.side-menu-loader { - text-align: center; -} - -.side-menu-loader svg { - width: 45px; - margin: auto; - stroke: var(--side-menu-text-color, #fff); -} - -.side-menu-with-categories .side-menu-app-icon, .side-menu-big .side-menu-app-icon { - vertical-align: middle; - margin-top: -2px; -} - -.side-menu-always-displayed body { - width: calc(100% - 50px) !important; - position: absolute; - left: 50px; -} - -.side-menu-always-displayed #header { - position: absolute !important; -} - -.side-menu-always-displayed #side-menu { - display: block; -} - -.side-menu-always-displayed .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-always-displayed .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-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-always-displayed #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-always-displayed #side-menu.open .side-menu-app-text { - display: inline; -} - -.side-menu-always-displayed .app-navigation-toggle-wrapper { - right: 0 !important; - margin-left: 0 !important; -} - -#side-menu.side-menu-with-categories { - max-width: 290px; - height: 100vh; -} - -.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; -} - -.app-menu { - visibility: hidden; -} - -.app-menu.show { - visibility: visible; -} - -.side-menu-search { - float: right; -} - -.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; -} - -@media screen and (max-width: 1024px) { - #side-menu.side-menu-big { - max-width: 290px; - height: 100vh; - } - - #side-menu.hide-opener.side-menu-big .side-menu-search { - float: none; - } - - .side-menu-categories { - display: block; - padding: 0; - } - - .side-menu-category { - padding: 10px 0; - } -} - -@media screen and (min-width: 1024px) { - .side-menu-closer { - display: block; - float: right; - margin-right: 9px; - } - - .side-menu-big .side-menu-header { - max-width: 100%; - } -} diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index c5181ef..2d4f364 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -8,7 +8,9 @@ use OC\Security\CSP\ContentSecurityPolicyNonceManager; use OC\User\User; use OCA\SideMenu\Service\AppRepository; use OCA\SideMenu\Service\CategoryRepository; +use OCA\SideMenu\Service\Color; use OCA\SideMenu\Service\ConfigProxy; +use OCA\Theming\ThemingDefaults; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; @@ -81,6 +83,12 @@ class Application extends App implements IBootstrap $c->get(IConfig::class), ); }); + + $context->registerService(Color::class, function (ContainerInterface $c) { + return new Color( + $c->get(ThemingDefaults::class), + ); + }); } public function boot(IBootContext $context): void @@ -119,8 +127,7 @@ class Application extends App implements IBootstrap protected function addAssets() { - Util::addScript(self::APP_ID, 'sideMenu'); - Util::addStyle(self::APP_ID, 'sideMenu'); + Util::addScript(self::APP_ID, 'side_menu-menu'); $assets = [ 'stylesheet' => [ @@ -131,14 +138,6 @@ class Application extends App implements IBootstrap 'rel' => 'stylesheet', ], ], - 'script' => [ - 'route' => 'side_menu.Js.script', - 'type' => 'script', - 'route_attr' => 'src', - 'attr' => [ - 'nonce' => $this->cspnm->getNonce(), - ], - ], ]; $cache = $this->config->getAppValue(self::APP_ID, 'cache', '0'); diff --git a/lib/Controller/AdminSettingController.php b/lib/Controller/AdminSettingController.php index 279a34c..e9ba8f9 100644 --- a/lib/Controller/AdminSettingController.php +++ b/lib/Controller/AdminSettingController.php @@ -20,10 +20,14 @@ namespace OCA\SideMenu\Controller; use OCA\SideMenu\AppInfo\Application; +use OCA\SideMenu\Service\Color; +use OCA\SideMenu\Service\ConfigProxy; +use OCA\SideMenu\Service\LangRepository; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\FrontpageRoute; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\DataDownloadResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\RedirectResponse; use OCP\IConfig; use OCP\IRequest; @@ -35,7 +39,10 @@ class AdminSettingController extends Controller $appName, IRequest $request, protected IConfig $config, - protected IURLGenerator $urlGenerator + protected ConfigProxy $configProxy, + protected IURLGenerator $urlGenerator, + protected Color $color, + protected LangRepository $langRepository, ) { parent::__construct($appName, $request); } @@ -60,6 +67,7 @@ class AdminSettingController extends Controller $excludedKeys = [ 'cache', 'cache-categories', + 'langs', ]; foreach ($keys as $key) { @@ -76,4 +84,135 @@ class AdminSettingController extends Controller 'text/json' ); } + + #[NoCSRFRequired] + #[FrontpageRoute(verb: 'GET', url: '/admin/config')] + public function configuration(): JSONResponse + { + $keys = $this->config->getAppKeys(Application::APP_ID); + $booleans = [ + 'opener-only', + 'opener-hover', + 'display-logo', + 'use-avatar', + 'add-logo-link', + 'show-settings', + 'loader-enabled', + 'always-displayed', + 'enabled', + 'force', + 'big-menu', + 'external-sites-in-top-menu', + 'force-light-icon', + 'side-with-categories', + 'default-enabled', + ]; + + $arrays = [ + 'apps-categories-custom', + 'big-menu-hidden-apps', + 'apps-order', + 'categories-custom', + 'categories-order', + 'target-blank-apps', + 'top-menu-apps', + 'top-side-menu-apps', + ]; + + $integers = [ + 'background-color-opacity', + 'dark-mode-background-color-opacity', + 'dark-mode-icon-invert-filter', + 'dark-mode-icon-opacity', + 'icon-invert-filter', + 'icon-opacity', + 'target-blank-mode', + 'top-menu-mouse-over-hidden-label', + ]; + + $defaults = [ + 'opener-only' => '0', + 'opener-hover' => '0', + 'display-logo' => '1', + 'use-avatar' => '0', + 'add-logo-link' => '1', + 'show-settings' => '0', + 'loader-enabled' => '1', + 'always-displayed' => '0', + 'enabled' => '1', + 'force' => '0', + 'big-menu' => '0', + 'external-sites-in-top-menu' => '0', + 'force-light-icon' => '0', + 'side-with-categories' => '0', + 'cache' => '1', + 'default-enabled' => '1', + + 'apps-categories-custom' => '[]', + 'big-menu-hidden-apps' => '[]', + 'apps-order' => '[]', + 'categories-custom' => '[]', + 'categories-order' => '[]', + 'target-blank-apps' => '[]', + 'top-menu-apps' => '[]', + 'top-side-menu-apps' => '[]', + 'cache-categories' => '[]', + + 'background-color-opacity' => '100', + 'dark-mode-background-color-opacity' => '100', + 'dark-mode-icon-invert-filter' => '0', + 'dark-mode-icon-opacity' => '100', + 'icon-invert-filter' => '0', + 'icon-opacity' => '100', + 'top-menu-mouse-over-hidden-label' => '0', + + 'opener' => 'side-menu-opener', + 'dark-mode-opener' => 'side-menu-opener', + 'size-icon' => 'normal', + 'size-text' => 'normal', + 'opener-position' => 'before', + + 'background-color' => $this->color->getPrimaryColor(), + 'background-color-to' => $this->color->getLightenPrimaryColor(), + 'current-app-background-color' => $this->color->getDarkenPrimaryColor(), + 'text-color' => $this->color->getTextColorPrimary(), + 'loader-color' => $this->color->getLightenPrimaryColor(), + + 'dark-mode-background-color' => $this->color->getDarkenPrimaryColor(), + 'dark-mode-background-color-to' => $this->color->getDarkenPrimaryColor(), + 'dark-mode-current-app-background-color' => $this->color->getDarkenPrimaryColor2(), + 'dark-mode-text-color' => $this->color->getTextColorPrimary(), + 'dark-mode-loader-color' => $this->color->getLightenPrimaryColor(), + + 'categories-order-type' => 'default', + ]; + + $config = []; + + foreach ($keys as $key) { + if (!isset($defaults[$key])) { + continue; + } + + if (in_array($key, $booleans)) { + $config[$key] = $this->configProxy->getAppValueBool($key, $defaults[$key]); + } elseif (in_array($key, $arrays)) { + $config[$key] = $this->configProxy->getAppValueArray($key, $defaults[$key]); + } elseif (in_array($key, $integers)) { + $config[$key] = $this->configProxy->getAppValueInt($key, $defaults[$key]); + } else { + $config[$key] = $this->configProxy->getAppValue($key, $defaults[$key]); + } + } + + foreach ($defaults as $key => $default) { + if (!array_key_exists($key, $config)) { + $config[$key] = $default; + } + } + + $config['langs'] = $this->langRepository->getUsedLangs(); + + return new JSONResponse($config); + } } diff --git a/lib/Controller/AppController.php b/lib/Controller/AppController.php index f8cb357..6bc2e98 100644 --- a/lib/Controller/AppController.php +++ b/lib/Controller/AppController.php @@ -37,7 +37,7 @@ class AppController extends Controller IRequest $request, protected AppRepository $appRepository, protected IURLGenerator $urlGenerator, - protected ConfigProxy $config + protected ConfigProxy $config, ) { parent::__construct($appName, $request); } diff --git a/lib/Controller/CssController.php b/lib/Controller/CssController.php index 5b3a2dd..6822563 100644 --- a/lib/Controller/CssController.php +++ b/lib/Controller/CssController.php @@ -41,7 +41,7 @@ class CssController extends Controller IRequest $request, protected ConfigProxy $config, protected ThemingDefaults $theming, - protected Color $color + protected Color $color, ) { parent::__construct($appName, $request); @@ -66,10 +66,6 @@ class CssController extends Controller $topMenuApps = $this->config->getAppValueArray('top-menu-apps', '[]'); $topSideMenuApps = $this->config->getAppValueArray('top-side-menu-apps', '[]'); - $isAccessibilityAppEnabled = $this->config->getAppValueBool('enabled', '0', 'accessibility'); - $isBreezeDarkAppEnabled = $this->config->getAppValueBool('enabled', '0', 'breezedark'); - $isBreezeDarkGlobalEnabled = $this->config->getAppValueBool('theme_enabled', '0', 'breezedark'); - if ($this->user) { $userTopMenuApps = $this->config->getUserValueArray($this->user, 'top-menu-apps', '[]'); $userTopSideMenuApps = $this->config->getUserValueArray($this->user, 'top-side-menu-apps', '[]'); @@ -81,81 +77,62 @@ class CssController extends Controller if (!empty($userTopSideMenuApps) && !$isForced) { $topSideMenuApps = $userTopSideMenuApps; } - - $isDarkThemeUserEnabled = 'dark' === $this->config->getUserValue($this->user, 'theme', '', 'accessibility'); - $isBreezeDarkUserEnabled = $this->config->getUserValue($this->user, 'theme_enabled', '', 'breezedark'); - - $isBreezeDarkUserEnabled = '1' === $isBreezeDarkUserEnabled - || ($isBreezeDarkGlobalEnabled && '' === $isBreezeDarkUserEnabled); - } else { - $isDarkThemeUserEnabled = false; - $isBreezeDarkUserEnabled = false; } - $isDarkMode = ($isAccessibilityAppEnabled && $isDarkThemeUserEnabled) - || ($isBreezeDarkAppEnabled && $isBreezeDarkUserEnabled); + $lightenPrimaryColor = $this->color->getLightenPrimaryColor(); + $darkenPrimaryColor = $this->color->getDarkenPrimaryColor(); + $darkenPrimaryColor2 = $this->color->getDarkenPrimaryColor2(); + $textColor = $this->color->getTextColorPrimary(); - $primaryColor = $this->theming->getColorPrimary(); - $lightenPrimaryColor = $this->color->adjustBrightness($primaryColor, 0.2); - $darkenPrimaryColor = $this->color->adjustBrightness($primaryColor, -0.2); - $darkenPrimaryColor2 = $this->color->adjustBrightness($primaryColor, -0.3); - $textColor = $this->theming->getTextColorPrimary(); - - if ($isDarkMode) { - $backgroundColor = $this->config->getAppValue('dark-mode-background-color', $darkenPrimaryColor); - $backgroundColorTo = $this->config->getAppValue('dark-mode-background-color-to', $darkenPrimaryColor); - $currentAppBackgroundColor = $this->config->getAppValue( - 'dark-mode-current-app-background-color', - $darkenPrimaryColor2 - ); - $loaderColor = $this->config->getAppValue('dark-mode-loader-color', $lightenPrimaryColor); - $textColor = $this->config->getAppValue('dark-mode-text-color', $textColor); - $iconInvertFilter = abs($this->config->getAppValueInt('dark-mode-icon-invert-filter', '0')).'%'; - $iconOpacity = abs($this->config->getAppValueInt('dark-mode-icon-opacity', '100') / 100); - $opener = $this->config->getAppValue('dark-mode-opener', 'side-menu-opener'); - - $opacity = $this->config->getAppValueInt('dark-mode-background-color-opacity', '100'); - $backgroundOpacity = dechex($opacity * 255 / 100); - } else { - $backgroundColor = $this->config->getAppValue('background-color', $darkenPrimaryColor); - $backgroundColorTo = $this->config->getAppValue('background-color-to', $darkenPrimaryColor); - $currentAppBackgroundColor = $this->config->getAppValue( - 'current-app-background-color', - $darkenPrimaryColor2 - ); - $loaderColor = $this->config->getAppValue('loader-color', $lightenPrimaryColor); - $textColor = $this->config->getAppValue('text-color', $textColor); - $iconInvertFilter = abs($this->config->getAppValueInt('icon-invert-filter', '0')).'%'; - $iconOpacity = abs($this->config->getAppValueInt('icon-opacity', '100') / 100); - $opener = $this->config->getAppValue('opener', 'side-menu-opener'); - - $opacity = $this->config->getAppValueInt('background-color-opacity', '100'); - $backgroundOpacity = dechex($opacity * 255 / 100); - } + $backgroundColor = $this->config->getAppValue('background-color', $darkenPrimaryColor); + $backgroundColorTo = $this->config->getAppValue('background-color-to', $darkenPrimaryColor); + $opacity = $this->config->getAppValueInt('background-color-opacity', '100'); + $backgroundOpacity = dechex($opacity * 255 / 100); $backgroundColor .= $backgroundOpacity; $backgroundColorTo .= $backgroundOpacity; + $darkBackgroundColor = $this->config->getAppValue('dark-mode-background-color', $darkenPrimaryColor); + $darkBackgroundColorTo = $this->config->getAppValue('dark-mode-background-color-to', $darkenPrimaryColor); + $darkOpacity = $this->config->getAppValueInt('dark-mode-background-color-opacity', '100'); + $darkBackgroundOpacity = dechex($opacity * 255 / 100); + + $darkBackgroundColor .= $darkBackgroundOpacity; + $darkBackgroundColorTo .= $darkBackgroundOpacity; + return [ 'vars' => [ - 'background-color' => $backgroundColor, - 'background-color-to' => $backgroundColorTo, - 'current-app-background-color' => $currentAppBackgroundColor, - 'loader-color' => $loaderColor, - 'text-color' => $textColor, - 'opener' => $opener, - 'icon-invert-filter' => $iconInvertFilter, - 'icon-opacity' => $iconOpacity, + 'light' => [ + 'background-color' => $backgroundColor, + 'background-color-to' => $backgroundColorTo, + 'current-app-background-color' => $this->config->getAppValue( + 'current-app-background-color', + $darkenPrimaryColor2 + ), + 'loader-color' => $this->config->getAppValue('loader-color', $lightenPrimaryColor), + 'text-color' => $this->config->getAppValue('text-color', $textColor), + 'opener' => $this->config->getAppValue('opener', 'side-menu-opener'), + 'icon-invert-filter' => abs($this->config->getAppValueInt('icon-invert-filter', '0')).'%', + 'icon-opacity' => abs($this->config->getAppValueInt('icon-opacity', '100') / 100), + ], + 'dark' => [ + 'background-color' => $darkBackgroundColor, + 'background-color-to' => $darkBackgroundColorTo, + 'current-app-background-color' => $this->config->getAppValue( + 'dark-mode-current-app-background-color', + $darkenPrimaryColor2 + ), + 'loader-color' => $this->config->getAppValue('dark-mode-loader-color', $lightenPrimaryColor), + 'text-color' => $this->config->getAppValue('dark-mode-text-color', $textColor), + 'opener' => $this->config->getAppValue('dark-mode-opener', 'side-menu-opener'), + 'icon-invert-filter' => abs($this->config->getAppValueInt('dark-mode-icon-invert-filter', '0')).'%', + 'icon-opacity' => abs($this->config->getAppValueInt('dark-mode-icon-opacity', '100') / 100), + ] ], - 'display-logo' => $this->config->getAppValueBool('display-logo', '1'), 'opener-only' => $this->config->getAppValueBool('opener-only', '0'), - 'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', '0'), 'size-icon' => $this->config->getAppValue('size-icon', 'normal'), 'size-text' => $this->config->getAppValue('size-text', 'normal'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'), - 'big-menu' => $this->config->getAppValueBool('big-menu', '0'), - 'top-menu-apps' => $topMenuApps, - 'top-side-menu-apps' => $topSideMenuApps, ]; } } diff --git a/lib/Controller/JsController.php b/lib/Controller/JsController.php index 8f06345..a8be206 100644 --- a/lib/Controller/JsController.php +++ b/lib/Controller/JsController.php @@ -43,7 +43,7 @@ class JsController extends Controller IRequest $request, protected ConfigProxy $config, protected ThemingDefaults $themingDefaults, - protected IFactory $l10nFactory + protected IFactory $l10nFactory, ) { parent::__construct($appName, $request); @@ -54,18 +54,6 @@ class JsController extends Controller $this->l10nFactory = $l10nFactory; } - #[NoCSRFRequired] - #[NoAdminRequired] - #[PublicPage] - #[FrontpageRoute(verb: 'GET', url: '/js/script')] - public function script(): TemplateResponse - { - $response = new TemplateResponse(Application::APP_ID, 'js/script', $this->getConfig(), 'blank'); - $response->addHeader('Content-Type', 'text/javascript'); - - return $response; - } - #[NoCSRFRequired] #[NoAdminRequired] #[PublicPage] @@ -145,6 +133,8 @@ class JsController extends Controller 'opener-hover' => $this->config->getAppValueBool('opener-hover', '0'), 'external-sites-in-top-menu' => $this->config->getAppValueBool('external-sites-in-top-menu', '0'), 'force-light-icon' => $this->config->getAppValueBool('force-light-icon', '0'), + 'display-logo' => $this->config->getAppValueBool('display-logo', '1'), + 'use-avatar' => $this->config->getAppValueBool('use-avatar', '0'), 'hide-when-no-apps' => $this->config->getAppValueBool('hide-when-no-apps', '0'), 'loader-enabled' => $this->config->getAppValueBool('loader-enabled', '1'), 'always-displayed' => $this->config->getAppValueBool('always-displayed', '0'), diff --git a/lib/Controller/NavController.php b/lib/Controller/NavController.php index 1d90849..23540df 100644 --- a/lib/Controller/NavController.php +++ b/lib/Controller/NavController.php @@ -42,7 +42,7 @@ class NavController extends Controller protected AppRepository $appRepository, protected CategoryRepository $categoryRepository, protected URLGenerator $router, - protected IFactory $l10nFactory + protected IFactory $l10nFactory, ) { parent::__construct($appName, $request); } @@ -115,6 +115,7 @@ class NavController extends Controller $appsCategories[$app['id']][] = $category; $items[$category]['apps'][$app['id']] = [ + 'id' => $app['id'], 'name' => $app['name'], 'href' => $app['href'], 'icon' => $app['icon'], diff --git a/lib/Controller/PersonalSettingController.php b/lib/Controller/PersonalSettingController.php index 482a7c6..9b63576 100644 --- a/lib/Controller/PersonalSettingController.php +++ b/lib/Controller/PersonalSettingController.php @@ -25,6 +25,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\FrontpageRoute; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\JSONResponse; use OCP\IConfig; use OCP\IRequest; use OCP\IUserSession; @@ -36,14 +37,14 @@ class PersonalSettingController extends Controller IRequest $request, protected IConfig $config, protected ConfigProxy $configProxy, - protected IUserSession $userSession + protected IUserSession $userSession, ) { parent::__construct($appName, $request); } #[NoCSRFRequired] #[NoAdminRequired] - #[FrontpageRoute(verb: 'POST', url: '/personalSetting/valueSet')] + #[FrontpageRoute(verb: 'POST', url: '/user/valueSet')] public function valueSet($name, $value): array { $doSave = false; @@ -65,22 +66,7 @@ class PersonalSettingController extends Controller } } - if ('target-blank-apps' === $name) { - $doSave = true; - $data = json_decode($value, true); - - if (!is_array($data)) { - $doSave = false; - } else { - foreach ($data as $v) { - if (!is_string($v)) { - $doSave = false; - } - } - } - } - - if (in_array($name, ['top-menu-apps', 'top-side-menu-apps', 'apps-order'])) { + if (in_array($name, ['target-blank-apps', 'top-menu-apps', 'top-side-menu-apps', 'apps-order'])) { $doSave = true; $data = json_decode($value, true); @@ -110,4 +96,62 @@ class PersonalSettingController extends Controller return []; } + + #[NoCSRFRequired] + #[FrontpageRoute(verb: 'GET', url: '/user/config')] + public function configuration(): JSONResponse + { + $user = $this->userSession->getUser(); + $keys = $this->config->getUserKeys($user->getUid(), Application::APP_ID); + + $booleans = [ + 'enabled', + ]; + + $arrays = [ + 'apps-order', + 'target-blank-apps', + 'top-menu-apps', + 'top-side-menu-apps', + ]; + + $integers = [ + 'target-blank-mode', + ]; + + $defaults = [ + 'enabled' => '1', + 'target-blank-mode' => '1', + 'apps-order' => '[]', + 'target-blank-apps' => '[]', + 'top-menu-apps' => '[]', + 'top-side-menu-apps' => '[]', + ]; + + $config = []; + + foreach ($keys as $key) { + if (!isset($defaults[$key])) { + continue; + } + + if (in_array($key, $booleans)) { + $config[$key] = $this->configProxy->getUserValueBool($user, $key, $defaults[$key]); + } elseif (in_array($key, $arrays)) { + $config[$key] = $this->configProxy->getUserValueArray($user, $key, $defaults[$key]); + } elseif (in_array($key, $integers)) { + $config[$key] = $this->configProxy->getUserValueInt($user, $key, $defaults[$key]); + } else { + $config[$key] = $this->configProxy->getUserValue($user, $key, $defaults[$key]); + } + } + + foreach ($defaults as $key => $default) { + if (!array_key_exists($key, $config)) { + $config[$key] = $default; + } + } + + return new JSONResponse($config); + } } diff --git a/lib/Service/CategoryRepository.php b/lib/Service/CategoryRepository.php index 81e44e2..404c061 100644 --- a/lib/Service/CategoryRepository.php +++ b/lib/Service/CategoryRepository.php @@ -20,8 +20,9 @@ class CategoryRepository protected ConfigProxy $config, protected IConfig $iConfig, protected IFactory $l10nFactory, - protected IUserSession $userSession - ) {} + protected IUserSession $userSession, + ) { + } /** * Retrieves categories. diff --git a/lib/Service/Color.php b/lib/Service/Color.php index cf90dd6..98e4ed5 100644 --- a/lib/Service/Color.php +++ b/lib/Service/Color.php @@ -2,6 +2,8 @@ namespace OCA\SideMenu\Service; +use OCA\Theming\ThemingDefaults; + /** * class Color. * @@ -9,6 +11,10 @@ namespace OCA\SideMenu\Service; */ class Color { + public function __construct(protected ThemingDefaults $theming) + { + } + /** * @thanks https://stackoverflow.com/posts/54393956/revision */ @@ -31,4 +37,29 @@ class Color return '#'.implode($hexCode); } + + public function getPrimaryColor() + { + return $this->theming->getColorPrimary(); + } + + public function getLightenPrimaryColor() + { + return $this->adjustBrightness($this->getPrimaryColor(), 0.2); + } + + public function getDarkenPrimaryColor() + { + return $this->adjustBrightness($this->getPrimaryColor(), -0.2); + } + + public function getDarkenPrimaryColor2() + { + return $this->adjustBrightness($this->getPrimaryColor(), -0.3); + } + + public function getTextColorPrimary() + { + return $this->theming->getTextColorPrimary(); + } } diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index 7796f72..0d806c7 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -39,8 +39,9 @@ class Admin implements ISettings protected CategoryRepository $categoryRepository, protected ThemingDefaults $theming, protected Color $color, - protected LangRepository $langRepository - ) {} + protected LangRepository $langRepository, + ) { + } /** * @return TemplateResponse diff --git a/lib/Settings/AdminSection.php b/lib/Settings/AdminSection.php index 67c8fcc..820b0f3 100644 --- a/lib/Settings/AdminSection.php +++ b/lib/Settings/AdminSection.php @@ -28,8 +28,9 @@ class AdminSection implements IIconSection { public function __construct( protected IURLGenerator $url, - protected IL10N $l - ) {} + protected IL10N $l, + ) { + } public function getID() { diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index 2aebec8..fbc1e57 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -33,8 +33,9 @@ class Personal implements ISettings protected IL10N $l, protected ConfigProxy $config, protected IUserSession $userSession, - protected AppRepository $appRepository - ) {} + protected AppRepository $appRepository, + ) { + } /** * @return TemplateResponse diff --git a/lib/Settings/PersonalSection.php b/lib/Settings/PersonalSection.php index efe180c..a42a56e 100644 --- a/lib/Settings/PersonalSection.php +++ b/lib/Settings/PersonalSection.php @@ -30,8 +30,9 @@ class PersonalSection implements IIconSection public function __construct( protected IURLGenerator $url, protected IL10N $l, - protected ConfigProxy $configProxy - ) {} + protected ConfigProxy $configProxy, + ) { + } public function getID() { diff --git a/package.json b/package.json index f002d50..0a23693 100644 --- a/package.json +++ b/package.json @@ -1,73 +1,54 @@ { - "license": "agpl", - "private": true, - "scripts": { - "build": "NODE_ENV=production ./node_modules/.bin/webpack-cli --progress --config webpack.js", - "dev": "NODE_ENV=development ./node_modules/.bin/webpack-cli --progress --config webpack.js", - "watch": "NODE_ENV=development ./node_modules/.bin/webpack-cli --progress --watch --config webpack.js", - "lint": "./node_modules/.bin/eslint --ext .js,.vue src", - "lint:fix": "./node_modules/.bin/eslint --ext .js,.vue src --fix", - "stylelint": "./node_modules/.bin/stylelint src", - "stylelint:fix": "./node_modules/.bin/stylelint src --fix" - }, - "dependencies": { - "@nextcloud/axios": "^2.5.1", - "@nextcloud/browserslist-config": "^3.0.1", - "@nextcloud/event-bus": "^3.3.1", - "@nextcloud/initial-state": "^2.2.0", - "@nextcloud/l10n": "^3.1.0", - "@nextcloud/vue": "^8.19.0", - "@vueuse/core": "^11.1.0", - "axios": "^1.6.7", - "trim": "^1.0.1" - }, - "browserslist": [ - "extends @nextcloud/browserslist-config" - ], - "engines": { - "node": ">=16.0.0" - }, - "devDependencies": { - "@babel/node": "^7.25.7", - "@babel/plugin-transform-private-methods": "^7.25.7", - "@babel/preset-typescript": "^7.24.7", - "@cypress/vue2": "^2.1.1", - "@cypress/webpack-preprocessor": "^6.0.2", - "@nextcloud/babel-config": "^1.2.0", - "@nextcloud/eslint-config": "^8.4.1", - "@nextcloud/stylelint-config": "^3.0.1", - "@nextcloud/typings": "^1.9.1", - "@nextcloud/webpack-vue-config": "^6.0.1", - "@simplewebauthn/types": "^10.0.0", - "@types/dockerode": "^3.3.29", - "@types/wait-on": "^5.3.4", - "@vue/tsconfig": "^0.5.1", - "babel-loader": "^9.2.1", - "babel-loader-exclude-node-modules-except": "^1.2.1", - "babel-plugin-module-resolver": "^5.0.2", - "colord": "^2.9.3", - "eslint-plugin-cypress": "^3.5.0", - "eslint-plugin-es": "^4.1.0", - "exports-loader": "^5.0.0", - "file-loader": "^6.2.0", - "handlebars-loader": "^1.7.3", - "jasmine-core": "~2.5.2", - "jasmine-sinon": "^0.4.0", - "jsdoc": "^4.0.2", - "raw-loader": "^4.0.2", - "sass": "^1.79.3", - "stylelint": "^16.9.0", - "stylelint-use-logical": "^2.1.2", - "ts-loader": "^9.5.0", - "ts-node": "^10.9.1", - "tslib": "^2.7.0", - "typescript": "^5.6.2", - "vue-loader": "^15.9.8", - "vue-template-compiler": "^2.7.16", - "wait-on": "^8.0.1", - "webpack": "^5.94.0", - "webpack-cli": "^5.0.2", - "webpack-merge": "^6.0.1", - "workbox-webpack-plugin": "^7.1.0" - } + "license": "agpl", + "private": true, + "module": true, + "scripts": { + "build": "NODE_ENV=production ./node_modules/.bin/webpack-cli --progress --config webpack.config.js", + "dev": "NODE_ENV=development ./node_modules/.bin/webpack-cli --progress --config webpack.config.js", + "watch": "NODE_ENV=development ./node_modules/.bin/webpack-cli --progress --watch --config webpack.config.js", + "lint": "ESLINT_USE_FLAT_CONFIG=false ./node_modules/.bin/eslint --ext .js,.vue --ignore-path .gitignore --fix src", + "format": "./node_modules/.bin/prettier src --write" + }, + "dependencies": { + "@babel/core": ">=7.12.0 <8.0.0", + "@nextcloud/router": "^3.0.1", + "@nextcloud/vue": "^9.0.0-alpha.8", + "node-polyfill-webpack-plugin": "^4.1.0", + "pinia": "^3.0.1", + "postcss": "^7.0.0 || ^8.0.1", + "vue": "^3.5.13", + "vuedraggable": "^4.1.0" + }, + "browserslist": [ + "extends @nextcloud/browserslist-config" + ], + "engines": { + "node": ">=16.0.0" + }, + "devDependencies": { + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@nextcloud/axios": "^2.5.1", + "@nextcloud/browserslist-config": "^3.0.1", + "@nextcloud/event-bus": "^3.3.1", + "@nextcloud/initial-state": "^2.2.0", + "@nextcloud/l10n": "^3.2.0", + "babel-loader": "^9.1.3", + "css-loader": "^7.1.2", + "eslint": "^9.19.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-vue": "^9.32.0", + "file-loader": "^6.2.0", + "mini-css-extract-plugin": "^2.9.1", + "postcss-loader": "^8.1.1", + "prettier": "3.4.2", + "sass": "^1.78.0", + "sass-loader": "^16.0.1", + "source-map-loader": "^5.0.0", + "style-loader": "^4.0.0", + "vue-loader": "^17.4.2", + "vue-router": "^4.4.5", + "webpack": "^5.94.0", + "webpack-cli": "^5.1.4", + "webpack-notifier": "^1.15.0" + } } diff --git a/screenshots/admin_settings.png b/screenshots/admin_settings.png index 4d7a0e0..eae14bb 100644 Binary files a/screenshots/admin_settings.png and b/screenshots/admin_settings.png differ diff --git a/screenshots/personal_settings.png b/screenshots/personal_settings.png index 05a73ee..480063b 100644 Binary files a/screenshots/personal_settings.png and b/screenshots/personal_settings.png differ diff --git a/src/AdminCategoriesCustom.vue b/src/AdminCategoriesCustom.vue deleted file mode 100644 index 21de363..0000000 --- a/src/AdminCategoriesCustom.vue +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - diff --git a/src/AppMenu.vue b/src/AppMenu.vue deleted file mode 100644 index 9558eb5..0000000 --- a/src/AppMenu.vue +++ /dev/null @@ -1,393 +0,0 @@ - - - - - - - - diff --git a/src/Loader.vue b/src/Loader.vue deleted file mode 100644 index d059f68..0000000 --- a/src/Loader.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - diff --git a/src/PageLoader.js b/src/PageLoader.js deleted file mode 100644 index 3c8bd13..0000000 --- a/src/PageLoader.js +++ /dev/null @@ -1,20 +0,0 @@ -const createElement = require('./lib/createElement') - -const PageLoader = () => { - const pageLoader = createElement('div', {id: 'side-menu-loader'}) - const pageLoaderBar = createElement('div', {id: 'side-menu-loader-bar'}) - - pageLoader.appendChild(pageLoaderBar) - document.querySelector('body').appendChild(pageLoader) - - let pageLoaderValue = 0 - - window.addEventListener('beforeunload', () => { - setInterval(() => { - pageLoaderBar.style.width = pageLoaderValue.toString() + '%' - pageLoaderValue = Math.min(pageLoaderValue + .2, 100) - }, 25) - }) -} - -module.exports = PageLoader diff --git a/src/SideMenu.js b/src/SideMenu.js deleted file mode 100644 index 22ac3f5..0000000 --- a/src/SideMenu.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -import Vue from 'vue' -import AppMenu from './AppMenu.vue' -import SideMenu from './SideMenu.vue' -import SideMenuBig from './SideMenuBig.vue' -import SideMenuWithCategories from './SideMenuWithCategories.vue' -import PageLoader from './PageLoader' - -Vue.prototype.OC = OC -Vue.prototype.t = OC.L10N.translate - -window.PageLoader = PageLoader - -const mountSideMenuComponent = () => { - const container = document.querySelector('#side-menu') - - if (!container) { - return window.setTimeout(mountSideMenuComponent, 50) - } - - const component = (() => { - if (container.getAttribute('data-bigmenu')) { - return SideMenuBig - } else if(container.getAttribute('data-sidewithcategories')) { - return SideMenuWithCategories - } else { - return SideMenu - } - })() - - const View = Vue.extend(component) - const App = new View({}) - - App.$mount('#side-menu') - - document.querySelector('body').dispatchEvent(new CustomEvent('side-menu.ready')) -} - -const mountAppMenu = () => { - const container = document.querySelector('#header .app-menu') - - if (!container) { - return window.setTimeout(mountAppMenu, 50) - } - - const View = Vue.extend(AppMenu) - const App = new View({}) - - App.$mount('#header .app-menu') -} - -mountSideMenuComponent() -mountAppMenu() diff --git a/src/SideMenu.vue b/src/SideMenu.vue deleted file mode 100644 index 00bd3d1..0000000 --- a/src/SideMenu.vue +++ /dev/null @@ -1,170 +0,0 @@ - - - - diff --git a/src/SideMenuBig.vue b/src/SideMenuBig.vue deleted file mode 100644 index f9c0783..0000000 --- a/src/SideMenuBig.vue +++ /dev/null @@ -1,155 +0,0 @@ - - - - diff --git a/src/SideMenuWithCategories.vue b/src/SideMenuWithCategories.vue deleted file mode 100644 index 07530a8..0000000 --- a/src/SideMenuWithCategories.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - - diff --git a/src/admin.js b/src/admin.js index 66fb71d..06cdbe5 100644 --- a/src/admin.js +++ b/src/admin.js @@ -8,275 +8,25 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * along with this program. If not, see . */ -import AdminCategoriesCustom from './AdminCategoriesCustom.vue' -import Vue from 'vue' +import './scss/admin.scss' -Vue.prototype.OC = window.OC -Vue.prototype.OCA = window.OCA +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import { waitContainer } from './lib/dom.js' -let elements = [] +import AdminSettings from './pages/AdminSettings' -const selector = '#side-menu-message' - -const userConfig = (name, value, callbacks) => { - const url = OC.generateUrl('/apps/side_menu/personalSetting/valueSet') - const formData = [] - - formData.push('name=' + encodeURIComponent(name)) - formData.push('value=' + encodeURIComponent(value)) - - fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: formData.join('&') - }) - .then(callbacks.success) - .catch(callbacks.error) -} - -const appConfig = (name, value, callbacks) => { - OCP.AppConfig.setValue('side_menu', name, value, callbacks) -} - -const saveSettings = (key) => { - const element = elements[key] - - if (!element) { - return - } - - let value - let name - - if (element.hasAttribute('data-checkbox')) { - name = element.getAttribute('data-name') - value = [] - - const inputs = document.querySelectorAll('input[name="' + name + '[]"]:checked') - - for (let input of inputs) { - value.push(input.value) - } - - value = JSON.stringify(value) - } else { - name = element.getAttribute('name') - value = element.value - } - - const size = elements.length - - if (name === 'cache') { - ++value - } - - const progress = document.querySelector('#side-menu-save-progress') - - progress.style.width = '40px'; - progress.style.marginLeft = '5px'; - - const callbacks = { - success: () => { - const percent = parseInt((key + 1) * 100 / size); - - progress.setAttribute('value', percent) - - if (key < size - 1) { - saveSettings(key + 1) - } else { - location.reload() - } - }, - error: () => { - OC.msg.finishedError(selector, t('side_menu', 'Error while saving "' + element + '"')) - } - } - - if (element.hasAttribute('data-personal')) { - userConfig(name, value, callbacks) - } else { - appConfig(name, value, callbacks) - } -} - -const elementToggler = (element) => { - let display = 'none' - - if (window.getComputedStyle(element).display === 'none') { - display = 'block' - } - - element.style.display = display -} - -const updateAppsCategoriesCustom = () => { - let values = {} - - for (let item of document.querySelectorAll('.apps-categories-custom')) { - let app = item.getAttribute('data-app') - let value = item.value - - if (value) { - values[app] = value - } - } - - document.querySelector('#apps-categories-custom').value = JSON.stringify(values) -} - -document.addEventListener('DOMContentLoaded', () => { - $('*[data-toggle="tooltip"]').tooltip(); - - if (document.querySelector('#side-menu-categories-custom')) { - const View = Vue.extend(AdminCategoriesCustom) - const adminCategoriesCustom = new View({}) - - adminCategoriesCustom.$mount('#side-menu-categories-custom') - } - - elements = document.querySelectorAll('.side-menu-setting') - - document.querySelector('#side-menu-save').addEventListener('click', (event) => { - event.preventDefault() - OC.msg.startSaving(selector) - - saveSettings(0) - }) - - const resets = document.querySelectorAll('.btn-reset') - - for (let btn of resets) { - btn.addEventListener('click', (event) => { - const target = event.target - const values = JSON.parse(target.getAttribute('data-reset')) - - target.classList.toggle('btn-reset--progress', true) - - for (let i in values) { - document.querySelector(`#${i}`).value = values[i] - } - - window.setTimeout(() => { - target.classList.toggle('btn-reset--progress', false) - }, 800) - }) - } - - const displays = document.querySelectorAll('.side-menu-display') - - for (let display of displays) { - display.addEventListener('click', (event) => { - const target = event.target - - for (let d of displays) { - d.classList.toggle('is-active', d === display) - } - - document.querySelector('#side-menu-always-displayed').value = target.getAttribute('data-alwaysdiplayed') - document.querySelector('#side-menu-big-menu').value = target.getAttribute('data-bigmenu') - document.querySelector('#side-menu-side-with-categories').value = target.getAttribute('data-sidewithcategories') - }) - } - - for (let item of document.querySelectorAll('.apps-categories-custom')) { - item.addEventListener('change', (event) => { - updateAppsCategoriesCustom() - }) - } - - for (let item of document.querySelectorAll('.side-menu-setting-live')) { - item.addEventListener('change', (event) => { - const target = event.target - const name = target.getAttribute('name') - - let value = target.value - let id = null - - if (name === 'background-color-opacity') { - id = '#side-menu-background-color, #side-menu-background-color-to' - } else if (name === 'dark-mode-background-color-opacity') { - id = '#side-menu-dark-mode-background-color, #side-menu-dark-mode-background-color-to' - } - - if (id) { - document.querySelector(id).dispatchEvent(new CustomEvent('change')) - - return - } - - if (name === 'opener') { - const url = OC.generateUrl(`/apps/side_menu/img/${value}.svg`).replace('/index.php', '') - - value = `url(${url})` - } - - if (name === 'icon-invert-filter' || name === 'icon-opacity') { - value/=100 - } - - if (['dark-mode-background-color', 'dark-mode-background-color-to'].indexOf(name) > -1) { - const opacity = parseInt(document.querySelector('#side-menu-dark-mode-background-color-opacity').value * 255 / 100) - - value = [value, opacity.toString(16)].join('') - } else if (['background-color', 'background-color-to'].indexOf(name) > -1) { - const opacity = parseInt(document.querySelector('#side-menu-background-color-opacity').value * 255 / 100) - - value = [value, opacity.toString(16)].join('') - } - - document.documentElement.style.setProperty('--side-menu-' + name, value) - }) - } - - for (let toggler of document.querySelectorAll('.side-menu-toggler')) { - toggler.addEventListener('click', (event) => { - const target = event.target - const element = document.querySelector(target.getAttribute('data-target')) - - elementToggler(element) - }) - } - - sortable('#categories-list .side-menu-setting-list', { - placeholderClass: 'side-menu-setting-list-drop' - }) - - try { - sortable('#categories-list .side-menu-setting-list')[0].addEventListener('sortstop', (e) => { - let value = [] - - for (let item of document.querySelectorAll('#categories-list .side-menu-setting-list-item')) { - value.push(item.getAttribute('data-id')) - } - - document.querySelector('input[name="categories-order"]').value = JSON.stringify(value) - }) - } catch (e) { - } - - sortable('#apps-order-list .side-menu-setting-list', { - placeholderClass: 'side-menu-setting-list-drop' - }) - - try { - sortable('#apps-order-list .side-menu-setting-list')[0].addEventListener('sortstop', (e) => { - let value = [] - - for (let item of document.querySelectorAll('#apps-order-list .side-menu-setting-list-item')) { - value.push(item.getAttribute('data-id')) - } - - document.querySelector('input[name="apps-order"]').value = JSON.stringify(value) - }) - } catch (e) { - } +waitContainer('#side-menu-admin-settings').then((selector) => { + const pinia = createPinia() + const app = createApp(AdminSettings) + app.use(pinia) + app.mixin({ methods: { t, n } }) + app.mount(selector) }) diff --git a/src/components/AppSearch.vue b/src/components/AppSearch.vue new file mode 100644 index 0000000..9366756 --- /dev/null +++ b/src/components/AppSearch.vue @@ -0,0 +1,29 @@ + + + + diff --git a/src/CloserButton.vue b/src/components/CloserButton.vue similarity index 75% rename from src/CloserButton.vue rename to src/components/CloserButton.vue index 80ed747..cfff324 100644 --- a/src/CloserButton.vue +++ b/src/components/CloserButton.vue @@ -15,18 +15,15 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/components/MenuLogo.vue b/src/components/MenuLogo.vue new file mode 100644 index 0000000..a619e96 --- /dev/null +++ b/src/components/MenuLogo.vue @@ -0,0 +1,52 @@ + + + + diff --git a/src/OpenerButton.vue b/src/components/OpenerButton.vue similarity index 76% rename from src/OpenerButton.vue rename to src/components/OpenerButton.vue index 538291c..536c61c 100644 --- a/src/OpenerButton.vue +++ b/src/components/OpenerButton.vue @@ -15,18 +15,15 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/components/PageLoader.vue b/src/components/PageLoader.vue new file mode 100644 index 0000000..fdd75a8 --- /dev/null +++ b/src/components/PageLoader.vue @@ -0,0 +1,49 @@ + + + + diff --git a/src/SettingsButton.vue b/src/components/SettingsButton.vue similarity index 70% rename from src/SettingsButton.vue rename to src/components/SettingsButton.vue index b8cb624..8c6eb41 100644 --- a/src/SettingsButton.vue +++ b/src/components/SettingsButton.vue @@ -15,35 +15,35 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/SideMenuApp.vue b/src/components/SideMenuApp.vue similarity index 55% rename from src/SideMenuApp.vue rename to src/components/SideMenuApp.vue index c910dce..a6a1190 100644 --- a/src/SideMenuApp.vue +++ b/src/components/SideMenuApp.vue @@ -15,38 +15,44 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/SideMenuBigApp.vue b/src/components/SideMenuBigApp.vue similarity index 55% rename from src/SideMenuBigApp.vue rename to src/components/SideMenuBigApp.vue index a0fcdde..a6a1190 100644 --- a/src/SideMenuBigApp.vue +++ b/src/components/SideMenuBigApp.vue @@ -15,38 +15,44 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/components/settings/AdminSaveButton.vue b/src/components/settings/AdminSaveButton.vue new file mode 100644 index 0000000..14cc274 --- /dev/null +++ b/src/components/settings/AdminSaveButton.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/src/components/settings/ExternalLink.vue b/src/components/settings/ExternalLink.vue new file mode 100644 index 0000000..80313fb --- /dev/null +++ b/src/components/settings/ExternalLink.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/settings/SectionTitle.vue b/src/components/settings/SectionTitle.vue new file mode 100644 index 0000000..b08b570 --- /dev/null +++ b/src/components/settings/SectionTitle.vue @@ -0,0 +1,35 @@ + + + + + + diff --git a/src/Logo.vue b/src/components/settings/SettingItem.vue similarity index 64% rename from src/Logo.vue rename to src/components/settings/SettingItem.vue index 1aec19f..ae7f8f9 100644 --- a/src/Logo.vue +++ b/src/components/settings/SettingItem.vue @@ -15,30 +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/components/settings/SettingLabel.vue b/src/components/settings/SettingLabel.vue new file mode 100644 index 0000000..a01b052 --- /dev/null +++ b/src/components/settings/SettingLabel.vue @@ -0,0 +1,71 @@ + + + + diff --git a/src/AppSearch.vue b/src/components/settings/SettingValue.vue similarity index 74% rename from src/AppSearch.vue rename to src/components/settings/SettingValue.vue index b2679a2..62db56c 100644 --- a/src/AppSearch.vue +++ b/src/components/settings/SettingValue.vue @@ -15,18 +15,20 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - diff --git a/src/components/settings/SettingsSection.vue b/src/components/settings/SettingsSection.vue new file mode 100644 index 0000000..f163c27 --- /dev/null +++ b/src/components/settings/SettingsSection.vue @@ -0,0 +1,34 @@ + + + + diff --git a/src/components/settings/UserSaveButton.vue b/src/components/settings/UserSaveButton.vue new file mode 100644 index 0000000..b2b8c6d --- /dev/null +++ b/src/components/settings/UserSaveButton.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/components/settings/form/FormAppCategory.vue b/src/components/settings/form/FormAppCategory.vue new file mode 100644 index 0000000..588ce73 --- /dev/null +++ b/src/components/settings/form/FormAppCategory.vue @@ -0,0 +1,292 @@ + + + + diff --git a/src/components/settings/form/FormAppPicker.vue b/src/components/settings/form/FormAppPicker.vue new file mode 100644 index 0000000..00df64b --- /dev/null +++ b/src/components/settings/form/FormAppPicker.vue @@ -0,0 +1,82 @@ + + + + diff --git a/src/components/settings/form/FormAppSort.vue b/src/components/settings/form/FormAppSort.vue new file mode 100644 index 0000000..7a2dec3 --- /dev/null +++ b/src/components/settings/form/FormAppSort.vue @@ -0,0 +1,116 @@ + + + + diff --git a/src/components/settings/form/FormCatSort.vue b/src/components/settings/form/FormCatSort.vue new file mode 100644 index 0000000..b335228 --- /dev/null +++ b/src/components/settings/form/FormCatSort.vue @@ -0,0 +1,119 @@ + + + + diff --git a/src/components/settings/form/FormColorPicker.vue b/src/components/settings/form/FormColorPicker.vue new file mode 100644 index 0000000..d13d578 --- /dev/null +++ b/src/components/settings/form/FormColorPicker.vue @@ -0,0 +1,33 @@ + + + + diff --git a/src/components/settings/form/FormDisplayPicker.vue b/src/components/settings/form/FormDisplayPicker.vue new file mode 100644 index 0000000..2e9c648 --- /dev/null +++ b/src/components/settings/form/FormDisplayPicker.vue @@ -0,0 +1,85 @@ + + diff --git a/src/components/settings/form/FormOpener.vue b/src/components/settings/form/FormOpener.vue new file mode 100644 index 0000000..f1129f9 --- /dev/null +++ b/src/components/settings/form/FormOpener.vue @@ -0,0 +1,37 @@ + + + + diff --git a/src/components/settings/form/FormRange.vue b/src/components/settings/form/FormRange.vue new file mode 100644 index 0000000..6ebada7 --- /dev/null +++ b/src/components/settings/form/FormRange.vue @@ -0,0 +1,65 @@ + + + + diff --git a/src/components/settings/form/FormSelect.vue b/src/components/settings/form/FormSelect.vue new file mode 100644 index 0000000..3b303ca --- /dev/null +++ b/src/components/settings/form/FormSelect.vue @@ -0,0 +1,78 @@ + + + + diff --git a/src/components/settings/form/FormSize.vue b/src/components/settings/form/FormSize.vue new file mode 100644 index 0000000..1e1b468 --- /dev/null +++ b/src/components/settings/form/FormSize.vue @@ -0,0 +1,35 @@ + + + + diff --git a/src/components/settings/form/FormYesNo.vue b/src/components/settings/form/FormYesNo.vue new file mode 100644 index 0000000..3d9f0aa --- /dev/null +++ b/src/components/settings/form/FormYesNo.vue @@ -0,0 +1,29 @@ + + + + diff --git a/src/components/settings/form/index.js b/src/components/settings/form/index.js new file mode 100644 index 0000000..ae9204b --- /dev/null +++ b/src/components/settings/form/index.js @@ -0,0 +1,13 @@ +import FormRange from './FormRange' +import FormColorPicker from './FormColorPicker' +import FormOpener from './FormOpener' +import FormSelect from './FormSelect' +import FormYesNo from './FormYesNo' +import FormSize from './FormSize' +import FormAppPicker from './FormAppPicker' +import FormAppSort from './FormAppSort' +import FormCatSort from './FormCatSort' +import FormDisplayPicker from './FormDisplayPicker' +import FormAppCategory from './FormAppCategory' + +export { FormRange, FormColorPicker, FormOpener, FormSelect, FormYesNo, FormSize, FormAppPicker, FormAppSort, FormCatSort, FormDisplayPicker, FormAppCategory } diff --git a/src/components/settings/index.js b/src/components/settings/index.js new file mode 100644 index 0000000..2036c95 --- /dev/null +++ b/src/components/settings/index.js @@ -0,0 +1,10 @@ +import SettingsSection from './SettingsSection' +import SettingItem from './SettingItem' +import SettingLabel from './SettingLabel' +import SettingValue from './SettingValue' +import SectionTitle from './SectionTitle' +import ExternalLink from './ExternalLink' +import AdminSaveButton from './AdminSaveButton' +import UserSaveButton from './UserSaveButton' + +export { SettingsSection, SettingItem, SettingLabel, SettingValue, SectionTitle, ExternalLink, AdminSaveButton, UserSaveButton } diff --git a/src/l10n/fixtures/cs.yaml b/src/l10n/fixtures/cs.yaml index e96e546..2ca05a3 100644 --- a/src/l10n/fixtures/cs.yaml +++ b/src/l10n/fixtures/cs.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Uživatelsky určená nabídka" -"Enable the custom menu": "Zapnout uživatelsky určenou nabídku" -"No": "Ne" -"Yes": "Ano" -"Menu": "Nabídka" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Pro otevření/skrytí postranní nabídky použijte zkratku Ctrl+O („O“ jako otevřít). Pro pohyb po použijte klávesu Tab.' -"Top menu": "Horní nabídka" -"Apps that not must be moved in the side menu": "Aplikace, které nepřesouvat do postranní nabídky" -"If there is no selection then the global configuration is applied.": "Pokud neexistuje žádný výběr, je uplatněno globální nastavení." -"Experimental": "Experimentální" -"Save": "Uložit" -"You like this app and you want to support me?": "Líbí se vám tato aplikace a chcete podpořit její vývoj?" -"Buy me a coffee ☕": "Kupte mi kafe ☕" -"Hidden": "Skryté" -"Small": "Malé" -"Normal": "Normální" -"Big": "Velké" -"Colors": "Barvy" -"Background color": "Barva pozadí" -"Background color of current app": "Barva pozadí stávající aplikace" -"Text color": "Barva textu" -"Loader": "Nástroj pro načítání" -"Icon": "Ikona" -"Same color": "Stejná barva" -"Opposite color": "Doplňková barva" -"Transparent": "Průhledné" -"Opaque": "Neprůhledné" -"Opener": "Tlačítko pro otevření" -"Default": "Výchozí" -"Default (dark)": "Výchozí (tmavé)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (tmavé)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (tmavé)" -"Before the logo": "Před logem" -"After the logo": "Za logem" -"Position": "Pozice" -"Show only the opener (hidden logo)": "Zobrazovat pouze otevírací tlačítko (logo skryto)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Nezobrazovat postranní nabídku a její otevírací tlačítko pokud nejsou dostupné žádné aplikace (např. na veřejných stránkách)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Otevřít nabídku při najetím ukazatelem na tlačítko nabídky (automaticky vypnuto pro dotykové obrazovky)" -"Display the big menu": "Zobrazit velkou nabídku" -"Display the logo": "Zobrazit logo" -"Icons and texts": "Ikony a texty" -"Loader enabled": "Načítání zapnuto" -"Tips": "Tipy" -"Always displayed": "Vždy zobrazeno" -"This is the automatic behavior when the menu is always displayed.": "Toto je automatické chování, kdy je nabídka vždy zobrazena." -"Not compatible with touch screens.": "Nekompatibilní s dotykovými obrazovkami." -"Big menu": "Velká nabídka" -"Live preview": "Živý náhled" -"Open apps in new tab": "Otevírat aplikace v novém panelu" -"Use the global setting": "Použít globální nastavení" -"Use my selection": "Použít můj výběr" -"Show and hide the list of applications": "Zobrazit/skrýt seznam aplikací" -"Use the avatar instead of the logo": "Použít namísto loga profilový obrázek uživatele" -"You do not have permission to change the settings.": "Nemáte oprávnění měnit nastavení." -"Force this configuration to users": "Vynutit uplatnění těchto nastavení uživatelům" -"Export the configuration": "Exportovat nastavení" -"Purge the cache": "Vyprázdnit mezipaměť" -"Show the link to settings": "Zobrazit odkaz na nastavení" -"The menu is enabled by default for users": "Nabídka je ve výchozím stavu pro uživatele zapnutá" -"Except when the configuration is forced.": "S výjimkou, kdy je nastavení vynuceno." -"Apps that should not be displayed in the menu": "Aplikace, které by neměly být v nabídce zobrazeny" -"This feature is only compatible with the big menu display.": "Tato funkce je kompatibilní pouze s velkou nabídkou." -"The logo is a link to the default app": "Logo je odkaz na výchozí aplikaci" -"Others": "Ostatní" -"Categories": "Kategorie" -"Customize sorting": "Přizpůsobit si řazení" -"Order by": "Řadit podle" -"Name": "Název" -"Customed": "Přizpůsobeno" -"Show and hide the list of categories": "Zobrazit/skrýt seznam kategorií" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Tyto parametry jsou použity v případě, že je zapnutý (Breeze) tmavý motiv vzhledu." -"Dark mode colors": "Barvy tmavého režimu" -"With categories": "S kategoriemi" -"Custom categories": "Vlastní kategorie" -"Customize application categories": "Přizpůsobte kategorie aplikací" -"Reset to default": "Vrátit zpět na výchozí hodnoty" -"Hidden icon": "Skrytá ikona" -"Small icon": "Malá ikona" -"Normal icon": "Normální ikona" -"Big icon": "Velká ikona" -"Hidden text": "Skrytý text" -"Small text": "Malý text" -"Normal text": "Normální text" -"Big text": "Velký text" -"Applications": "Aplikace" -"Applications kept in the top menu": "Aplikace ponechané v horní nabídce" -"Applications kept in the top menu but also shown in side menu": "Aplikace ponechané v horní nabídce ale také zobrazené v té boční" -"These applications must be selected in the previous option.": "Tyto aplikace je třeba vybrat v předchozí volbě." -"Hide labels on mouse over": "Skrýt popisky při najetím ukazatele myši" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Uživatelsky určená nabídka' +'Enable the custom menu': 'Zapnout uživatelsky určenou nabídku' +'No': 'Ne' +'Yes': 'Ano' +'Menu': 'Nabídka' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Pro otevření/skrytí postranní nabídky použijte zkratku Ctrl+o („O“ jako otevřít). Pro pohyb po použijte klávesu tab key.' +'Top menu': 'Horní nabídka' +'Apps that not must be moved in the side menu': 'Aplikace, které nepřesouvat do postranní nabídky' +'If there is no selection then the global configuration is applied.': 'Pokud neexistuje žádný výběr, je uplatněno globální nastavení.' +'Experimental': 'Experimentální' +'Save': 'Uložit' +'You like this app and you want to support me?': 'Líbí se vám tato aplikace a chcete podpořit její vývoj?' +'Buy me a coffee ☕': 'Kupte mi kafe ☕' +'Hidden': 'Skryté' +'Small': 'Malé' +'Normal': 'Normální' +'Big': 'Velké' +'Colors': 'Barvy' +'Background color': 'Barva pozadí' +'Background color of current app': 'Barva pozadí stávající aplikace' +'Text color': 'Barva textu' +'Loader': 'Nástroj pro načítání' +'Icon': 'Ikona' +'Same color': 'Stejná barva' +'Opposite color': 'Doplňková barva' +'Transparent': 'Průhledné' +'Opaque': 'Neprůhledné' +'Opener': 'Tlačítko pro otevření' +'Default': 'Výchozí' +'Default (dark)': 'Výchozí (tmavé)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (tmavé)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (tmavé)' +'Before the logo': 'Před logem' +'After the logo': 'Za logem' +'Position': 'Pozice' +'Show only the opener (hidden logo)': 'Zobrazovat pouze otevírací tlačítko (logo skryto)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Nezobrazovat postranní nabídku a její otevírací tlačítko pokud nejsou dostupné žádné aplikace (např. na veřejných stránkách).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Otevřít nabídku při najetím ukazatelem na tlačítko nabídky (automaticky vypnuto pro dotykové obrazovky)' +'Display the big menu': 'Zobrazit velkou nabídku' +'Display the logo': 'Zobrazit logo' +'Icons and texts': 'Ikony a texty' +'Loader enabled': 'Načítání zapnuto' +'Tips': 'Tipy' +'Always displayed': 'Vždy zobrazeno' +'This is the automatic behavior when the menu is always displayed.': 'Toto je automatické chování, kdy je nabídka vždy zobrazena.' +'Not compatible with touch screens.': 'Nekompatibilní s dotykovými obrazovkami.' +'Big menu': 'Velká nabídka' +'Live preview': 'Živý náhled' +'Open apps in new tab': 'Otevírat aplikace v novém panelu' +'Use the global setting': 'Použít globální nastavení' +'Use my selection': 'Použít můj výběr' +'Show and hide the list of applications': 'Zobrazit/skrýt seznam aplikací' +'Use the avatar instead of the logo': 'Použít namísto loga profilový obrázek uživatele' +'You do not have permission to change the settings.': 'Nemáte oprávnění měnit nastavení.' +'Force this configuration to users': 'Vynutit uplatnění těchto nastavení uživatelům' +'Export the configuration': 'Exportovat nastavení' +'Purge the cache': 'Vyprázdnit mezipaměť' +'Show the link to settings': 'Zobrazit odkaz na nastavení' +'The menu is enabled by default for users': 'Nabídka je ve výchozím stavu pro uživatele zapnutá' +'Except when the configuration is forced.': 'S výjimkou, kdy je nastavení vynuceno.' +'Apps that should not be displayed in the menu': 'Aplikace, které by neměly být v nabídce zobrazeny' +'This feature is only compatible with the big menu display.': 'Tato funkce je kompatibilní pouze s velkou nabídkou.' +'The logo is a link to the default app': 'Logo je odkaz na výchozí aplikaci' +'Others': 'Ostatní' +'Categories': 'Kategorie' +'Customize sorting': 'Přizpůsobit si řazení' +'Order by': 'Řadit podle' +'Name': 'Název' +'Customed': 'Přizpůsobeno' +'Show and hide the list of categories': 'Zobrazit/skrýt seznam kategorií' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Tyto parametry jsou použity v případě, že je zapnutý (Breeze) tmavý motiv vzhledu.' +'Dark mode colors': 'Barvy tmavého režimu' +'With categories': 'S kategoriemi' +'Custom categories': 'Vlastní kategorie' +'Customize application categories': 'Přizpůsobte kategorie aplikací' +'Reset to default': 'Vrátit zpět na výchozí hodnoty' +'Hidden icon': 'Skrytá ikona' +'Small icon': 'Malá ikona' +'Normal icon': 'Normální ikona' +'Big icon': 'Velká ikona' +'Hidden text': 'Skrytý text' +'Small text': 'Malý text' +'Normal text': 'Normální text' +'Big text': 'Velký text' +'Applications': 'Aplikace' +'Applications kept in the top menu': 'Aplikace ponechané v horní nabídce' +'Applications kept in the top menu but also shown in side menu': 'Aplikace ponechané v horní nabídce ale také zobrazené v té boční' +'These applications must be selected in the previous option.': 'Tyto aplikace je třeba vybrat v předchozí volbě.' +'Hide labels on mouse over': 'Skrýt popisky při najetím ukazatele myši' +'Except the hovered app': 'S výjimkou nadnášené aplikace' +'Search': 'Hledat' +'Toggle the menu': 'Vyp/zap nabídku' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/de.yaml b/src/l10n/fixtures/de.yaml index 62ceae2..6323421 100644 --- a/src/l10n/fixtures/de.yaml +++ b/src/l10n/fixtures/de.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Benutzerdefiniertes Menü" -"Enable the custom menu": "Benutzerdefiniertes Menü aktivieren" -"No": "Nein" -"Yes": "Ja" -"Menu": "Menü" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Verwende die Tastenkombination Strg+o, um das Seitenmenü ein- und auszublenden. Verwende tab zum Navigieren.' -"Top menu": "Obere Navigationsleiste" -"Apps that not must be moved in the side menu": "Apps, die nicht ins Seitenmenü verschoben werden sollen" -"If there is no selection then the global configuration is applied.": "Wenn keine Auswahl vorhanden ist, wird die globale Konfiguration angewendet." -"Experimental": "Experimentell" -"Save": "Speichern" -"You like this app and you want to support me?": "Du magst diese App und möchtest mich unterstützen?" -"Buy me a coffee ☕": "Gib mir einen Kaffee aus ☕" -"Hidden": "Ausblenden" -"Small": "Klein" -"Normal": "Normal" -"Big": "Groß" -"Colors": "Farben" -"Background color": "Hintergrundfarbe" -"Background color of current app": "Hintergrundfarbe der aktuellen App" -"Text color": "Textfarbe" -"Loader": "Fortschrittsbalken" -"Icon": "Symbol" -"Same color": "Selbe Farbe" -"Opposite color": "Gegenfarbe" -"Transparent": "Transparent" -"Opaque": "Nicht transparent" -"Opener": "Menü-Symbol" -"Default": "Standard" -"Default (dark)": "Standard (dunkel)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (dunkel)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (dunkel)" -"Before the logo": "Vor dem Logo" -"After the logo": "Nach dem Logo" -"Position": "Position" -"Show only the opener (hidden logo)": "Nur das Menü-Symbol anzeigen (Logo wird ausgeblendet)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Zeige das Seitenmenü und das Menü-Symbol nicht an, wenn keine App vorhanden ist (z.B. bei öffentlichen Seiten)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Öffne das Menü, wenn die Maus über das Menü-Symbol bewegt wird (auf Touchscreens automatisch deaktiviert)" -"Display the big menu": "Großes Menü anzeigen" -"Display the logo": "Logo anzeigen" -"Icons and texts": "Symbole und Texte" -"Loader enabled": "Fortschrittsbalken anzeigen" -"Tips": "Tipps" -"Always displayed": "Immer anzeigen" -"This is the automatic behavior when the menu is always displayed.": "Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird." -"Not compatible with touch screens.": "Nicht kompatibel mit Touchscreens." -"Big menu": "Großes Menü" -"Live preview": "Live-Vorschau" -"Open apps in new tab": "Öffne Apps in einem neuen Tab" -"Use the global setting": "Verwende die globale Einstellung" -"Use my selection": "Verwende meine Auswahl" -"Show and hide the list of applications": "Ein- und Ausblenden der Appliste" -"Use the avatar instead of the logo": "Avatar anstelle des Logos anzeigen" -"You do not have permission to change the settings.": "Du hast keine Berechtigung, die Einstellungen dieser App zu ändern." -"Force this configuration to users": "Konfiguration für alle Benutzer erzwingen" -"Export the configuration": "Konfiguration exportieren" -"Purge the cache": "Cache leeren" -"Show the link to settings": "Link zu den Einstellungen anzeigen" -"The menu is enabled by default for users": "Das Menü ist standardmäßig für alle Benutzer aktiviert" -"Except when the configuration is forced.": "Gilt nicht, wenn die Konfiguration erzwungen wird." -"Apps that should not be displayed in the menu": "Apps, die nicht im Menü angezeigt werden sollen" -"This feature is only compatible with the big menu display.": "Kompatibel mit dem großen Menü." -"The logo is a link to the default app": "Das Logo ist ein Link zur Standard-App" -"Others": "Andere" -"Categories": "Kategorien" -"Customize sorting": "Sortierung anpassen" -"Order by": "Sortieren nach" -"Name": "Name" -"Customed": "Benutzerdefiniert" -"Show and hide the list of categories": "Liste der Kategorien ein- und ausblenden" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Diese Optionen werden auf Dark Theme oder Breeze Dark Theme angewendet." -"Dark mode colors": "Farben für den dunklen Modus" -"With categories": "Mit Kategorien" -"Custom categories": "Benutzerdefinierte Kategorien" -"Customize application categories": "App-Kategorien anpassen" -"Reset to default": "Auf Standard zurücksetzen" -"Hidden icon": "Verstecktes Symbol" -"Small icon": "Kleines Symbol" -"Normal icon": "Normales Symbol" -"Big icon": "Großes Icon" -"Hidden text": "Versteckter Text" -"Small text": "Kleiner Text" -"Normal text": "Normaler Text" -"Big text": "Großer Text" -"Applications": "Apps" -"Applications kept in the top menu": "Apps in der oberen Navigationsleiste" -"Applications kept in the top menu but also shown in side menu": "Apps in der oberen Navigationsleiste, die auch im Seitenmenü angezeigt werden sollen" -"These applications must be selected in the previous option.": "Diese Apps müssen auch in der vorherigen Einstellung ausgewählt werden." -"Hide labels on mouse over": "Labels ausblenden, wenn sich die Maus darüber befindet (Hover)" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Benutzerdefiniertes Menü' +'Enable the custom menu': 'Benutzerdefiniertes Menü aktivieren' +'No': 'Nein' +'Yes': 'Ja' +'Menu': 'Menü' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Verwende die Tastenkombination Strg+o, um das Seitenmenü ein- und auszublenden. Verwende tab key zum Navigieren.' +'Top menu': 'Obere Navigationsleiste' +'Apps that not must be moved in the side menu': 'Apps, die nicht ins Seitenmenü verschoben werden sollen' +'If there is no selection then the global configuration is applied.': 'Wenn keine Auswahl vorhanden ist, wird die globale Konfiguration angewendet.' +'Experimental': 'Experimentell' +'Save': 'Speichern' +'You like this app and you want to support me?': 'Du magst diese App und möchtest mich unterstützen?' +'Buy me a coffee ☕': 'Gib mir einen Kaffee aus ☕' +'Hidden': 'Ausblenden' +'Small': 'Klein' +'Normal': 'Normal' +'Big': 'Groß' +'Colors': 'Farben' +'Background color': 'Hintergrundfarbe' +'Background color of current app': 'Hintergrundfarbe der aktuellen App' +'Text color': 'Textfarbe' +'Loader': 'Fortschrittsbalken' +'Icon': 'Symbol' +'Same color': 'Selbe Farbe' +'Opposite color': 'Gegenfarbe' +'Transparent': 'Transparent' +'Opaque': 'Nicht transparent' +'Opener': 'Menü-Symbol' +'Default': 'Standard' +'Default (dark)': 'Standard (dunkel)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (dunkel)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (dunkel)' +'Before the logo': 'Vor dem Logo' +'After the logo': 'Nach dem Logo' +'Position': 'Position' +'Show only the opener (hidden logo)': 'Nur das Menü-Symbol anzeigen (Logo wird ausgeblendet)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Zeige das Seitenmenü und das Menü-Symbol nicht an, wenn keine App vorhanden ist (z.B. bei öffentlichen Seiten).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Öffne das Menü, wenn die Maus über das Menü-Symbol bewegt wird (auf Touchscreens automatisch deaktiviert)' +'Display the big menu': 'Großes Menü anzeigen' +'Display the logo': 'Logo anzeigen' +'Icons and texts': 'Symbole und Texte' +'Loader enabled': 'Fortschrittsbalken anzeigen' +'Tips': 'Tipps' +'Always displayed': 'Immer anzeigen' +'This is the automatic behavior when the menu is always displayed.': 'Dies ist das automatische Verhalten, wenn das Menü immer angezeigt wird.' +'Not compatible with touch screens.': 'Nicht kompatibel mit Touchscreens.' +'Big menu': 'Großes Menü' +'Live preview': 'Live-Vorschau' +'Open apps in new tab': 'Öffne Apps in einem neuen Tab' +'Use the global setting': 'Verwende die globale Einstellung' +'Use my selection': 'Verwende meine Auswahl' +'Show and hide the list of applications': 'Ein- und Ausblenden der Appliste' +'Use the avatar instead of the logo': 'Avatar anstelle des Logos anzeigen' +'You do not have permission to change the settings.': 'Du hast keine Berechtigung, die Einstellungen dieser App zu ändern.' +'Force this configuration to users': 'Konfiguration für alle Benutzer erzwingen' +'Export the configuration': 'Konfiguration exportieren' +'Purge the cache': 'Cache leeren' +'Show the link to settings': 'Link zu den Einstellungen anzeigen' +'The menu is enabled by default for users': 'Das Menü ist standardmäßig für alle Benutzer aktiviert' +'Except when the configuration is forced.': 'Gilt nicht, wenn die Konfiguration erzwungen wird.' +'Apps that should not be displayed in the menu': 'Apps, die nicht im Menü angezeigt werden sollen' +'This feature is only compatible with the big menu display.': 'Kompatibel mit dem großen Menü.' +'The logo is a link to the default app': 'Das Logo ist ein Link zur Standard-App' +'Others': 'Andere' +'Categories': 'Kategorien' +'Customize sorting': 'Sortierung anpassen' +'Order by': 'Sortieren nach' +'Name': 'Name' +'Customed': 'Benutzerdefiniert' +'Show and hide the list of categories': 'Liste der Kategorien ein- und ausblenden' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Diese Optionen werden auf Dark Theme oder Breeze Dark Theme angewendet.' +'Dark mode colors': 'Farben für den dunklen Modus' +'With categories': 'Mit Kategorien' +'Custom categories': 'Benutzerdefinierte Kategorien' +'Customize application categories': 'App-Kategorien anpassen' +'Reset to default': 'Auf Standard zurücksetzen' +'Hidden icon': 'Verstecktes Symbol' +'Small icon': 'Kleines Symbol' +'Normal icon': 'Normales Symbol' +'Big icon': 'Großes Icon' +'Hidden text': 'Versteckter Text' +'Small text': 'Kleiner Text' +'Normal text': 'Normaler Text' +'Big text': 'Großer Text' +'Applications': 'Apps' +'Applications kept in the top menu': 'Apps in der oberen Navigationsleiste' +'Applications kept in the top menu but also shown in side menu': 'Apps in der oberen Navigationsleiste, die auch im Seitenmenü angezeigt werden sollen' +'These applications must be selected in the previous option.': 'Diese Apps müssen auch in der vorherigen Einstellung ausgewählt werden.' +'Hide labels on mouse over': 'Labels ausblenden, wenn sich die Maus darüber befindet (Hover)' +'Except the hovered app': 'Außer die markierte App' +'Search': 'Suche' +'Toggle the menu': 'Menü ein- und ausblenden' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/es.yaml b/src/l10n/fixtures/es.yaml index 3d0aae1..1217c3b 100644 --- a/src/l10n/fixtures/es.yaml +++ b/src/l10n/fixtures/es.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Menú personalizado" -"Enable the custom menu": "Habilitar el menú personalizado" -"No": "No" -"Yes": "Sí" -"Menu": "Menú" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Usa la combinación de teclas Ctrl+o para activar y desactivar el menú lateral. Use tab para navegar.' -"Top menu": "Menu principal" -"Apps that not must be moved in the side menu": "Aplicaciones que no se deben mover al menú lateral" -"If there is no selection then the global configuration is applied.": "Si no hay selección, se aplica la configuración global." -"Experimental": "En pruebas" -"Save": "Guardar" -"You like this app and you want to support me?": "¿Te gusta esta aplicación y quieres apoyarme?" -"Buy me a coffee ☕": "Cómprame un café ☕" -"Hidden": "Oculto" -"Small": "Pequeño" -"Normal": "Normal" -"Big": "Grande" -"Hidden icon": "Ocultar Icono" -"Small icon": "Icono pequeño" -"Normal icon": "Icono normal" -"Big icon": "Icono grande" -"Hidden text": "Texto oculto" -"Small text": "Texto pequeño" -"Normal text": "Texto normal" -"Big text": "Texto grande" -"Colors": "Colores" -"Background color": "Color de fondo" -"Background color of current app": "Color de fondo de la aplicación actual" -"Text color": "Color del texto" -"Loader": "Cargador" -"Icon": "Icono" -"Same color": "El mismo color" -"Opposite color": "Color opuesto" -"Transparent": "Transparente" -"Opaque": "Opaco" -"Opener": "Abrir" -"Default": "Por defecto" -"Default (dark)": "Por defecto (oscuro)" -"Hamburger": "Hamburguesa" -"Hamburger (dark)": "Hamburger (negro)" -"Hamburger 2": "Hamburguesa 2" -"Hamburger 2 (dark)": "Hamburger 2 (negro)" -"Before the logo": "Antes del logotipo" -"After the logo": "Después del logotipo" -"Position": "Posición" -"Show only the opener (hidden logo)": "Mostrar solo abrir (ocultar logotipo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "No mostrar el menú lateral y el abridor si no hay aplicación (por ejemplo: páginas públicas)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Abra el menú cuando el ratón esté sobre el icono (se desactiva automáticamente en las pantallas táctiles)" -"Display the big menu": "Mostrar el menú grande" -"Display the logo": "Mostrar el logotipo" -"Icons and texts": "Iconos y textos" -"Loader enabled": "Cargador activado" -"Tips": "Consejos" -"Always displayed": "Siempre se muestra" -"This is the automatic behavior when the menu is always displayed.": "Este es el comportamiento automático cuando aún se muestra el menú." -"Not compatible with touch screens.": "No es compatible con las pantallas táctiles." -"Big menu": "Menú grande" -"Live preview": "Previsualización en directo" -"Open apps in new tab": "Abrir las aplicaciones en una nueva pestaña" -"Use the global setting": "Utilizar la configuración global" -"Use my selection": "Utilizar mi selección" -"Show and hide the list of applications": "Mostrar y ocultar la lista de aplicaciones" -"Use the avatar instead of the logo": "Utilizar un avatar en lugar de un logotipo" -"You do not have permission to change the settings.": "No tienes permiso para cambiar la configuración." -"Force this configuration to users": "Forzar esta configuración a todos los usuarios" -"Export the configuration": "Exportar la configuración" -"Purge the cache": "Vaciar la caché" -"Show the link to settings": "Mostrar un enlace a la configuración" -"The menu is enabled by default for users": "El menú está activado por defecto para los usuarios" -"Except when the configuration is forced.": "Excepto cuando la configuración es forzada." -"Apps that should not be displayed in the menu": "Aplicaciones que no deben aparecer en el menú" -"This feature is only compatible with the big menu display.": "Esta función sólo es compatible con la pantalla del menú grande." -"The logo is a link to the default app": "El logotipo es un enlace a la aplicación por defecto" -"Others": "Otros" -"Categories": "Categorías" -"Customize sorting": "Personalizar la clasificación" -"Order by": "Ordenar por" -"Name": "Nombre" -"Customed": "Personalizado" -"Show and hide the list of categories": "Mostrar y ocultar la lista de categorías" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Estos parámetros se utilizan cuando el tema oscuro o el tema oscuro de Breeze están activados." -"Dark mode colors": "Colores del modo oscuro" -"With categories": "Con categorías" -"Custom categories": "Categorías personalizadas" -"Customize application categories": "Personalizar las categorías de las aplicaciones" -"Reset to default": "Restablecer los valores por defecto" -"Applications": "Aplicaciones" -"Applications kept in the top menu": "Aplicaciones guardadas en el menú superior" -"Applications kept in the top menu but also shown in side menu": "Las aplicaciones se mantienen en el menú superior pero también se muestran en el menú lateral" -"These applications must be selected in the previous option.": "Estas aplicaciones deben ser seleccionadas en las opciones anteriores." -"Hide labels on mouse over": "Ocultar las etiquetas al pasar el ratón" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Menú personalizado' +'Enable the custom menu': 'Activar el menú personalizado' +'No': 'No' +'Yes': 'Sí' +'Menu': 'Menú' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Usa la combinación de teclas Ctrl+o para activar y desactivar el menú lateral. Use tab key para navegar.' +'Top menu': 'Menu principal' +'Apps that not must be moved in the side menu': 'Aplicaciones que no se deben mover al menú lateral' +'If there is no selection then the global configuration is applied.': 'Si no hay selección, se aplica la configuración global.' +'Experimental': 'En pruebas' +'Save': 'Guardar' +'You like this app and you want to support me?': '¿Te gusta esta aplicación y quieres apoyarme?' +'Buy me a coffee ☕': 'Cómprame un café ☕' +'Hidden': 'Oculto' +'Small': 'Pequeño' +'Normal': 'Normal' +'Big': 'Grande' +'Hidden icon': 'Ocultar Icono' +'Small icon': 'Icono pequeño' +'Normal icon': 'Icono normal' +'Big icon': 'Icono grande' +'Hidden text': 'Texto oculto' +'Small text': 'Texto pequeño' +'Normal text': 'Texto normal' +'Big text': 'Texto grande' +'Colors': 'Colores' +'Background color': 'Color de fondo' +'Background color of current app': 'Color de fondo de la aplicación actual' +'Text color': 'Color del texto' +'Loader': 'Cargador' +'Icon': 'Icono' +'Same color': 'El mismo color' +'Opposite color': 'Color opuesto' +'Transparent': 'Transparente' +'Opaque': 'Opaco' +'Opener': 'Abrir' +'Default': 'Por defecto' +'Default (dark)': 'Por defecto (oscuro)' +'Hamburger': 'Hamburguesa' +'Hamburger (dark)': 'Hamburger (negro)' +'Hamburger 2': 'Hamburguesa 2' +'Hamburger 2 (dark)': 'Hamburger 2 (negro)' +'Before the logo': 'Antes del logotipo' +'After the logo': 'Después del logotipo' +'Position': 'Posición' +'Show only the opener (hidden logo)': 'Mostrar solo abrir (ocultar logotipo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'No mostrar el menú lateral y el abridor si no hay aplicación (por ejemplo: páginas públicas).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Abra el menú cuando el ratón esté sobre el icono (se desactiva automáticamente en las pantallas táctiles)' +'Display the big menu': 'Mostrar el menú grande' +'Display the logo': 'Mostrar el logotipo' +'Icons and texts': 'Iconos y textos' +'Loader enabled': 'Cargador activado' +'Tips': 'Consejos' +'Always displayed': 'Siempre se muestra' +'This is the automatic behavior when the menu is always displayed.': 'Este es el comportamiento automático cuando aún se muestra el menú.' +'Not compatible with touch screens.': 'No es compatible con las pantallas táctiles.' +'Big menu': 'Menú grande' +'Live preview': 'Previsualización en directo' +'Open apps in new tab': 'Abrir las aplicaciones en una nueva pestaña' +'Use the global setting': 'Utilizar la configuración global' +'Use my selection': 'Utilizar mi selección' +'Show and hide the list of applications': 'Mostrar y ocultar la lista de aplicaciones' +'Use the avatar instead of the logo': 'Utilizar un avatar en lugar de un logotipo' +'You do not have permission to change the settings.': 'No tienes permiso para cambiar la configuración.' +'Force this configuration to users': 'Forzar esta configuración a todos los usuarios' +'Export the configuration': 'Exportar la configuración' +'Purge the cache': 'Vaciar la caché' +'Show the link to settings': 'Mostrar un enlace a la configuración' +'The menu is enabled by default for users': 'El menú está activado por defecto para los usuarios' +'Except when the configuration is forced.': 'Excepto cuando la configuración es forzada.' +'Apps that should not be displayed in the menu': 'Aplicaciones que no deben aparecer en el menú' +'This feature is only compatible with the big menu display.': 'Esta función sólo es compatible con la pantalla del menú grande.' +'The logo is a link to the default app': 'El logotipo es un enlace a la aplicación por defecto' +'Others': 'Otros' +'Categories': 'Categorías' +'Customize sorting': 'Personalizar la clasificación' +'Order by': 'Ordenar por' +'Name': 'Nombre' +'Customed': 'Personalizado' +'Show and hide the list of categories': 'Mostrar y ocultar la lista de categorías' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Estos parámetros se utilizan cuando el tema oscuro o el tema oscuro de Breeze están activados.' +'Dark mode colors': 'Colores del modo oscuro' +'With categories': 'Con categorías' +'Custom categories': 'Categorías personalizadas' +'Customize application categories': 'Personalizar las categorías de las aplicaciones' +'Reset to default': 'Restablecer los valores por defecto' +'Applications': 'Aplicaciones' +'Applications kept in the top menu': 'Aplicaciones guardadas en el menú superior' +'Applications kept in the top menu but also shown in side menu': 'Las aplicaciones se mantienen en el menú superior pero también se muestran en el menú lateral' +'These applications must be selected in the previous option.': 'Estas aplicaciones deben ser seleccionadas en las opciones anteriores.' +'Hide labels on mouse over': 'Ocultar las etiquetas al pasar el ratón' +'Except the hovered app': 'Excepto la aplicación sobre la que se pasa el cursor' +'Search': 'Buscar' +'Toggle the menu': 'Alternar el menú' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/fr.yaml b/src/l10n/fixtures/fr.yaml index c9af165..29b3c3f 100644 --- a/src/l10n/fixtures/fr.yaml +++ b/src/l10n/fixtures/fr.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Menu personnalisé" -"Enable the custom menu": "Activer le menu personnalisé" -"No": "Non" -"Yes": "Oui" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Utiliser le raccourcis clavier Ctrl+o pour ouvrir et fermer le menu latéral. Utiliser tab pour naviguer.' -"Top menu": "Menu supérieur" -"Apps that not must be moved in the side menu": "Les applications qui ne doivent pas être affichées dans le menu latéral" -"If there is no selection then the global configuration is applied.": "Si il n'y a aucune sélection alors la configuration globale sera appliquée." -"Experimental": "Expérimental" -"Save": "Sauvegarder" -"You like this app and you want to support me?": "Vous aimer cette application et vous souhaitez m'aider ?" -"Buy me a coffee ☕": "Offrez moi un café ☕" -"Hidden": "Caché" -"Small": "Petit" -"Normal": "Normal" -"Big": "Gros" -"Hidden icon": "Icône masqué" -"Small icon": "Petit icône" -"Normal icon": "Icône normal" -"Big icon": "Gros icône" -"Hidden text": "Text masqué" -"Small text": "Texte petit" -"Normal text": "Texte normal" -"Big text": "Gros texte" -"Colors": "Couleurs" -"Background color": "Couleur de fond" -"Background color of current app": "Couleur de fond de l'application en cours" -"Text color": "Couleur du texte" -"Loader": "Indicateur de chargement" -"Icon": "Icône" -"Same color": "Même couleur" -"Opposite color": "Couleur opposée" -"Transparent": "Transparent" -"Opaque": "Opaque" -"Opener": "Bouton d'ouverture" -"Default": "Par défaut" -"Default (dark)": "Par défaut (sombre)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (sombre)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (sombre)" -"Before the logo": "Avant le logo" -"After the logo": "Après le logo" -"Position": "Position" -"Show only the opener (hidden logo)": "Afficher uniquement le bouton d'ouverture (masquer le logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Ne pas afficher le menu latéral et le bouton d'ouverture s'il n'y a aucune application (exemple : page publiques)." -"Panel": "Panneau" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Ouvrir le menu au passage de la souris (automatiquement désactivé sur les écrans tactiles)" -"Display the big menu": "Afficher le menu large" -"Display the logo": "Afficher le logo" -"Icons and texts": "Icônes et textes" -"Loader enabled": "Activation de l'indicateur de chargement" -"Tips": "Astuces" -"Always displayed": "Toujours affiché" -"This is the automatic behavior when the menu is always displayed.": "C'est le comportement automatique lorsque le menu est toujours affiché." -"Not compatible with touch screens.": "Incompatible avec les écrans tactiles." -"Big menu": "Menu large" -"Live preview": "Aperçu en direct" -"Open apps in new tab": "Ouvrir les applications dans un nouvel onglet" -"Use the global setting": "Utiliser la configuration globale" -"Use my selection": "Utiliser ma sélection" -"Show and hide the list of applications": "Afficher et masquer la liste des applications" -"Use the avatar instead of the logo": "Utiliser l'avatar à la place du logo" -"You do not have permission to change the settings.": "Vous n'avez pas la permission de changer les paramètres." -"Force this configuration to users": "Forcer cette configuration aux utilisateurs" -"Export the configuration": "Exporter la configuration" -"Purge the cache": "Purger le cache" -"Show the link to settings": "Afficher le lien vers les paramètres" -"The menu is enabled by default for users": "Le menu est activé par défaut pour les utilisateurs" -"Except when the configuration is forced.": "Sauf lorsque la configuration est forcée." -"Apps that should not be displayed in the menu": "Applications qui ne doivent pas être affichées dans le menu" -"This feature is only compatible with the big menu display.": "Compatible avec l'affichage Menu large." -"The logo is a link to the default app": "Le logo est un lien vers l'application par défaut" -"Others": "Autres" -"Categories": "Catégories" -"Customize sorting": "Personnaliser le tri" -"Order by": "Trier par" -"Name": "Nom" -"Customed": "Personnalisé" -"Show and hide the list of categories": "Afficher et masquer la liste des catégories" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Ces paramètres sont utilisés lorsque le thème sombre ou le thème Breeze Dark sont activés." -"Dark mode colors": "Couleurs du mode sombre" -"With categories": "Avec les catégories" -"Custom categories": "Catégories personnalisées" -"Customize application categories": "Personnaliser les catégories des applications" -"Reset to default": "Restaurer les valeurs par défaut" -"Applications": "Applications" -"Applications kept in the top menu": "Applications conservées dans le menu supérieur" -"Applications kept in the top menu but also shown in side menu": "Applications conservées dans le menu supérieur mais également affichées dans le menu latéral" -"These applications must be selected in the previous option.": "Ces applications doivent également être sélectionnées dans l'option précédente." -"Hide labels on mouse over": "Masquer le libellé des applications au passage de la souris" -"Except the hovered app": "À l'exception de l'application survolée" -"Search": "Rechercher" -"Toggle the menu": "Basculer le menu" +'Custom menu': 'Menu personnalisé' +'Enable the custom menu': 'Activer le menu personnalisé' +'No': 'Non' +'Yes': 'Oui' +'Menu': 'Menu' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Utiliser le raccourcis clavier Ctrl+o pour ouvrir et fermer le menu latéral. Utiliser tab key pour naviguer.' +'Top menu': 'Menu supérieur' +'Apps that not must be moved in the side menu': 'Les applications qui ne doivent pas être affichées dans le menu latéral' +'If there is no selection then the global configuration is applied.': "Si il n'y a aucune sélection alors la configuration globale sera appliquée." +'Experimental': 'Expérimental' +'Save': 'Sauvegarder' +'You like this app and you want to support me?': "Vous aimer cette application et vous souhaitez m'aider ?" +'Buy me a coffee ☕': 'Offrez moi un café ☕' +'Hidden': 'Caché' +'Small': 'Petit' +'Normal': 'Normal' +'Big': 'Gros' +'Hidden icon': 'Icône masqué' +'Small icon': 'Petit icône' +'Normal icon': 'Icône normal' +'Big icon': 'Gros icône' +'Hidden text': 'Text masqué' +'Small text': 'Texte petit' +'Normal text': 'Texte normal' +'Big text': 'Gros texte' +'Colors': 'Couleurs' +'Background color': 'Couleur de fond' +'Background color of current app': "Couleur de fond de l'application en cours" +'Text color': 'Couleur du texte' +'Loader': 'Indicateur de chargement' +'Icon': 'Icône' +'Same color': 'Même couleur' +'Opposite color': 'Couleur opposée' +'Transparent': 'Transparent' +'Opaque': 'Opaque' +'Opener': "Bouton d'ouverture" +'Default': 'Par défaut' +'Default (dark)': 'Par défaut (sombre)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (sombre)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (sombre)' +'Before the logo': 'Avant le logo' +'After the logo': 'Après le logo' +'Position': 'Position' +'Show only the opener (hidden logo)': "Afficher uniquement le bouton d'ouverture (masquer le logo)" +'Do not display the side menu and the opener if there is no application (eg: public pages).': "Ne pas afficher le menu latéral et le bouton d'ouverture s'il n'y a aucune application (exemple : page publiques)." +'Panel': 'Panneau' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Ouvrir le menu au passage de la souris (automatiquement désactivé sur les écrans tactiles)' +'Display the big menu': 'Afficher le menu large' +'Display the logo': 'Afficher le logo' +'Icons and texts': 'Icônes et textes' +'Loader enabled': "Activation de l'indicateur de chargement" +'Tips': 'Astuces' +'Always displayed': 'Toujours affiché' +'This is the automatic behavior when the menu is always displayed.': "C'est le comportement automatique lorsque le menu est toujours affiché." +'Not compatible with touch screens.': 'Incompatible avec les écrans tactiles.' +'Big menu': 'Menu large' +'Live preview': 'Aperçu en direct' +'Open apps in new tab': 'Ouvrir les applications dans un nouvel onglet' +'Use the global setting': 'Utiliser la configuration globale' +'Use my selection': 'Utiliser ma sélection' +'Show and hide the list of applications': 'Afficher et masquer la liste des applications' +'Use the avatar instead of the logo': "Utiliser l'avatar à la place du logo" +'You do not have permission to change the settings.': "Vous n'avez pas la permission de changer les paramètres." +'Force this configuration to users': 'Forcer cette configuration aux utilisateurs' +'Export the configuration': 'Exporter la configuration' +'Purge the cache': 'Purger le cache' +'Show the link to settings': 'Afficher le lien vers les paramètres' +'The menu is enabled by default for users': 'Le menu est activé par défaut pour les utilisateurs' +'Except when the configuration is forced.': 'Sauf lorsque la configuration est forcée.' +'Apps that should not be displayed in the menu': 'Applications qui ne doivent pas être affichées dans le menu' +'This feature is only compatible with the big menu display.': "Compatible avec l'affichage Menu large." +'The logo is a link to the default app': "Le logo est un lien vers l'application par défaut" +'Others': 'Autres' +'Categories': 'Catégories' +'Customize sorting': 'Personnaliser le tri' +'Order by': 'Trier par' +'Name': 'Nom' +'Customed': 'Personnalisé' +'Show and hide the list of categories': 'Afficher et masquer la liste des catégories' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Ces paramètres sont utilisés lorsque le thème sombre ou le thème Breeze Dark sont activés.' +'Dark mode colors': 'Couleurs du mode sombre' +'With categories': 'Avec les catégories' +'Custom categories': 'Catégories personnalisées' +'Customize application categories': 'Personnaliser les catégories des applications' +'Reset to default': 'Restaurer les valeurs par défaut' +'Applications': 'Applications' +'Applications kept in the top menu': 'Applications conservées dans le menu supérieur' +'Applications kept in the top menu but also shown in side menu': 'Applications conservées dans le menu supérieur mais également affichées dans le menu latéral' +'These applications must be selected in the previous option.': "Ces applications doivent également être sélectionnées dans l'option précédente." +'Hide labels on mouse over': 'Masquer le libellé des applications au passage de la souris' +'Except the hovered app': "À l'exception de l'application survolée" +'Search': 'Rechercher' +'Toggle the menu': 'Basculer le menu' +'Open the documentation': 'Afficher la documentation' +'Ask the developer': 'Demander au(x) développeurs⋅euses' +'New request': 'Nouvelle requête' +'Report a bug': 'Rapporter un bug' +'Show the configuration': 'Afficher la configuration' +'Configuration:': 'Configuration :' +'Done!': 'Fait !' +'Copy': 'Copié' +'Need help': "Besoin d'aide" +'I would like a new feature': 'Je souhaiterais une fonctionnalité' +'Something went wrong': "Quelque chose s'est mal passé" +'Select apps': 'Selection des apps' +'Sort': 'Ordonner' +'Customize': 'Personnaliser' +'Custom': 'Personnalisé' +'Close': 'Fermer' diff --git a/src/l10n/fixtures/gl.yaml b/src/l10n/fixtures/gl.yaml index a25bf54..3fb8be0 100644 --- a/src/l10n/fixtures/gl.yaml +++ b/src/l10n/fixtures/gl.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Custom menu" -"Enable the custom menu": "Enable the custom menu" -"No": "No" -"Yes": "Yes" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -"Top menu": "Top menu" -"Apps that not must be moved in the side menu": "Apps that not must be moved in the side menu" -"If there is no selection then the global configuration is applied.": "If there is no selection then the global configuration is applied." -"Experimental": "Experimental" -"Save": "Save" -"You like this app and you want to support me?": "You like this app and you want to support me?" -"Buy me a coffee ☕": "Buy me a coffee ☕" -"Hidden": "Hidden" -"Small": "Small" -"Normal": "Normal" -"Big": "Big" -"Hidden icon": "Hidden icon" -"Small icon": "Small icon" -"Normal icon": "Normal icon" -"Big icon": "Big icon" -"Hidden text": "Hidden text" -"Small text": "Small text" -"Normal text": "Normal text" -"Big text": "Big text" -"Colors": "Colors" -"Background color": "Background color" -"Background color of current app": "Background color of current app" -"Text color": "Text color" -"Loader": "Loader" -"Icon": "Icon" -"Same color": "Same color" -"Opposite color": "Opposite color" -"Transparent": "Transparent" -"Opaque": "Opaque" -"Opener": "Opener" -"Default": "Default" -"Default (dark)": "Default (dark)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (dark)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (dark)" -"Before the logo": "Before the logo" -"After the logo": "After the logo" -"Position": "Position" -"Show only the opener (hidden logo)": "Show only the opener (hidden logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Do not display the side menu and the opener if there is no application (eg: public pages)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Open the menu when the mouse is hover the opener (automatically disabled on touch screens)" -"Display the big menu": "Display the big menu" -"Display the logo": "Display the logo" -"Icons and texts": "Icons and texts" -"Loader enabled": "Loader enabled" -"Tips": "Tips" -"Always displayed": "Always displayed" -"This is the automatic behavior when the menu is always displayed.": "This is the automatic behavior when the menu is always displayed." -"Not compatible with touch screens.": "Not compatible with touch screens." -"Big menu": "Big menu" -"Live preview": "Live preview" -"Open apps in new tab": "Open apps in new tab" -"Use the global setting": "Use the global setting" -"Use my selection": "Use my selection" -"Show and hide the list of applications": "Show and hide the list of applications" -"Use the avatar instead of the logo": "Use the avatar instead of the logo" -"You do not have permission to change the settings.": "You do not have permission to change the settings." -"Force this configuration to users": "Force this configuration to users" -"Export the configuration": "Export the configuration" -"Purge the cache": "Purge the cache" -"Show the link to settings": "Show the link to settings" -"The menu is enabled by default for users": "The menu is enabled by default for users" -"Except when the configuration is forced.": "Except when the configuration is forced." -"Apps that should not be displayed in the menu": "Apps that should not be displayed in the menu" -"This feature is only compatible with the big menu display.": "This feature is only compatible with the big menu display." -"The logo is a link to the default app": "The logo is a link to the default app" -"Others": "Others" -"Categories": "Categories" -"Customize sorting": "Customize sorting" -"Order by": "Order by" -"Name": "Name" -"Customed": "Customed" -"Show and hide the list of categories": "Show and hide the list of categories" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "This parameters are used when Dark theme or Breeze Dark Theme are enabled." -"Dark mode colors": "Dark mode colors" -"With categories": "With categories" -"Custom categories": "Custom categories" -"Customize application categories": "Customize application categories" -"Reset to default": "Reset to default" -"Applications": "Applications" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Hide labels on mouse over" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Menú personalizado' +'Enable the custom menu': 'Activar o menú personalizado' +'No': 'Non' +'Yes': 'Si' +'Menu': 'Menú' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.' +'Top menu': 'Top menu' +'Apps that not must be moved in the side menu': 'As aplicacións que non deben moverse no menú lateral' +'If there is no selection then the global configuration is applied.': 'Se non hai selección, aplícase a configuración global.' +'Experimental': 'Experimental' +'Save': 'Gardar' +'You like this app and you want to support me?': 'Gústalle esta aplicación e quere axudarme?' +'Buy me a coffee ☕': 'Convídeme a un café ☕' +'Hidden': 'Agochado' +'Small': 'Pequeno' +'Normal': 'Normal' +'Big': 'Grande' +'Hidden icon': 'Icona agochada' +'Small icon': 'Icona pequena' +'Normal icon': 'Icona normal' +'Big icon': 'Icona grande' +'Hidden text': 'Texto agochado' +'Small text': 'Texto pequeno' +'Normal text': 'Texto normal' +'Big text': 'Texto grande' +'Colors': 'Cores' +'Background color': 'Cor do fondo' +'Background color of current app': 'Cor do fondo da aplicación actual' +'Text color': 'Cor do texto' +'Loader': 'Cargador' +'Icon': 'Icona' +'Same color': 'A mesma cor' +'Opposite color': 'A cor oposta' +'Transparent': 'Transparente' +'Opaque': 'Opaco' +'Opener': 'Abrir' +'Default': 'Predeterminado' +'Default (dark)': 'Predeterminado (escuro)' +'Hamburger': 'Hamburguesa' +'Hamburger (dark)': 'Hamburguesa (escuro)' +'Hamburger 2': 'Hamburguesa 2' +'Hamburger 2 (dark)': 'Hamburguesa 2 (escuro)' +'Before the logo': 'Antes do logotipo' +'After the logo': 'Após o logotipo' +'Position': 'Posición' +'Show only the opener (hidden logo)': 'Amosar só a icona de abrir (agochar o logotipo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Non amosar o menú lateral e a icona de abrir se non hai ningunha aplicación (por exemplo: páxinas públicas).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Abre o menú cando o rato está sobre a icona de abrir (desactivado automaticamente nas pantallas táctiles)' +'Display the big menu': 'Amosar o menú en grande' +'Display the logo': 'Amosar o logotipo' +'Icons and texts': 'Iconas e textos' +'Loader enabled': 'Cargador activado' +'Tips': 'Consellos' +'Always displayed': 'Amosado sempre' +'This is the automatic behavior when the menu is always displayed.': 'Este é o comportamento automático cando se amosa sempre o menú.' +'Not compatible with touch screens.': 'Non é compatíbel coas pantallas táctiles.' +'Big menu': 'Menú grande' +'Live preview': 'Vista previa en directo' +'Open apps in new tab': 'Abrir as aplicacións nunha nova lapela' +'Use the global setting': 'Usar o axuste global' +'Use my selection': 'Usar a miña selección' +'Show and hide the list of applications': 'Amosar e agochar a lista de aplicacións' +'Use the avatar instead of the logo': 'Usar o avatar no canto do logotipo' +'You do not have permission to change the settings.': 'Non ten permiso para cambiar os axustes.' +'Force this configuration to users': 'Forzar esta configuración para os usuarios' +'Export the configuration': 'Exportar a configuración' +'Purge the cache': 'Limpar a caché' +'Show the link to settings': 'Amosar a ligazón aos axustes' +'The menu is enabled by default for users': 'De xeito predeterminado o menú está activado para os usuarios' +'Except when the configuration is forced.': 'Agás cando a configuración é forzada.' +'Apps that should not be displayed in the menu': 'Aplicacións que non deben amosarse no menú' +'This feature is only compatible with the big menu display.': 'Esta función só é compatíbel coa presentación do menú grande.' +'The logo is a link to the default app': 'O logotipo é unha ligazón á aplicación predeterminada' +'Others': 'Outros' +'Categories': 'Categorías' +'Customize sorting': 'Personalizar a ordenación' +'Order by': 'Ordenar por' +'Name': 'Nome' +'Customed': 'Personalizado' +'Show and hide the list of categories': 'Amosar e agochar a lista de categorías' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Estes parámetros úsanse cando o tema escuro ou o tema escuro de Breeze están activados.' +'Dark mode colors': 'Cores do modo escuro' +'With categories': 'Con categorías' +'Custom categories': 'Categorías personalizadas' +'Customize application categories': 'Personalizar as categorías das aplicacións' +'Reset to default': 'Restabelecer os valores predeterminados' +'Applications': 'Aplicacións' +'Applications kept in the top menu': 'As aplicacións mantéñense no menú superior' +'Applications kept in the top menu but also shown in side menu': 'As aplicacións mantéñense no menú superior mais tamén aparecen no menú lateral' +'These applications must be selected in the previous option.': 'Estas aplicacións deben ser seleccionadas na opción anterior.' +'Hide labels on mouse over': 'Agochar as etiquetas ao pasar o rato' +'Except the hovered app': 'Agás a aplicación que pasa o rato' +'Search': 'Buscar' +'Toggle the menu': 'Alternar o menú' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/nl.yaml b/src/l10n/fixtures/nl.yaml index bf6ee2c..f1b3e55 100644 --- a/src/l10n/fixtures/nl.yaml +++ b/src/l10n/fixtures/nl.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Aangepast menu" -"Enable the custom menu": "Het aangepaste menu inschakelen" -"No": "Nee" -"Yes": "Ja" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Gebruik de snelkoppeling Ctrl+o om het zijmenu te openen en te verbergen. Gebruik tab om te navigeren.' -"Top menu": "Bovenste menu" -"Apps that not must be moved in the side menu": "Apps die niet moeten worden verplaatst in het zijmenu" -"If there is no selection then the global configuration is applied.": "Als er geen keuze is, wordt de globale configuratie toegepast." -"Experimental": "Experimenteel" -"Save": "Opslaan" -"You like this app and you want to support me?": "Vind je deze app leuk en wil je me steunen?" -"Buy me a coffee ☕": "Koop een koffie voor me ☕" -"Hidden": "Verborgen" -"Small": "Klein" -"Normal": "Normaal" -"Big": "Groot" -"Hidden icon": "Verborgen icoon" -"Small icon": "Klein icoon" -"Normal icon": "Normaal icoon" -"Big icon": "Groot icoon" -"Hidden text": "Verborgen tekst" -"Small text": "Kleine tekst" -"Normal text": "Normale tekst" -"Big text": "Grote tekst" -"Colors": "Kleuren" -"Background color": "Achtergrond kleur" -"Background color of current app": "Achtergrondkleur van huidige app" -"Text color": "Tekst kleur" -"Loader": "Lader" -"Icon": "Icoon" -"Same color": "Zelfde kleur" -"Opposite color": "Tegenovergestelde kleur" -"Transparent": "Transparant" -"Opaque": "Ondoorzichtig" -"Opener": "Opener" -"Default": "Standaard" -"Default (dark)": "Standaard (donker)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (donker)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (donker)" -"Before the logo": "Voor het logo" -"After the logo": "Na het logo" -"Position": "Positie" -"Show only the opener (hidden logo)": "Toon alleen de opener (verborgen logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Geef het zijmenu en de opener niet weer als er geen toepassing is (bijv. openbare pagina's)." -"Panel": "Paneel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Open het menu wanneer de muis over de opener gaat (automatisch uitgeschakeld op aanraakschermen)" -"Display the big menu": "Toon het grote menu" -"Display the logo": "Toon het logo" -"Icons and texts": "Iconen en teksten" -"Loader enabled": "Lader ingeschakeld" -"Tips": "Tips" -"Always displayed": "Altijd weergegeven" -"This is the automatic behavior when the menu is always displayed.": "Dit is het automatische gedrag wanneer het menu altijd wordt weergegeven." -"Not compatible with touch screens.": "Niet compatibel met aanraakschermen." -"Big menu": "Groot menu" -"Live preview": "Live voorbeeld" -"Open apps in new tab": "Open apps in nieuwe tab" -"Use the global setting": "Gebruik de globale instellingen" -"Use my selection": "Gebruik mijn selectie" -"Show and hide the list of applications": "De lijst met toepassingen tonen en verbergen" -"Use the avatar instead of the logo": "Gebruik avatar in plaats van het logo" -"You do not have permission to change the settings.": "Je hebt geen toestemming om de instellingen te veranderen." -"Force this configuration to users": "Forceer deze configuratie aan gebruikers" -"Export the configuration": "Exporteer de configuratie" -"Purge the cache": "De cache wissen" -"Show the link to settings": "Toon de link naar de instellingen" -"The menu is enabled by default for users": "Het menu is standaard ingeschakeld voor gebruikers" -"Except when the configuration is forced.": "Behalve als de configuratie geforceerd is." -"Apps that should not be displayed in the menu": "Apps die niet in het menu weergegeven mogen worden" -"This feature is only compatible with the big menu display.": "Deze functie is alleen compatibel met het grote menu scherm." -"The logo is a link to the default app": "Het logo is een link naar de standaard app" -"Others": "Overige" -"Categories": "Categorieën" -"Customize sorting": "Sortering aanpassen" -"Order by": "Sorteer op" -"Name": "Naam" -"Customed": "Aangepast" -"Show and hide the list of categories": "De lijst met categorieën tonen en verbergen" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Deze parameters worden gebruikt wanneer Dark theme of Breeze Dark Theme zijn ingeschakeld." -"Dark mode colors": "Donkere modus kleuren" -"With categories": "Met categorieën" -"Custom categories": "Aangepaste categorieën" -"Customize application categories": "Toepassingscategorieën aanpassen" -"Reset to default": "Terugzetten naar standaard" -"Applications": "Applicaties" -"Applications kept in the top menu": "Applicaties bewaard in het bovenste menu" -"Applications kept in the top menu but also shown in side menu": "Applicaties blijven in het topmenu maar worden ook in het zijmenu getoond" -"These applications must be selected in the previous option.": "Deze toepassingen moeten bij de vorige optie zijn geselecteerd." -"Hide labels on mouse over": "Hide labels on mouse over" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Aangepast menu' +'Enable the custom menu': 'Het aangepaste menu inschakelen' +'No': 'Nee' +'Yes': 'Ja' +'Menu': 'Menu' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Gebruik de snelkoppeling Ctrl+o om het zijmenu te openen en te verbergen. Gebruik tab key om te navigeren.' +'Top menu': 'Bovenste menu' +'Apps that not must be moved in the side menu': 'Apps die niet moeten worden verplaatst in het zijmenu' +'If there is no selection then the global configuration is applied.': 'Als er geen keuze is, wordt de globale configuratie toegepast.' +'Experimental': 'Experimenteel' +'Save': 'Opslaan' +'You like this app and you want to support me?': 'Vind je deze app leuk en wil je me steunen?' +'Buy me a coffee ☕': 'Koop een koffie voor me ☕' +'Hidden': 'Verborgen' +'Small': 'Klein' +'Normal': 'Normaal' +'Big': 'Groot' +'Hidden icon': 'Verborgen icoon' +'Small icon': 'Klein icoon' +'Normal icon': 'Normaal icoon' +'Big icon': 'Groot icoon' +'Hidden text': 'Verborgen tekst' +'Small text': 'Kleine tekst' +'Normal text': 'Normale tekst' +'Big text': 'Grote tekst' +'Colors': 'Kleuren' +'Background color': 'Achtergrond kleur' +'Background color of current app': 'Achtergrondkleur van huidige app' +'Text color': 'Tekst kleur' +'Loader': 'Lader' +'Icon': 'Icoon' +'Same color': 'Zelfde kleur' +'Opposite color': 'Tegenovergestelde kleur' +'Transparent': 'Transparant' +'Opaque': 'Ondoorzichtig' +'Opener': 'Opener' +'Default': 'Standaard' +'Default (dark)': 'Standaard (donker)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (donker)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (donker)' +'Before the logo': 'Voor het logo' +'After the logo': 'Na het logo' +'Position': 'Positie' +'Show only the opener (hidden logo)': 'Toon alleen de opener (verborgen logo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Geef het zijmenu en de opener niet weer als er geen toepassing is (bijv. openbare pagina''s).' +'Panel': 'Paneel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Open het menu wanneer de muis over de opener gaat (automatisch uitgeschakeld op aanraakschermen)' +'Display the big menu': 'Toon het grote menu' +'Display the logo': 'Toon het logo' +'Icons and texts': 'Iconen en teksten' +'Loader enabled': 'Lader ingeschakeld' +'Tips': 'Tips' +'Always displayed': 'Altijd weergegeven' +'This is the automatic behavior when the menu is always displayed.': 'Dit is het automatische gedrag wanneer het menu altijd wordt weergegeven.' +'Not compatible with touch screens.': 'Niet compatibel met aanraakschermen.' +'Big menu': 'Groot menu' +'Live preview': 'Live voorbeeld' +'Open apps in new tab': 'Open apps in nieuwe tab' +'Use the global setting': 'Gebruik de globale instellingen' +'Use my selection': 'Gebruik mijn selectie' +'Show and hide the list of applications': 'De lijst met toepassingen tonen en verbergen' +'Use the avatar instead of the logo': 'Gebruik avatar in plaats van het logo' +'You do not have permission to change the settings.': 'Je hebt geen toestemming om de instellingen te veranderen.' +'Force this configuration to users': 'Forceer deze configuratie aan gebruikers' +'Export the configuration': 'Exporteer de configuratie' +'Purge the cache': 'De cache wissen' +'Show the link to settings': 'Toon de link naar de instellingen' +'The menu is enabled by default for users': 'Het menu is standaard ingeschakeld voor gebruikers' +'Except when the configuration is forced.': 'Behalve als de configuratie geforceerd is.' +'Apps that should not be displayed in the menu': 'Apps die niet in het menu weergegeven mogen worden' +'This feature is only compatible with the big menu display.': 'Deze functie is alleen compatibel met het grote menu scherm.' +'The logo is a link to the default app': 'Het logo is een link naar de standaard app' +'Others': 'Overige' +'Categories': 'Categorieën' +'Customize sorting': 'Sortering aanpassen' +'Order by': 'Sorteer op' +'Name': 'Naam' +'Customed': 'Aangepast' +'Show and hide the list of categories': 'De lijst met categorieën tonen en verbergen' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Deze parameters worden gebruikt wanneer Dark theme of Breeze Dark Theme zijn ingeschakeld.' +'Dark mode colors': 'Donkere modus kleuren' +'With categories': 'Met categorieën' +'Custom categories': 'Aangepaste categorieën' +'Customize application categories': 'Toepassingscategorieën aanpassen' +'Reset to default': 'Terugzetten naar standaard' +'Applications': 'Applicaties' +'Applications kept in the top menu': 'Applicaties bewaard in het bovenste menu' +'Applications kept in the top menu but also shown in side menu': 'Applicaties blijven in het topmenu maar worden ook in het zijmenu getoond' +'These applications must be selected in the previous option.': 'Deze toepassingen moeten bij de vorige optie zijn geselecteerd.' +'Hide labels on mouse over': 'Hide labels on mouse over' +'Except the hovered app': 'Except the hovered app' +'Search': 'Search' +'Toggle the menu': 'Toggle the menu' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/pt_BR.yaml b/src/l10n/fixtures/pt_BR.yaml index b93608f..9e314a5 100644 --- a/src/l10n/fixtures/pt_BR.yaml +++ b/src/l10n/fixtures/pt_BR.yaml @@ -1,94 +1,109 @@ -"Custom menu": "Menu personalizado" -"Enable the custom menu": "Habilitar o menu personalizado" -"No": "Não" -"Yes": "Sim" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Use o atalho Ctrl+o para exibir e para esconder o menu lateral. Use tab para navegar.' -"Top menu": "Menu superior" -"Apps that not must be moved in the side menu": "Apps que não devem ser movidos para o menu lateral" -"If there is no selection then the global configuration is applied.": "Se não houver seleção, a configuração global será aplicada." -"Experimental": "Experimental" -"Save": "Salvar" -"You like this app and you want to support me?": "Você gosta deste aplicativo e quer me apoiar?" -"Buy me a coffee ☕": "Me pague um café ☕" -"Hidden": "Oculto" -"Small": "Pequeno" -"Normal": "Normal" -"Big": "Grande" -"Hidden icon": "Ícone oculto" -"Small icon": "Ícone pequeno" -"Normal icon": "Ícone normal" -"Big icon": "Ícone grance" -"Hidden text": "Texto oculto" -"Small text": "Texto pequeno" -"Normal text": "Texto normal" -"Big text": "Texto grande" -"Colors": "Cores" -"Background color": "Cor de fundo" -"Background color of current app": "Cor de fundo do app atual" -"Text color": "Cor do texto" -"Loader": "Progresso" -"Icon": "Ícone" -"Same color": "Mesma cor" -"Opposite color": "Cor oposta" -"Transparent": "Transparente" -"Opaque": "Opaco" -"Opener": "Abrir" -"Default": "Padrão" -"Default (dark)": "Padrão (escuro)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (escuro)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (escuro)" -"Before the logo": "Antes da logo" -"After the logo": "Depois da logo" -"Position": "Posição" -"Show only the opener (hidden logo)": "Mostrar apenas o Abrir (ocultar logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Não mostrar o menu lateral e o Abrir se não houver aplicação (p.ex. páginas públicas)." -"Panel": "Painel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Abrir o menu quando o mouse passar sobre o Abrir (desativado automaticamente em telas de toque)" -"Display the big menu": "Mostrar o menu grande" -"Display the logo": "Mostrar a logo" -"Icons and texts": "Ícones e textos" -"Loader enabled": "Progresso ativado" -"Tips": "Dicas" -"Always displayed": "Sempre visível" -"This is the automatic behavior when the menu is always displayed.": "Este é o comportamento automático quando o menu está sempre visível." -"Not compatible with touch screens.": "Não compatível com telas de toque." -"Big menu": "Menu grande" -"Live preview": "Visualização ao vivo" -"Open apps in new tab": "Abrir apps em nova aba" -"Use the global setting": "Usar configurações globais" -"Use my selection": "Usar minha seleção" -"Show and hide the list of applications": "Mostrar e ocultar a lista de aplicativos" -"Use the avatar instead of the logo": "Use o avatar ao invés da logo" -"You do not have permission to change the settings.": "Você não tem permissão para alterar as configurações." -"Force this configuration to users": "Forçar esta configuração para os usuários" -"Export the configuration": "Exportar a configuração" -"Purge the cache": "Limpar o cache" -"Show the link to settings": "Mostrar o link para configurações" -"The menu is enabled by default for users": "O menu é habilitado por padrão para os usuários" -"Except when the configuration is forced.": "Exceto quando a configuração é forçada." -"Apps that should not be displayed in the menu": "Apps que não devem ser mostrados no menu" -"This feature is only compatible with the big menu display.": "Este recurso só é compatível com a exibição do menu grande." -"The logo is a link to the default app": "A logo é um link para o app padrão" -"Others": "Outros" -"Categories": "Categorias" -"Customize sorting": "Personalizar classificação" -"Order by": "Ordenar por" -"Name": "Nome" -"Customed": "Personalizado" -"Show and hide the list of categories": "Mostrar e esconder a lista de categorias" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Estes parâmetros são usados quando o tema escuro ou o tema Dark Breeze está ativo." -"Dark mode colors": "Cores do modo escuro" -"With categories": "Com categorias" -"Custom categories": "Categorias personalizadas" -"Customize application categories": "Personalizar categorias de apps" -"Reset to default": "Restaurar padrão" -"Applications": "Aplicativos" -"Applications kept in the top menu": "Aplicativos mantidos no menu superior" -"Applications kept in the top menu but also shown in side menu": "Aplicativos mantidos no menu superior, mas também mostrados no menu lateral" -"These applications must be selected in the previous option.": "Estes aplicativos devem ser selecionados na opção anterior." -"Hide labels on mouse over": "Ocultar descrição ao passar o mouse" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Menú personalizado' +'Enable the custom menu': 'Activar o menu personalizado' +'No': 'Não' +'Yes': 'Sim' +'Menu': 'Menu' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Use o atalho Ctrl+o para exibir e para esconder o menu lateral. Use tab key para navegar.' +'Top menu': 'Menu superior' +'Apps that not must be moved in the side menu': 'Apps que não devem ser movidos para o menu lateral' +'If there is no selection then the global configuration is applied.': 'Se não houver seleção, a configuração global será aplicada.' +'Experimental': 'Experimental' +'Save': 'Salvar' +'You like this app and you want to support me?': 'Você gosta deste aplicativo e quer me apoiar?' +'Buy me a coffee ☕': 'Me pague um café ☕' +'Hidden': 'Oculto' +'Small': 'Pequeno' +'Normal': 'Normal' +'Big': 'Grande' +'Hidden icon': 'Ícone oculto' +'Small icon': 'Ícone pequeno' +'Normal icon': 'Ícone normal' +'Big icon': 'Ícone grance' +'Hidden text': 'Texto oculto' +'Small text': 'Texto pequeno' +'Normal text': 'Texto normal' +'Big text': 'Texto grande' +'Colors': 'Cores' +'Background color': 'Cor de fundo' +'Background color of current app': 'Cor de fundo do app atual' +'Text color': 'Cor do texto' +'Loader': 'Progresso' +'Icon': 'Ícone' +'Same color': 'Mesma cor' +'Opposite color': 'Cor oposta' +'Transparent': 'Transparente' +'Opaque': 'Opaco' +'Opener': 'Abrir' +'Default': 'Padrão' +'Default (dark)': 'Padrão (escuro)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (escuro)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (escuro)' +'Before the logo': 'Antes da logo' +'After the logo': 'Depois da logo' +'Position': 'Posição' +'Show only the opener (hidden logo)': 'Mostrar apenas o Abrir (ocultar logo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Não mostrar o menu lateral e o Abrir se não houver aplicação (p.ex. páginas públicas).' +'Panel': 'Painel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Abrir o menu quando o mouse passar sobre o Abrir (desativado automaticamente em telas de toque)' +'Display the big menu': 'Mostrar o menu grande' +'Display the logo': 'Mostrar a logo' +'Icons and texts': 'Ícones e textos' +'Loader enabled': 'Progresso ativado' +'Tips': 'Dicas' +'Always displayed': 'Sempre visível' +'This is the automatic behavior when the menu is always displayed.': 'Este é o comportamento automático quando o menu está sempre visível.' +'Not compatible with touch screens.': 'Não compatível com telas de toque.' +'Big menu': 'Menu grande' +'Live preview': 'Visualização ao vivo' +'Open apps in new tab': 'Abrir apps em nova aba' +'Use the global setting': 'Usar configurações globais' +'Use my selection': 'Usar minha seleção' +'Show and hide the list of applications': 'Mostrar e ocultar a lista de aplicativos' +'Use the avatar instead of the logo': 'Use o avatar ao invés da logo' +'You do not have permission to change the settings.': 'Você não tem permissão para alterar as configurações.' +'Force this configuration to users': 'Forçar esta configuração para os usuários' +'Export the configuration': 'Exportar a configuração' +'Purge the cache': 'Limpar o cache' +'Show the link to settings': 'Mostrar o link para configurações' +'The menu is enabled by default for users': 'O menu é habilitado por padrão para os usuários' +'Except when the configuration is forced.': 'Exceto quando a configuração é forçada.' +'Apps that should not be displayed in the menu': 'Apps que não devem ser mostrados no menu' +'This feature is only compatible with the big menu display.': 'Este recurso só é compatível com a exibição do menu grande.' +'The logo is a link to the default app': 'A logo é um link para o app padrão' +'Others': 'Outros' +'Categories': 'Categorias' +'Customize sorting': 'Personalizar classificação' +'Order by': 'Ordenar por' +'Name': 'Nome' +'Customed': 'Personalizado' +'Show and hide the list of categories': 'Mostrar e esconder a lista de categorias' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Estes parâmetros são usados quando o tema escuro ou o tema Dark Breeze está ativo.' +'Dark mode colors': 'Cores do modo escuro' +'With categories': 'Com categorias' +'Custom categories': 'Categorias personalizadas' +'Customize application categories': 'Personalizar categorias de apps' +'Reset to default': 'Restaurar padrão' +'Applications': 'Aplicativos' +'Applications kept in the top menu': 'Aplicativos mantidos no menu superior' +'Applications kept in the top menu but also shown in side menu': 'Aplicativos mantidos no menu superior, mas também mostrados no menu lateral' +'These applications must be selected in the previous option.': 'Estes aplicativos devem ser selecionados na opção anterior.' +'Hide labels on mouse over': 'Ocultar descrição ao passar o mouse' +'Toggle the menu': 'Toggle the menu' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/ru.yaml b/src/l10n/fixtures/ru.yaml index 660214f..e23aa0b 100644 --- a/src/l10n/fixtures/ru.yaml +++ b/src/l10n/fixtures/ru.yaml @@ -1,96 +1,111 @@ -"Custom menu": "Custom menu" -"Enable the custom menu": "Включить пользовательское меню" -"No": "Нет" -"Yes": "Да" -"Menu": "Меню" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Используйте сочетание клавиш Ctrl+o, чтобы открыть или скрыть боковое меню. Используйте Tab для навигации.' -"Top menu": "Верхнее меню" -"Apps that not must be moved in the side menu": "Приложения не перемещаемые в боковое меню" -"If there is no selection then the global configuration is applied.": "Если тут ничего не отмечено, применяются глобальные настройки." -"Experimental": "Экспериментальный" -"Save": "Сохранить" -"You like this app and you want to support me?": "Вам нравится приложение или вы хотите поддержать меня?" -"Buy me a coffee ☕": "Купить мне чашку кофе ☕" -"Hidden": "Скрыто" -"Small": "Маленький" -"Normal": "Средний" -"Big": "Большой" -"Hidden icon": "Без иконки" -"Small icon": "Маленькая иконка" -"Normal icon": "Средняя иконка" -"Big icon": "Большая иконка" -"Hidden text": "Без текста" -"Small text": "Маленький текст" -"Normal text": "Средний текст" -"Big text": "Большой текст" -"Colors": "Цвета" -"Background color": "Цвет фона" -"Background color of current app": "Цвет фона выбранного приложения" -"Text color": "Цвет текста" -"Loader": "Загрузчик" -"Icon": "Иконка" -"Same color": "Такой же цвет" -"Opposite color": "Противоположный цвет" -"Transparent": "Прозрачный" -"Opaque": "Непрозрачный" -"Opener": "Открывалка" -"Default": "По умолчанию" -"Default (dark)": "По умолчанию (тёмный)" -"Hamburger": "Гамбургер" -"Hamburger (dark)": "Гамбургер (тёмный)" -"Hamburger 2": "Гамбургер 2" -"Hamburger 2 (dark)": "Гамбургер 2 (тёмный)" -"Before the logo": "Перед логотипом" -"After the logo": "После логотипа" -"Position": "Положение" -"Show only the opener (hidden logo)": "Показать только открывающую часть (скрытый логотип)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Не отображать боковое меню и открывалку, если нет приложения (например, публичные страницы)." -"Panel": "Панель" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Открывать меню при наведении мыши на экран (автоматически отключается на сенсорных экранах)" -"Display the big menu": "Отобразить большое меню" -"Display the logo": "Показать логотип" -"Icons and texts": "Иконки и текст" -"Loader enabled": "Загрузчик включен" -"Tips": "Советы" -"Always displayed": "Всегда отображается" -"This is the automatic behavior when the menu is always displayed.": "This is the automatic behavior when the menu is always displayed." -"Not compatible with touch screens.": "Не совместимо с сенсорными экранами." -"Big menu": "Большое меню" -"Live preview": "Live preview" -"Open apps in new tab": "Открывать приложения в новой вкладке" -"Use the global setting": "Использовать глобальные настройки" -"Use my selection": "Использовать мои настройки" -"Show and hide the list of applications": "Показать или скрыть список приложений" -"Use the avatar instead of the logo": "Использовать аватар вместо логотипа" -"You do not have permission to change the settings.": "У вас нет разрешения изменять настройки." -"Force this configuration to users": "Force this configuration to users" -"Export the configuration": "Экспортировать конфигурацию" -"Purge the cache": "Очистить кэш" -"Show the link to settings": "Показать ссылку на настройки" -"The menu is enabled by default for users": "Это меню включено по умолчанию для пользователей" -"Except when the configuration is forced.": "Except when the configuration is forced." -"Apps that should not be displayed in the menu": "Ппрограммы, скрытые из меню" -"This feature is only compatible with the big menu display.": "This feature is only compatible with the big menu display." -"The logo is a link to the default app": "Логотип открывает приложение по умолчанию" -"Others": "Прочие" -"Categories": "Категории" -"Customize sorting": "Настроить сортировку" -"Order by": "В порядке" -"Name": "Название" -"Customed": "Customed" -"Show and hide the list of categories": "Показать или скрыть список категорий" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "Эти настройки используются темами Тёмная и Тёмная Breeze." -"Dark mode colors": "Цвета тёмной темы" -"With categories": "С категориями" -"Custom categories": "Пользовательские категории" -"Customize application categories": "Изменить категории приложений" -"Reset to default": "Сбросить к значениям по умолчанию" -"Applications": "Приложения" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Скрыть название при наведении мыши" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Custom menu' +'Enable the custom menu': 'Включить пользовательское меню' +'No': 'Нет' +'Yes': 'Да' +'Menu': 'Меню' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Используйте сочетание клавиш Ctrl+o, чтобы открыть или скрыть боковое меню. Используйте tab key для навигации.' +'Top menu': 'Верхнее меню' +'Apps that not must be moved in the side menu': 'Приложения не перемещаемые в боковое меню' +'If there is no selection then the global configuration is applied.': 'Если тут ничего не отмечено, применяются глобальные настройки.' +'Experimental': 'Экспериментальный' +'Save': 'Сохранить' +'You like this app and you want to support me?': 'Вам нравится приложение или вы хотите поддержать меня?' +'Buy me a coffee ☕': 'Купить мне чашку кофе ☕' +'Hidden': 'Скрыто' +'Small': 'Маленький' +'Normal': 'Средний' +'Big': 'Большой' +'Hidden icon': 'Без иконки' +'Small icon': 'Маленькая иконка' +'Normal icon': 'Средняя иконка' +'Big icon': 'Большая иконка' +'Hidden text': 'Без текста' +'Small text': 'Маленький текст' +'Normal text': 'Средний текст' +'Big text': 'Большой текст' +'Colors': 'Цвета' +'Background color': 'Цвет фона' +'Background color of current app': 'Цвет фона выбранного приложения' +'Text color': 'Цвет текста' +'Loader': 'Загрузчик' +'Icon': 'Иконка' +'Same color': 'Такой же цвет' +'Opposite color': 'Противоположный цвет' +'Transparent': 'Прозрачный' +'Opaque': 'Непрозрачный' +'Opener': 'Открывалка' +'Default': 'По умолчанию' +'Default (dark)': 'По умолчанию (тёмный)' +'Hamburger': 'Гамбургер' +'Hamburger (dark)': 'Гамбургер (тёмный)' +'Hamburger 2': 'Гамбургер 2' +'Hamburger 2 (dark)': 'Гамбургер 2 (тёмный)' +'Before the logo': 'Перед логотипом' +'After the logo': 'После логотипа' +'Position': 'Положение' +'Show only the opener (hidden logo)': 'Показать только открывающую часть (скрытый логотип)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Не отображать боковое меню и открывалку, если нет приложения (например, публичные страницы).' +'Panel': 'Панель' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Открывать меню при наведении мыши на открывалку (автоматически отключается на сенсорных экранах)' +'Display the big menu': 'Отобразить большое меню' +'Display the logo': 'Показать логотип' +'Icons and texts': 'Иконки и текст' +'Loader enabled': 'Загрузчик включен' +'Tips': 'Советы' +'Always displayed': 'Всегда отображается' +'This is the automatic behavior when the menu is always displayed.': 'Это автоматическое поведение, когда меню отображается всегда.' +'Not compatible with touch screens.': 'Не совместимо с сенсорными экранами.' +'Big menu': 'Большое меню' +'Live preview': 'Предпросмотр в реальном времени' +'Open apps in new tab': 'Открывать приложения в новой вкладке' +'Use the global setting': 'Использовать глобальные настройки' +'Use my selection': 'Использовать мои настройки' +'Show and hide the list of applications': 'Показать или скрыть список приложений' +'Use the avatar instead of the logo': 'Использовать аватар вместо логотипа' +'You do not have permission to change the settings.': 'У вас нет разрешения изменять настройки.' +'Force this configuration to users': 'Принудительно предоставить эту конфигурацию пользователям' +'Export the configuration': 'Экспортировать конфигурацию' +'Purge the cache': 'Очистить кэш' +'Show the link to settings': 'Показать ссылку на настройки' +'The menu is enabled by default for users': 'Это меню включено по умолчанию для пользователей' +'Except when the configuration is forced.': 'За исключением случаев, когда конфигурация является принудительной.' +'Apps that should not be displayed in the menu': 'Ппрограммы, скрытые из меню' +'This feature is only compatible with the big menu display.': 'Эта функция совместима только с отображением большого меню.' +'The logo is a link to the default app': 'Логотип открывает приложение по умолчанию' +'Others': 'Прочие' +'Categories': 'Категории' +'Customize sorting': 'Настроить сортировку' +'Order by': 'В порядке' +'Name': 'Название' +'Customed': 'Customed' +'Show and hide the list of categories': 'Показать или скрыть список категорий' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'Эти настройки используются темами Тёмная и Тёмная Breeze.' +'Dark mode colors': 'Цвета тёмной темы' +'With categories': 'С категориями' +'Custom categories': 'Пользовательские категории' +'Customize application categories': 'Изменить категории приложений' +'Reset to default': 'Сбросить к значениям по умолчанию' +'Applications': 'Приложения' +'Applications kept in the top menu': 'Приложения, хранящиеся в верхнем меню' +'Applications kept in the top menu but also shown in side menu': 'Приложения хранящиеся в верхнем меню, но также отображающиеся в боковом меню' +'These applications must be selected in the previous option.': 'Эти приложения необходимо выбрать в предыдущем выборе.' +'Hide labels on mouse over': 'Скрыть название при наведении мыши' +'Except the hovered app': 'Кроме приложения, на котором курсор' +'Search': 'Поиск' +'Toggle the menu': 'Переключить меню' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/sk.yaml b/src/l10n/fixtures/sk.yaml index d386863..aa9d09c 100644 --- a/src/l10n/fixtures/sk.yaml +++ b/src/l10n/fixtures/sk.yaml @@ -1,94 +1,109 @@ -"Custom menu": "Custom menu" -"Enable the custom menu": "Enable the custom menu" -"No": "No" -"Yes": "Yes" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -: 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.' -"Top menu": "Top menu" -"Apps that not must be moved in the side menu": "Apps that not must be moved in the side menu" -"If there is no selection then the global configuration is applied.": "If there is no selection then the global configuration is applied." -"Experimental": "Experimental" -"Save": "Save" -"You like this app and you want to support me?": "You like this app and you want to support me?" -"Buy me a coffee ☕": "Buy me a coffee ☕" -"Hidden": "Hidden" -"Small": "Small" -"Normal": "Normal" -"Big": "Big" -"Hidden icon": "Hidden icon" -"Small icon": "Small icon" -"Normal icon": "Normal icon" -"Big icon": "Big icon" -"Hidden text": "Hidden text" -"Small text": "Small text" -"Normal text": "Normal text" -"Big text": "Big text" -"Colors": "Colors" -"Background color": "Background color" -"Background color of current app": "Background color of current app" -"Text color": "Text color" -"Loader": "Loader" -"Icon": "Icon" -"Same color": "Same color" -"Opposite color": "Opposite color" -"Transparent": "Transparent" -"Opaque": "Opaque" -"Opener": "Opener" -"Default": "Default" -"Default (dark)": "Default (dark)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (dark)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (dark)" -"Before the logo": "Before the logo" -"After the logo": "After the logo" -"Position": "Position" -"Show only the opener (hidden logo)": "Show only the opener (hidden logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Do not display the side menu and the opener if there is no application (eg: public pages)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Open the menu when the mouse is hover the opener (automatically disabled on touch screens)" -"Display the big menu": "Display the big menu" -"Display the logo": "Display the logo" -"Icons and texts": "Icons and texts" -"Loader enabled": "Loader enabled" -"Tips": "Tips" -"Always displayed": "Always displayed" -"This is the automatic behavior when the menu is always displayed.": "This is the automatic behavior when the menu is always displayed." -"Not compatible with touch screens.": "Not compatible with touch screens." -"Big menu": "Big menu" -"Live preview": "Live preview" -"Open apps in new tab": "Open apps in new tab" -"Use the global setting": "Use the global setting" -"Use my selection": "Use my selection" -"Show and hide the list of applications": "Show and hide the list of applications" -"Use the avatar instead of the logo": "Use the avatar instead of the logo" -"You do not have permission to change the settings.": "You do not have permission to change the settings." -"Force this configuration to users": "Force this configuration to users" -"Export the configuration": "Export the configuration" -"Purge the cache": "Purge the cache" -"Show the link to settings": "Show the link to settings" -"The menu is enabled by default for users": "The menu is enabled by default for users" -"Except when the configuration is forced.": "Except when the configuration is forced." -"Apps that should not be displayed in the menu": "Apps that should not be displayed in the menu" -"This feature is only compatible with the big menu display.": "This feature is only compatible with the big menu display." -"The logo is a link to the default app": "The logo is a link to the default app" -"Others": "Others" -"Categories": "Categories" -"Customize sorting": "Customize sorting" -"Order by": "Order by" -"Name": "Name" -"Customed": "Customed" -"Show and hide the list of categories": "Show and hide the list of categories" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "This parameters are used when Dark theme or Breeze Dark Theme are enabled." -"Dark mode colors": "Dark mode colors" -"With categories": "With categories" -"Custom categories": "Custom categories" -"Customize application categories": "Customize application categories" -"Reset to default": "Reset to default" -"Applications": "Applications" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Hide labels on mouse over" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Custom menu' +'Enable the custom menu': 'Enable the custom menu' +'No': 'No' +'Yes': 'Yes' +'Menu': 'Menu' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.' +'Top menu': 'Top menu' +'Apps that not must be moved in the side menu': 'Apps that not must be moved in the side menu' +'If there is no selection then the global configuration is applied.': 'If there is no selection then the global configuration is applied.' +'Experimental': 'Experimental' +'Save': 'Save' +'You like this app and you want to support me?': 'You like this app and you want to support me?' +'Buy me a coffee ☕': 'Buy me a coffee ☕' +'Hidden': 'Hidden' +'Small': 'Small' +'Normal': 'Normal' +'Big': 'Big' +'Hidden icon': 'Hidden icon' +'Small icon': 'Small icon' +'Normal icon': 'Normal icon' +'Big icon': 'Big icon' +'Hidden text': 'Hidden text' +'Small text': 'Small text' +'Normal text': 'Normal text' +'Big text': 'Big text' +'Colors': 'Colors' +'Background color': 'Background color' +'Background color of current app': 'Background color of current app' +'Text color': 'Text color' +'Loader': 'Loader' +'Icon': 'Icon' +'Same color': 'Same color' +'Opposite color': 'Opposite color' +'Transparent': 'Transparent' +'Opaque': 'Opaque' +'Opener': 'Opener' +'Default': 'Default' +'Default (dark)': 'Default (dark)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (dark)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (dark)' +'Before the logo': 'Before the logo' +'After the logo': 'After the logo' +'Position': 'Position' +'Show only the opener (hidden logo)': 'Show only the opener (hidden logo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Do not display the side menu and the opener if there is no application (eg: public pages).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)' +'Display the big menu': 'Display the big menu' +'Display the logo': 'Display the logo' +'Icons and texts': 'Icons and texts' +'Loader enabled': 'Loader enabled' +'Tips': 'Tips' +'Always displayed': 'Always displayed' +'This is the automatic behavior when the menu is always displayed.': 'This is the automatic behavior when the menu is always displayed.' +'Not compatible with touch screens.': 'Not compatible with touch screens.' +'Big menu': 'Big menu' +'Live preview': 'Live preview' +'Open apps in new tab': 'Open apps in new tab' +'Use the global setting': 'Use the global setting' +'Use my selection': 'Use my selection' +'Show and hide the list of applications': 'Show and hide the list of applications' +'Use the avatar instead of the logo': 'Use the avatar instead of the logo' +'You do not have permission to change the settings.': 'You do not have permission to change the settings.' +'Force this configuration to users': 'Force this configuration to users' +'Export the configuration': 'Export the configuration' +'Purge the cache': 'Purge the cache' +'Show the link to settings': 'Show the link to settings' +'The menu is enabled by default for users': 'The menu is enabled by default for users' +'Except when the configuration is forced.': 'Except when the configuration is forced.' +'Apps that should not be displayed in the menu': 'Apps that should not be displayed in the menu' +'This feature is only compatible with the big menu display.': 'This feature is only compatible with the big menu display.' +'The logo is a link to the default app': 'The logo is a link to the default app' +'Others': 'Others' +'Categories': 'Categories' +'Customize sorting': 'Customize sorting' +'Order by': 'Order by' +'Name': 'Name' +'Customed': 'Customed' +'Show and hide the list of categories': 'Show and hide the list of categories' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'This parameters are used when Dark theme or Breeze Dark Theme are enabled.' +'Dark mode colors': 'Dark mode colors' +'With categories': 'With categories' +'Custom categories': 'Custom categories' +'Customize application categories': 'Customize application categories' +'Reset to default': 'Reset to default' +'Applications': 'Applications' +'Applications kept in the top menu': 'Applications kept in the top menu' +'Applications kept in the top menu but also shown in side menu': 'Applications kept in the top menu but also shown in side menu' +'These applications must be selected in the previous option.': 'These applications must be selected in the previous option.' +'Hide labels on mouse over': 'Hide labels on mouse over' +'Toggle the menu': 'Toggle the menu' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/tpl/base.yaml b/src/l10n/fixtures/tpl/base.yaml index a2e635a..eebd8c2 100644 --- a/src/l10n/fixtures/tpl/base.yaml +++ b/src/l10n/fixtures/tpl/base.yaml @@ -1,100 +1,111 @@ -"Custom menu": "Custom menu" -"Enable the custom menu": "Enable the custom menu" -"No": "No" -"Yes": "Yes" -"Menu": "Menu" -? 'Use the shortcut Ctrl+o - to open and to hide the side menu. Use tab to - navigate.' -: 'Use the shortcut Ctrl+o - to open and to hide the side menu. Use tab to - navigate.' -"Top menu": "Top menu" -"Apps that not must be moved in the side menu": "Apps that not must be moved in the side menu" -"If there is no selection then the global configuration is applied.": "If there is no selection then the global configuration is applied." -"Experimental": "Experimental" -"Save": "Save" -"You like this app and you want to support me?": "You like this app and you want to support me?" -"Buy me a coffee ☕": "Buy me a coffee ☕" -"Hidden": "Hidden" -"Small": "Small" -"Normal": "Normal" -"Big": "Big" -"Hidden icon": "Hidden icon" -"Small icon": "Small icon" -"Normal icon": "Normal icon" -"Big icon": "Big icon" -"Hidden text": "Hidden text" -"Small text": "Small text" -"Normal text": "Normal text" -"Big text": "Big text" -"Colors": "Colors" -"Background color": "Background color" -"Background color of current app": "Background color of current app" -"Text color": "Text color" -"Loader": "Loader" -"Icon": "Icon" -"Same color": "Same color" -"Opposite color": "Opposite color" -"Transparent": "Transparent" -"Opaque": "Opaque" -"Opener": "Opener" -"Default": "Default" -"Default (dark)": "Default (dark)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (dark)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (dark)" -"Before the logo": "Before the logo" -"After the logo": "After the logo" -"Position": "Position" -"Show only the opener (hidden logo)": "Show only the opener (hidden logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "Do not display the side menu and the opener if there is no application (eg: public pages)." -"Panel": "Panel" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "Open the menu when the mouse is hover the opener (automatically disabled on touch screens)" -"Display the big menu": "Display the big menu" -"Display the logo": "Display the logo" -"Icons and texts": "Icons and texts" -"Loader enabled": "Loader enabled" -"Tips": "Tips" -"Always displayed": "Always displayed" -"This is the automatic behavior when the menu is always displayed.": "This is the automatic behavior when the menu is always displayed." -"Not compatible with touch screens.": "Not compatible with touch screens." -"Big menu": "Big menu" -"Live preview": "Live preview" -"Open apps in new tab": "Open apps in new tab" -"Use the global setting": "Use the global setting" -"Use my selection": "Use my selection" -"Show and hide the list of applications": "Show and hide the list of applications" -"Use the avatar instead of the logo": "Use the avatar instead of the logo" -"You do not have permission to change the settings.": "You do not have permission to change the settings." -"Force this configuration to users": "Force this configuration to users" -"Export the configuration": "Export the configuration" -"Purge the cache": "Purge the cache" -"Show the link to settings": "Show the link to settings" -"The menu is enabled by default for users": "The menu is enabled by default for users" -"Except when the configuration is forced.": "Except when the configuration is forced." -"Apps that should not be displayed in the menu": "Apps that should not be displayed in the menu" -"This feature is only compatible with the big menu display.": "This feature is only compatible with the big menu display." -"The logo is a link to the default app": "The logo is a link to the default app" -"Others": "Others" -"Categories": "Categories" -"Customize sorting": "Customize sorting" -"Order by": "Order by" -"Name": "Name" -"Customed": "Customed" -"Show and hide the list of categories": "Show and hide the list of categories" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "This parameters are used when Dark theme or Breeze Dark Theme are enabled." -"Dark mode colors": "Dark mode colors" -"With categories": "With categories" -"Custom categories": "Custom categories" -"Customize application categories": "Customize application categories" -"Reset to default": "Reset to default" -"Applications": "Applications" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Hide labels on mouse over" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle the menu": "Toggle the menu" +'Custom menu': 'Custom menu' +'Enable the custom menu': 'Enable the custom menu' +'No': 'No' +'Yes': 'Yes' +'Menu': 'Menu' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.': 'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab key to navigate.' +'Top menu': 'Top menu' +'Apps that not must be moved in the side menu': 'Apps that not must be moved in the side menu' +'If there is no selection then the global configuration is applied.': 'If there is no selection then the global configuration is applied.' +'Experimental': 'Experimental' +'Save': 'Save' +'You like this app and you want to support me?': 'You like this app and you want to support me?' +'Buy me a coffee ☕': 'Buy me a coffee ☕' +'Hidden': 'Hidden' +'Small': 'Small' +'Normal': 'Normal' +'Big': 'Big' +'Hidden icon': 'Hidden icon' +'Small icon': 'Small icon' +'Normal icon': 'Normal icon' +'Big icon': 'Big icon' +'Hidden text': 'Hidden text' +'Small text': 'Small text' +'Normal text': 'Normal text' +'Big text': 'Big text' +'Colors': 'Colors' +'Background color': 'Background color' +'Background color of current app': 'Background color of current app' +'Text color': 'Text color' +'Loader': 'Loader' +'Icon': 'Icon' +'Same color': 'Same color' +'Opposite color': 'Opposite color' +'Transparent': 'Transparent' +'Opaque': 'Opaque' +'Opener': 'Opener' +'Default': 'Default' +'Default (dark)': 'Default (dark)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (dark)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (dark)' +'Before the logo': 'Before the logo' +'After the logo': 'After the logo' +'Position': 'Position' +'Show only the opener (hidden logo)': 'Show only the opener (hidden logo)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': 'Do not display the side menu and the opener if there is no application (eg: public pages).' +'Panel': 'Panel' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': 'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)' +'Display the big menu': 'Display the big menu' +'Display the logo': 'Display the logo' +'Icons and texts': 'Icons and texts' +'Loader enabled': 'Loader enabled' +'Tips': 'Tips' +'Always displayed': 'Always displayed' +'This is the automatic behavior when the menu is always displayed.': 'This is the automatic behavior when the menu is always displayed.' +'Not compatible with touch screens.': 'Not compatible with touch screens.' +'Big menu': 'Big menu' +'Live preview': 'Live preview' +'Open apps in new tab': 'Open apps in new tab' +'Use the global setting': 'Use the global setting' +'Use my selection': 'Use my selection' +'Show and hide the list of applications': 'Show and hide the list of applications' +'Use the avatar instead of the logo': 'Use the avatar instead of the logo' +'You do not have permission to change the settings.': 'You do not have permission to change the settings.' +'Force this configuration to users': 'Force this configuration to users' +'Export the configuration': 'Export the configuration' +'Purge the cache': 'Purge the cache' +'Show the link to settings': 'Show the link to settings' +'The menu is enabled by default for users': 'The menu is enabled by default for users' +'Except when the configuration is forced.': 'Except when the configuration is forced.' +'Apps that should not be displayed in the menu': 'Apps that should not be displayed in the menu' +'This feature is only compatible with the big menu display.': 'This feature is only compatible with the big menu display.' +'The logo is a link to the default app': 'The logo is a link to the default app' +'Others': 'Others' +'Categories': 'Categories' +'Customize sorting': 'Customize sorting' +'Order by': 'Order by' +'Name': 'Name' +'Customed': 'Customed' +'Show and hide the list of categories': 'Show and hide the list of categories' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': 'This parameters are used when Dark theme or Breeze Dark Theme are enabled.' +'Dark mode colors': 'Dark mode colors' +'With categories': 'With categories' +'Custom categories': 'Custom categories' +'Customize application categories': 'Customize application categories' +'Reset to default': 'Reset to default' +'Applications': 'Applications' +'Applications kept in the top menu': 'Applications kept in the top menu' +'Applications kept in the top menu but also shown in side menu': 'Applications kept in the top menu but also shown in side menu' +'These applications must be selected in the previous option.': 'These applications must be selected in the previous option.' +'Hide labels on mouse over': 'Hide labels on mouse over' +'Except the hovered app': 'Except the hovered app' +'Search': 'Search' +'Toggle the menu': 'Toggle the menu' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/l10n/fixtures/zh_CN.yaml b/src/l10n/fixtures/zh_CN.yaml index 2f544b6..b6a1cb1 100644 --- a/src/l10n/fixtures/zh_CN.yaml +++ b/src/l10n/fixtures/zh_CN.yaml @@ -1,96 +1,111 @@ -"Custom menu": "自定义菜单" -"Enable the custom menu": "激活自定义菜单" -"No": "取消" -"Yes": "确定" -"Menu": "菜单" -? "Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate." -: "使用快捷键 Ctrl+o 打开或隐藏侧边栏菜单。使用tab 来导航。" -"Top menu": "顶部菜单" -"Apps that not must be moved in the side menu": "禁止在侧边栏菜单移动的应用" -"If there is no selection then the global configuration is applied.": "如不选择,将应用全局设定。" -"Experimental": "实验性" -"Save": "保存" -"You like this app and you want to support me?": "喜欢本应用并支持我一下?" -"Buy me a coffee ☕": "赏一杯咖啡 ☕ 给我" -"Hidden": "隐藏" -"Small": "小型" -"Normal": "标准" -"Big": "大型" -"Colors": "颜色" -"Background color": "背景颜色" -"Background color of current app": "当前应用的背景色" -"Text color": "文字颜色" -"Loader": "菜单指示器" -"Icon": "图标" -"Same color": "相同颜色" -"Opposite color": "相反颜色" -"Transparent": "透明" -"Opaque": "不透明" -"Opener": "容器" -"Default": "默认" -"Default (dark)": "默认(深色)" -"Hamburger": "Hamburger" -"Hamburger (dark)": "Hamburger (深色)" -"Hamburger 2": "Hamburger 2" -"Hamburger 2 (dark)": "Hamburger 2 (深色)" -"Before the logo": "在logo前" -"After the logo": "在logo后" -"Position": "位置" -"Show only the opener (hidden logo)": "只显示容器 (隐藏logo)" -"Do not display the side menu and the opener if there is no application (eg: public pages).": "N如果没有应用,不显示侧边栏菜单和容器 (例如 : 公共页面)。" -"Panel": "面板" -"Open the menu when the mouse is hover the opener (automatically disabled on touch screens)": "鼠标悬停时打开菜单 (触摸屏时将自动禁用)" -"Display the big menu": "显示大型菜单" -"Display the logo": "显示logo" -"Icons and texts": "图标与文字" -"Loader enabled": "菜单指示器已激活" -"Tips": "技巧" -"Always displayed": "一直显示" -"This is the automatic behavior when the menu is always displayed.": "一直显示菜单时的自动动作。" -"Not compatible with touch screens.": "与触屏不兼容。" -"Big menu": "大型菜单" -"Live preview": "实时预览" -"Open apps in new tab": "在新标签中打开应用" -"Use the global setting": "使用全局设定" -"Use my selection": "使用自定义设定" -"Show and hide the list of applications": "显示或隐藏应用列表" -"Use the avatar instead of the logo": "使用头像代替logo" -"You do not have permission to change the settings.": "没有更改设置的权限。" -"Force this configuration to users": "强制用户使用此设置" -"Export the configuration": "导出设置" -"Purge the cache": "清除缓存" -"Show the link to settings": "显示设置链接" -"The menu is enabled by default for users": "用户的默认菜单已激活" -"Except when the configuration is forced.": "除非设置被强制使用。" -"Apps that should not be displayed in the menu": "禁止在菜单中显示的应用" -"This feature is only compatible with the big menu display.": "此功能只和大型菜单兼容。" -"The logo is a link to the default app": "logo链接到默认应用" -"Others": "其他" -"Categories": "类别" -"Customize sorting": "自定义顺序" -"Order by": "排序规则" -"Name": "名称" -"Customed": "自定义" -"Show and hide the list of categories": "显示或隐藏类别列表" -"This parameters are used when Dark theme or Breeze Dark Theme are enabled.": "此参数将应用于暗黑主题激活时。" -"Dark mode colors": "暗黑模式颜色" -"With categories": "有类别" -"Custom categories": "自定义类别" -"Customize application categories": "自定义应用程序类别" -"Reset to default": "重置为默认设置" -"Hidden icon": "隐藏图标" -"Small icon": "小图标" -"Normal icon": "正常图标" -"Big icon": "大图标" -"Hidden text": "隐藏文字" -"Small text": "小文本" -"Normal text": "普通文本" -"Big text": "大文本" -"Applications": "Applications" -"Applications kept in the top menu": "Applications kept in the top menu" -"Applications kept in the top menu but also shown in side menu": "Applications kept in the top menu but also shown in side menu" -"These applications must be selected in the previous option.": "These applications must be selected in the previous option." -"Hide labels on mouse over": "Hide labels on mouse over" -"Except the hovered app": "Except the hovered app" -"Search": "Search" -"Toggle menu": "Toggle menu" +'Custom menu': '自定义菜单' +'Enable the custom menu': '启用自定义菜单' +'No': '取消' +'Yes': '确定' +'Menu': '菜单' +'Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.': '使用快捷键 Ctrl+o 打开或隐藏侧边栏菜单。使用tab 来导航。' +'Top menu': '顶部菜单' +'Apps that not must be moved in the side menu': '禁止在侧边栏菜单移动的应用' +'If there is no selection then the global configuration is applied.': '如果没有选择,则应用全局配置。' +'Experimental': '实验性' +'Save': '保存' +'You like this app and you want to support me?': '喜欢本应用并支持我一下?' +'Buy me a coffee ☕': '赏一杯咖啡 ☕ 给我' +'Hidden': '隐藏' +'Small': '小型' +'Normal': '标准' +'Big': '大型' +'Colors': '颜色' +'Background color': '背景颜色' +'Background color of current app': '当前应用的背景色' +'Text color': '文本颜色' +'Loader': '菜单指示器' +'Icon': '图标' +'Same color': '相同颜色' +'Opposite color': '相反颜色' +'Transparent': '透明' +'Opaque': '不透明' +'Opener': '容器' +'Default': '默认' +'Default (dark)': '默认(深色)' +'Hamburger': 'Hamburger' +'Hamburger (dark)': 'Hamburger (深色)' +'Hamburger 2': 'Hamburger 2' +'Hamburger 2 (dark)': 'Hamburger 2 (深色)' +'Before the logo': '在徽标之前' +'After the logo': '在徽标之后' +'Position': '位置' +'Show only the opener (hidden logo)': '只显示容器(隐藏徽标)' +'Do not display the side menu and the opener if there is no application (eg: public pages).': '如果没有应用程序(例如:公共页面),则不要显示侧边栏菜单和容器。' +'Panel': '面板' +'Open the menu when the mouse is hover the opener (automatically disabled on touch screens)': '鼠标悬停时打开菜单 (触摸屏时将自动禁用)' +'Display the big menu': '显示大型菜单' +'Display the logo': '显示徽标' +'Icons and texts': '图标和文本' +'Loader enabled': '菜单指示器已启用' +'Tips': '技巧' +'Always displayed': '始终显示' +'This is the automatic behavior when the menu is always displayed.': '这是菜单始终显示时的自动行为。' +'Not compatible with touch screens.': '与触摸屏不兼容。' +'Big menu': '大型菜单' +'Live preview': '实时预览' +'Open apps in new tab': '在新标签页中打开应用' +'Use the global setting': '使用全局设置' +'Use my selection': '使用自定义设置' +'Show and hide the list of applications': '显示和隐藏应用程序列表' +'Use the avatar instead of the logo': '使用头像代替徽标' +'You do not have permission to change the settings.': '您没有更改设置的权限。' +'Force this configuration to users': '强制用户使用此配置' +'Export the configuration': '导出配置' +'Purge the cache': '清除缓存' +'Show the link to settings': '显示设置链接' +'The menu is enabled by default for users': '默认情况下为用户启用菜单' +'Except when the configuration is forced.': '除非强制配置。' +'Apps that should not be displayed in the menu': '禁止在菜单中显示的应用' +'This feature is only compatible with the big menu display.': '此功能只和大型菜单兼容。' +'The logo is a link to the default app': 'logo链接到默认应用' +'Others': '其他' +'Categories': '类别' +'Customize sorting': '自定义排序' +'Order by': '排序方式' +'Name': '名称' +'Customed': '自定义' +'Show and hide the list of categories': '显示或隐藏类别列表' +'This parameters are used when Dark theme or Breeze Dark Theme are enabled.': '启用深色主题时使用此参数。' +'Dark mode colors': '深色模式颜色' +'With categories': '按类别' +'Custom categories': '自定义类别' +'Customize application categories': '自定义应用程序类别' +'Reset to default': '重置为默认设置' +'Hidden icon': '隐藏图标' +'Small icon': '小图标' +'Normal icon': '正常图标' +'Big icon': '大图标' +'Hidden text': '隐藏文本' +'Small text': '小文本' +'Normal text': '普通文本' +'Big text': '大文本' +'Applications': 'Applications' +'Applications kept in the top menu': 'Applications kept in the top menu' +'Applications kept in the top menu but also shown in side menu': 'Applications kept in the top menu but also shown in side menu' +'These applications must be selected in the previous option.': 'These applications must be selected in the previous option.' +'Hide labels on mouse over': 'Hide labels on mouse over' +'Except the hovered app': 'Except the hovered app' +'Search': 'Search' +'Toggle menu': 'Toggle menu' +'Open the documentation': 'Open the documentation' +'Ask the developer': 'Ask the developer' +'New request': 'New request' +'Report a bug': 'Report a bug' +'Show the configuration': 'Show the configuration' +'Configuration:': 'Configuration:' +'Done!': 'Done!' +'Copy': 'Copy' +'Need help': 'Need help' +'I would like a new feature': 'I would like a new feature' +'Something went wrong': 'Something went wrong' +'Select apps': 'Select apps' +'Sort': 'Sort' +'Customize': 'Customize' +'Custom': 'Custom' +'Close': 'Close' diff --git a/src/lib/app.js b/src/lib/app.js new file mode 100644 index 0000000..bf012e0 --- /dev/null +++ b/src/lib/app.js @@ -0,0 +1,32 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { loadState } from '@nextcloud/initial-state' + +const getActiveAppId = () => { + const apps = loadState('core', 'apps', {}) + + for (let id in apps) { + if (apps[id].active) { + return apps[id].id + } + } + + return null +} + +export { getActiveAppId } diff --git a/src/lib/createElement.js b/src/lib/createElement.js deleted file mode 100644 index 9be7ff4..0000000 --- a/src/lib/createElement.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = (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 -} diff --git a/src/lib/dom.js b/src/lib/dom.js new file mode 100644 index 0000000..b03ce5e --- /dev/null +++ b/src/lib/dom.js @@ -0,0 +1,54 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +const waitContainer = async (selector) => { + return new Promise((resolve) => { + const execute = () => { + const container = document.querySelector(selector) + + if (container) { + resolve(container) + } else { + setTimeout(() => { + execute(selector) + }, 50) + } + } + + execute(selector) + }) +} + +const createElement = (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 +} + +export { waitContainer, createElement } diff --git a/src/lib/menu.js b/src/lib/menu.js new file mode 100644 index 0000000..6153682 --- /dev/null +++ b/src/lib/menu.js @@ -0,0 +1,28 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +const focusActiveApp = (menu) => { + window.setTimeout(() => { + const a = menu.querySelector('.side-menu-app.active a') || menu.querySelector('.side-menu-app a') + + if (a) { + a.focus() + } + }, 500) +} + +export { focusActiveApp } diff --git a/src/lib/search.js b/src/lib/search.js new file mode 100644 index 0000000..033dfd6 --- /dev/null +++ b/src/lib/search.js @@ -0,0 +1,40 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +const containsAppsMatchingSearch = (values, search) => { + if (search.trim() === '') { + return true + } + + for (let key in values) { + if (isAppMatchingSearch(values[key], search)) { + return true + } + } + + return false +} + +const isAppMatchingSearch = (item, search) => { + if (search.trim() === '') { + return true + } + + return item.name.toLowerCase().includes(search.trim().toLowerCase()) +} + +export { containsAppsMatchingSearch, isAppMatchingSearch } diff --git a/src/lib/setting.js b/src/lib/setting.js new file mode 100644 index 0000000..f69ee60 --- /dev/null +++ b/src/lib/setting.js @@ -0,0 +1,26 @@ +const waitPasswordConfirmation = async () => { + let tries = 0 + + return new Promise((resolve, reject) => { + const execute = () => { + if (!OC.PasswordConfirmation.requiresPasswordConfirmation()) { + resolve() + return + } + + OC.PasswordConfirmation.requirePasswordConfirmation(() => {}) + + if (++tries !== 10) { + setTimeout(() => { + execute() + }, 2000) + } else { + reject() + } + } + + execute() + }) +} + +export { waitPasswordConfirmation } diff --git a/src/menu.js b/src/menu.js new file mode 100644 index 0000000..7a92f62 --- /dev/null +++ b/src/menu.js @@ -0,0 +1,52 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import './scss/menu.scss' + +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import { createElement, waitContainer } from './lib/dom.js' + +import StandardMenu from './menus/StandardMenu' +import MenuContainer from './menus/MenuContainer' + +const pinia = createPinia() +const body = document.querySelector('body') +const container = createElement('div', { + id: 'side-menu-container', +}) + +body.appendChild(container) + +const app = createApp(MenuContainer) +app.use(pinia) +app.mixin({ methods: { t, n } }) +app.mount(container) + +waitContainer('#header .app-menu').then((container) => { + const menu = createElement('div', { + id: 'app-menu-container', + }) + + container.parentNode.insertBefore(menu, container.nextSibling) + container.remove() + + const app = createApp(StandardMenu) + app.use(pinia) + app.mixin({ methods: { t, n } }) + app.mount(menu) +}) diff --git a/src/menus/MenuContainer.vue b/src/menus/MenuContainer.vue new file mode 100644 index 0000000..ba44f97 --- /dev/null +++ b/src/menus/MenuContainer.vue @@ -0,0 +1,139 @@ + + + + diff --git a/src/menus/SideMenuWithCategories.vue b/src/menus/SideMenuWithCategories.vue new file mode 100644 index 0000000..eb8ae1f --- /dev/null +++ b/src/menus/SideMenuWithCategories.vue @@ -0,0 +1,132 @@ + + + + diff --git a/src/menus/SimpleSideMenu.vue b/src/menus/SimpleSideMenu.vue new file mode 100644 index 0000000..65d0fa4 --- /dev/null +++ b/src/menus/SimpleSideMenu.vue @@ -0,0 +1,176 @@ + + + + diff --git a/src/menus/StandardMenu.vue b/src/menus/StandardMenu.vue new file mode 100644 index 0000000..5e817ee --- /dev/null +++ b/src/menus/StandardMenu.vue @@ -0,0 +1,185 @@ + + + + + + diff --git a/src/menus/TopWideMenu.vue b/src/menus/TopWideMenu.vue new file mode 100644 index 0000000..596b1ea --- /dev/null +++ b/src/menus/TopWideMenu.vue @@ -0,0 +1,137 @@ + + + + diff --git a/src/pages/AdminSettings.vue b/src/pages/AdminSettings.vue new file mode 100644 index 0000000..d3c7c84 --- /dev/null +++ b/src/pages/AdminSettings.vue @@ -0,0 +1,627 @@ + + + + diff --git a/src/pages/UserSettings.vue b/src/pages/UserSettings.vue new file mode 100644 index 0000000..d3a7dfb --- /dev/null +++ b/src/pages/UserSettings.vue @@ -0,0 +1,170 @@ + + + + + + diff --git a/src/scss/admin.scss b/src/scss/admin.scss new file mode 100644 index 0000000..0cd332c --- /dev/null +++ b/src/scss/admin.scss @@ -0,0 +1,262 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +.cm-settings { + &--nav { + padding-top: 30px; + } + + &-nav { + .app-navigation__content { + padding: 20px; + } + + .app-navigation-entry-icon { + display: none !important; + } + + .app-navigation-entry__name { + padding-left: 10px !important; + } + } + + &-tips { + margin-bottom: 15px; + } + + &-section { + width: 100%; + padding: 20px; + + &--hidden { + display: none; + } + } + + &-item { + display: flex; + justify-content: start; + margin-bottom: 10px; + + &--disabled { + opacity: 0.5; + } + + &-label { + max-width: 350px; + width: 100%; + padding-right: 20px; + + &--short { + max-width: 300px; + } + + &--top { + vertical-align: top; + } + + &--middle { + display: flex; + flex-direction: column; + text-align: left; + } + } + + &-form { + } + } + + &-form { + &-arrow { + color: var(--color-text-maxcontrast); + display: inline-block; + margin-right: 3px; + } + + &-draggable { + cursor: pointer; + padding: 8px 12px; + border-bottom: 1px solid var(--color-border); + } + + &-displaypicker { + img { + padding: 10px 10px 10px 0; + border: 2px solid transparent; + max-width: 100%; + cursor: pointer; + } + } + + &-colorpicker { + display: inline-block; + margin-right: 12px; + width: 60px; + height: 30px; + + &-value { + cursor: pointer; + width: 60px; + height: 30px; + border-radius: 6px; + border: 1px solid var(--color-border); + } + } + + &-range { + input { + min-height: auto; + } + + div * { + vertical-align: middle; + } + + em + input, + input + em { + margin-left: 10px; + } + } + + &-catsort-modal { + .modal__footer { + padding: 20px; + text-align: right; + } + + .modal__footer button { + display: inline-block; + } + } + + &-appsort-modal { + .modal__footer { + text-align: right; + padding: 20px; + } + + .modal__footer button { + display: inline-block; + } + } + + &-apppicker-modal { + .modal__content { + padding: 20px; + } + + .modal__footer { + margin-top: 20px; + text-align: right; + } + + .modal__footer button { + display: inline-block; + } + + img { + width: 15px; + height: 15px; + } + } + + &-appcategory-modal { + .modal__content { + padding: 20px; + } + + .menu button { + display: inline-block; + margin-right: 5px; + } + + .modal__footer { + margin-top: 20px; + text-align: right; + } + + .modal__footer button { + display: inline-block; + } + + td { + padding: 5px 0; + } + + tr:hover, + td:hover { + background: none !important; + } + + .form { + padding: 10px 0; + } + + img { + width: 15px; + height: 15px; + } + + .btn-close { + margin-left: 20px; + } + } + } + + &-btn { + &--save { + margin-top: 30px; + } + } + + &-config-modal { + textarea { + width: 100%; + height: 30vh; + } + + .modal__content { + padding: 20px; + } + + .modal__footer { + margin-top: 20px; + text-align: right; + } + + .modal__footer button { + display: inline-block; + margin-right: 5px; + } + } + + &-children-inline { + > * { + display: inline-block !important; + margin-right: 5px; + margin-bottom: 5px; + } + } + + &-button-inline { + .button-vue { + display: inline-block !important; + margin-right: 5px; + margin-bottom: 5px; + } + } +} diff --git a/src/scss/menu.scss b/src/scss/menu.scss new file mode 100644 index 0000000..097c002 --- /dev/null +++ b/src/scss/menu.scss @@ -0,0 +1,601 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#header { + .cm-opener { + margin-left: 0px; + margin-top: 0px; + } +} + +.app-menu { + visibility: hidden; +} + +.cm { + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100%; + max-width: 290px; + background: linear-gradient(90deg, var(--side-menu-background-color, #333) 0%, var(--side-menu-background-color-to, #333) 100%); + z-index: 3000; + color: var(--side-menu-text-color, #fff); + box-shadow: + 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; + + &-opener { + background: var(--side-menu-opener, url('../../img/side-menu-opener.svg')); + background-color: transparent !important; + height: 40px !important; + width: 40px !important; + border-radius: 0 !important; + border: 0 !important; + padding-right: 12px !important; + padding-left: 12px !important; + margin-top: 1px !important; + margin-left: 5px !important; + margin-left: 3px !important; + overflow: hidden; + + span { + position: relative; + left: 50px; + display: block; + width: 1px; + height: 1px; + overflow: hidden; + } + + &:active, + &:focus { + background-color: var(--side-menu-current-app-background-color, #444) !important; + } + } + + &-closer { + background: url('../../img/side-menu-opener-closer.svg'); + display: none; + } + + a { + transition: 0.2s; + } + + &-categories-wrapper { + padding-bottom: 70px; + } + + &-search { + float: right; + + input { + background: none; + border: 0; + border-radius: 0; + color: var(--side-menu-text-color); + + &::placeholder { + color: var(--side-menu-text-color); + } + } + } + + &-categories { + max-height: calc(100vh - 55px); + overflow: auto; + position: relative; + display: flex; + flex-wrap: wrap; + justify-content: center; + padding: 0 10% 0 10%; + } + + &-category { + padding: 10px 20px; + flex: 1 1 auto; + + &-title { + padding-left: 10px; + color: var(--side-menu-text-color, #fff); + font-weight: bold; + font-size: 20px; + margin-bottom: 12px; + line-height: 30px; + margin-top: 0; + } + } + + &-header { + width: 100%; + z-index: 2300; + max-width: 290px; + padding-top: 2px; + top: 0; + + &::after { + content: ' '; + display: block; + clear: both; + } + } + + &-loader { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 3001; + + &-bar { + height: 4px; + background: var(--side-menu-loader-color, #0e75ac); + width: 0; + transition-property: width; + } + } + + &-apps { + height: calc(100vh - 49px); + top: 49px; + z-index: 2200; + position: fixed; + width: 100%; + max-width: 290px; + overflow: auto; + + &.side-menu-apps-list--with-logo { + height: calc(100vh - 160px); + top: 160px; + } + } + + &-app { + a { + line-height: 30px; + color: var(--side-menu-text-color, #fff); + display: block; + padding: 7px 0 5px 13px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + a:hover, + a:focus, + &:active, + &.active { + background: var(--side-menu-current-app-background-color, #444); + } + + &-icon { + width: 20px; + vertical-align: middle; + margin-top: -4px; + margin-right: 10px; + filter: invert(var(--side-menu-icon-invert-filter, 0%)); + opacity: var(--side-menu-icon-opacity, 1); + } + } + + &-setting { + margin-right: 9px; + margin-top: 2px; + float: right; + line-height: 34px; + height: 42px; + display: none; + + a { + color: var(--side-menu-text-color, #fff); + display: block; + padding: 4px 7px; + } + + &:hover a, + a:active, + a:focus { + background: var(--side-menu-current-app-background-color, #444); + } + + img { + vertical-align: bottom; + margin-left: 3px; + width: 32px; + height: 32px; + } + } + + &.open { + display: block; + + .cm-setting { + display: block; + } + } + + &-logo { + text-align: center; + clear: both; + + img { + max-width: 60%; + max-height: 100px; + } + } + + &--topwidemenu { + max-width: 100%; + height: auto; + } + + &--sidemenuwithcategories { + max-width: 290px; + height: 100vh; + + .cm-categories { + display: block; + padding: 0; + width: 100%; + } + + .cm-category { + padding: 10px 0; + } + + .cm-header { + max-width: 295px; + } + } + + &.cm--topwidemenu, + &.cm--sidemenuwithcategories { + .cm-apps { + height: auto !important; + position: static !important; + max-width: 100vw !important; + overflow: auto !important; + } + + .cm-app { + a { + padding: 7px 0 7px 7px; + } + + &-icon { + vertical-align: middle; + margin-top: -2px; + } + } + } +} + +.cm-standardmenu { + visibility: hidden; + + &.show { + visibility: visible; + } +} + +.cm-always-displayed { + body { + width: calc(100% - 50px) !important; + position: absolute; + left: 50px; + } + + #header { + position: absolute !important; + + .cm-opener { + display: none; + } + } + + .cm { + display: block; + width: 50px; + + &-apps { + height: calc(100vh - 49px); + width: 50px; + top: 49px; + + &:hover { + overflow: auto; + } + } + + &-header { + height: 49px; + width: 50px; + } + + &-logo { + display: none; + } + + &-app { + &-text { + display: none; + } + } + + &.open { + width: 100%; + max-width: 290px; + + .cm-apps { + width: 100%; + } + + .cm-app { + &-text { + display: inline; + } + } + + .cm-header { + width: 100%; + } + } + } + + .app-navigation-toggle-wrapper { + right: 0 !important; + margin-left: 0 !important; + } +} + +@media screen and (max-width: 1024px) { + .cm { + &--topwidemenu { + max-width: 290px; + height: 100vh; + + .cm-header { + max-width: 100%; + } + } + + &-categories { + display: block; + padding: 0; + } + + &-category { + padding: 10px 0; + } + } +} + +@media screen and (min-width: 1024px) { + .cm { + &--topwidemenu { + .cm-header { + max-width: 100%; + } + } + + &-closer { + display: block; + float: right; + margin-right: 9px; + } + } +} + +$header-icon-size: 20px; + +.cm-standardmenu { + width: 100%; + display: flex; + flex-shrink: 1; + flex-wrap: wrap; + + .app-menu-main { + display: flex; + flex-wrap: nowrap; + + .app-menu-entry { + width: 50px; + height: 50px; + position: relative; + display: flex; + + &.app-menu-entry__active { + opacity: 1; + + &::before { + content: ' '; + position: absolute; + pointer-events: none; + border-bottom-color: var(--color-main-background); + transform: translateX(-50%); + width: 12px; + height: 5px; + border-radius: 3px; + background-color: var(--color-primary-text); + left: 50%; + bottom: 6px; + display: block; + transition: all 0.1s ease-in-out; + opacity: 1; + } + + .app-menu-entry--label { + font-weight: bold; + } + } + + a { + width: calc(100% - 4px); + height: calc(100% - 4px); + margin: 2px; + color: var(--color-primary-text); + position: relative; + } + + img { + transition: margin 0.1s ease-in-out; + width: $header-icon-size; + height: $header-icon-size; + padding: calc((100% - $header-icon-size) / 2); + box-sizing: content-box; + filter: var(--background-image-invert-if-bright, var(--primary-invert-if-bright)); + } + + .app-menu-entry--label { + opacity: 0; + position: absolute; + font-size: 12px; + color: var(--color-primary-text); + text-align: center; + left: 50%; + top: 45%; + display: block; + min-width: 100%; + transform: translateX(-50%); + transition: all 0.1s ease-in-out; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + letter-spacing: -0.5px; + } + + &:not(.app-menu-entry__hidden-label):not(.app-menu-entry__show-hovered):hover, + &:not(.app-menu-entry__hidden-label):not(.app-menu-entry__show-hovered):focus-within { + opacity: 1; + .app-menu-entry--label { + opacity: 1; + font-weight: bolder; + bottom: 0; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + } + } + } + + // Show labels + &:hover, + &:focus-within, + .app-menu-entry:hover, + .app-menu-entry:focus { + opacity: 1; + } + + &:not(.app-menu-main__hidden-label):not(.app-menu-main__show-hovered):hover, + &:not(.app-menu-main__hidden-label):not(.app-menu-main__show-hovered):focus-within, + .app-menu-entry:not(.app-menu-entry__hidden-label):hover, + .app-menu-entry:not(.app-menu-entry__hidden-label):focus { + opacity: 1; + + img { + margin-top: -8px; + } + + .app-menu-entry--label { + opacity: 1; + bottom: 0; + } + + &::before, + .app-menu-entry::before { + opacity: 0; + } + } + + &.app-menu-main__show-hovered .app-menu-entry:hover, + &.app-menu-main__show-hovered .app-menu-entry:focus { + img { + margin-top: -8px; + } + + .app-menu-entry--label { + opacity: 1; + bottom: 0; + } + + &::before, + .app-menu-entry::before { + opacity: 0; + } + } + } + + .app-menu-more .button-vue--vue-tertiary { + opacity: 0.7; + margin: 8px 3px 3px 3px; + filter: var(--background-image-invert-if-bright, var(--primary-invert-if-bright)); + + &:not([aria-expanded='true']) { + color: var(--color-main-text); + + &:hover { + opacity: 1; + background-color: transparent !important; + } + } + + &:focus-visible { + opacity: 1; + outline: none !important; + } + } + + &-app-menu-popover-entry { + .app-icon { + position: relative; + height: 35px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + filter: var(--background-invert-if-bright, var(--primary-invert-if-bright)); + + &.has-unread::after { + background-color: var(--color-main-text); + } + + img { + width: $header-icon-size; + height: $header-icon-size; + } + } + } + + .has-unread::after { + content: ''; + width: 8px; + height: 8px; + background-color: var(--color-primary-element-text); + border-radius: 50%; + position: absolute; + display: block; + top: 10px; + right: 10px; + } + + .unread-counter { + display: none; + } +} diff --git a/src/store/config.js b/src/store/config.js new file mode 100644 index 0000000..65540be --- /dev/null +++ b/src/store/config.js @@ -0,0 +1,56 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { defineStore } from 'pinia' +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +export const useConfigStore = defineStore('config', () => { + let config = null + let appConfig = null + let userConfig = null + + async function getConfig() { + if (config === null) { + config = await axios.get(generateUrl('/apps/side_menu/js/config')).then((response) => response.data) + } + + return config + } + + async function getAppConfig() { + if (appConfig === null) { + appConfig = await axios.get(generateUrl('/apps/side_menu/admin/config')).then((response) => response.data) + } + + return appConfig + } + + async function getUserConfig() { + if (userConfig === null) { + userConfig = await axios.get(generateUrl('/apps/side_menu/user/config')).then((response) => response.data) + } + + return userConfig + } + + return { + getConfig, + getAppConfig, + getUserConfig, + } +}) diff --git a/src/store/nav.js b/src/store/nav.js new file mode 100644 index 0000000..03a128e --- /dev/null +++ b/src/store/nav.js @@ -0,0 +1,66 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { defineStore } from 'pinia' +import axios from '@nextcloud/axios' +import { generateUrl, generateOcsUrl } from '@nextcloud/router' + +export const useNavStore = defineStore('nav', () => { + let categories = null + let apps = null + let coreApps = null + + async function getApps() { + if (apps === null) { + apps = [] + const cats = await getCategories() + + cats.forEach((category) => { + Object.values(category.apps).forEach((app) => { + apps.push(app) + }) + }) + } + + return apps + } + + async function getCoreApps() { + if (coreApps == null) { + coreApps = await axios + .get(generateOcsUrl('core/navigation', 2) + '/apps?format=json') + .then((response) => response.data) + .then((value) => value.ocs.data) + } + + return coreApps + } + + async function getCategories() { + if (categories === null) { + categories = await axios.get(generateUrl('/apps/side_menu/nav/items')).then((response) => response.data.items) + } + + return categories + } + + return { + getApps, + getCoreApps, + getCategories, + } +}) diff --git a/src/user.js b/src/user.js new file mode 100644 index 0000000..0f4b27a --- /dev/null +++ b/src/user.js @@ -0,0 +1,32 @@ +/** + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import './scss/admin.scss' + +import { createApp } from 'vue' +import { createPinia } from 'pinia' +import { waitContainer } from './lib/dom.js' + +import UserSettings from './pages/UserSettings' + +waitContainer('#side-menu-user-settings').then((selector) => { + const pinia = createPinia() + const app = createApp(UserSettings) + app.use(pinia) + app.mixin({ methods: { t, n } }) + app.mount(selector) +}) diff --git a/templates/css/stylesheet.php b/templates/css/stylesheet.php index 5638629..969f17a 100644 --- a/templates/css/stylesheet.php +++ b/templates/css/stylesheet.php @@ -1,125 +1,124 @@ + $value) { + echo sprintf( + "--side-menu-%s: %s;\n", + $key, + 'opener' === $key + ? sprintf('url("%s")', image_path('side_menu', $value.'.svg')) + : $value + ); + } +} +?> + :root { - $value): ?> - - --side-menu-: url(''); - - --side-menu-: ; - - + } - - #appmenu { - display: none; +@media (prefers-color-scheme: light) { + :root { + } +} - #appmenu + nav { - display: none; - } - - .app-hidden { - opacity: 0; - } - +@media (prefers-color-scheme: dark) { + +} - +body[data-theme-dark], body[data-theme-dark-highcontrast] { + +} + +body[data-theme-light], body[data-theme-light-highcontrast] { + +} + + #nextcloud { display: none; } - + - - .side-menu-logo { + + .cm-apps { + + width: 55px; + + width: 52px; + + } + + .cm .cm-opener { + + margin-left: 1px; + + margin-left: 0px; + + } + + + + .cm-app-icon { display: none; } - - .side-menu-header { - height: 50px; - } - - .side-menu-apps-list { - height: calc(100vh - 49px); - top: 49px; - } - - #side-menu.hide-opener .side-menu-header .side-menu-opener.side-menu-closer { - visibility: hidden; - } - - #side-menu.hide-opener.side-menu-with-categories .side-menu-search { - float: none; - } - - - #side-menu, .side-menu-apps-list { - - width: 55px; - - width: 52px; - - } - - #side-menu .side-menu-opener { - - margin-left: 1px; - - margin-left: 0px; - - } - - - - - .side-menu-app-icon { - display: none; - } - - .side-menu-app-icon svg { + + .cm-app-icon svg { width: 15px; height: 15px; } - img.side-menu-app-icon { + img.cm-app-icon { width: 15px; height: 15px; } - - .side-menu-app-icon svg { + + .cm-app a { + padding-left: 16px !important; + } + + .cm-app-icon svg { width: 20px; height: 20px; } - img.side-menu-app-icon { + img.cm-app-icon { width: 20px; height: 20px; } - - .side-menu-app-icon svg { + + .cm-app-icon svg { width: 23px; height: 23px; } - img.side-menu-app-icon { + img.cm-app-icon { width: 23px; height: 23px; } - - - .side-menu-app-text { + .cm-app a { + padding-left: 11px !important; + } + + + + .cm-app-text { display: none; } - - .side-menu-app-text { + + .cm-app-text { font-size: 12px; } - - .side-menu-app-text { + + .cm-app-text { font-size: 16px; } - + - + #content { left: 53px; width: calc(100% - (var(--body-container-margin) * 2) - 62px); @@ -129,4 +128,4 @@ width: calc(100% - (var(--body-container-margin) * 2) - 60px); margin-left: 11px; } - + diff --git a/templates/js/script.php b/templates/js/script.php deleted file mode 100644 index f623d8f..0000000 --- a/templates/js/script.php +++ /dev/null @@ -1,204 +0,0 @@ - - -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') - - if (a) { - a.focus() - } - } - - 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') { - return - } - - body.classList.toggle('body-settings-side-menu', sideMenu.classList.contains('open')) - }) - - sideMenuObserver.observe(sideMenu, { - attributes: true, - attributeFilter: ['class'], - childList: false, - 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) - - } -})(); diff --git a/templates/settings/admin-form.php b/templates/settings/admin-form.php index 1053b04..9666f08 100644 --- a/templates/settings/admin-form.php +++ b/templates/settings/admin-form.php @@ -20,1130 +20,7 @@ use OCP\IURLGenerator; use OCP\IConfig; use OCA\SideMenu\AppInfo\Application; -vendor_script('side_menu', 'html5sortable.min'); -script('side_menu', 'admin'); -style('side_menu', 'admin'); - -$urlGenerator = \OC::$server[IURLGenerator::class]; -$cacheSize = floor(mb_strlen(\OC::$server[IConfig::class]->getAppValue(Application::APP_ID, 'cache-categories', ''), '8bit') / 1024); - -$choicesYesNo = [ - 'No' => '0', - 'Yes' => '1', -]; - -$choicesSizes = [ - 'Hidden' => 'hidden', - 'Small' => 'small', - 'Normal' => 'normal', - 'Big' => 'big', -]; - -$labelShowHideApps = 'Show and hide the list of applications'; -$labelReset = 'Reset to default'; -$labelDefault = 'Default'; -$labelWithCategories = 'With categories'; -$labelBigMenu = 'Big menu'; -$labelAlwaysDisplayed = 'Always displayed'; - +script('side_menu', 'side_menu-admin'); ?> -
-
-

- t('Panel')); ?> -

- - !$_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'always-displayed' => $_['always-displayed'] && !$_['big-menu'] && !$_['side-with-categories'], - 'side-with-categories' => $_['side-with-categories'] && !$_['always-displayed'] && !$_['big-menu'], - 'big-menu' => $_['big-menu'] && !$_['always-displayed'] && !$_['side-with-categories'], - ]; - ?> - -
- -
-

- <?php p($l->t($labelDefault)); ?> -

- -
- -
-

- <?php p($l->t($labelWithCategories)); ?> -

- -
- -
-

- <?php p($l->t($labelBigMenu)); ?> -

- -
- -
-

t('Not compatible with touch screens.')); ?>

-

- <?php p($l->t($labelAlwaysDisplayed)); ?> -

- - - - -
- -
-

- t('Colors')); ?> - - t('Live preview')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Background color')); ?> -
-
- - - -
-
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
- -
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
- -

- t('Dark mode colors')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('This parameters are used when Dark theme or Breeze Dark Theme are enabled.'); ?> -

- -
-
-
- t('Background color')); ?> -
-
- - - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
-
-
- t('Background color of current app')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Text color')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Loader')); ?> -
-
- - -
-
-
-
- -
-
-
- t('Icon')); ?> -
-
-
- - t('Same color')); ?> - - - - - - t('Opposite color')); ?> - -
- -
- - t('Transparent')); ?> - - - - - - t('Opaque')); ?> - -
-
-
-
- -
- 'side-menu-opener', - 'Default (dark)' => 'side-menu-opener-dark', - 'Hamburger' => 'side-menu-opener-hamburger', - 'Hamburger (dark)' => 'side-menu-opener-hamburger-dark', - 'Hamburger 2' => 'side-menu-opener-hamburger-2', - 'Hamburger 2 (dark)' => 'side-menu-opener-hamburger-2-dark', - ]; - ?> -
-
- t('Icon')); ?> -
-
- -
-
-
-
- -
-

- t('Opener')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
- 'before', - 'After the logo' => 'after', - ]; - ?> -
- t('Position')); ?> -
-
- -
-
- -
-
- t('Show only the opener (hidden logo)')); ?> -
-
- -
-
- -
-
- t('Do not display the side menu and the opener if there is no application (eg: public pages).')); ?> -
-
- -
-
- -
-
- t('Open the menu when the mouse is hover the opener (automatically disabled on touch screens)')); ?> - -
- t('This is the automatic behavior when the menu is always displayed.')); ?> -
-
- -
-
-
-
- -
-
-
-
- t('Display the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Use the avatar instead of the logo')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('The logo is a link to the default app')); ?> - -
- t($labelDefault)); ?> -
-
-
- -
-
- -
-
- t('Apps that should not be displayed in the menu')); ?> - -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
-
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Show the link to settings')); ?> -
-
- -
-
- -
-
- t('Icons and texts')); ?> -
-
- - - -
-
- -
-
- t('Open apps in new tab')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Loader enabled')); ?> -
-
- -
-
-
-
- -
-

- t('Top menu')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Applications kept in the top menu')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
- -
-
- t('Applications kept in the top menu but also shown in side menu')); ?> -
- t('These applications must be selected in the previous option.')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - -
-
-
-
- t('Hide labels on mouse over')); ?> -
- '2'] - ); - ?> -
- -
-
-
-
- -
-

- t('Applications')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -
-
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - -
- - - - ' name="apps-order" class="side-menu-setting" id="side-menu-apps-order"> -
-
-
-
- - -
-

- t('Categories')); ?> -

- -
- t($labelWithCategories)); ?> - t($labelBigMenu)); ?> -
- -
-
- 'default', - 'Customed' => 'custom', - ]; - ?> -
- t('Order by')); ?> -
-
- -
-
- -
-
- t('Custom categories')); ?> -
-
- - -
-
-
-
- -
-
- t('Customize application categories')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - - - - -
-
- -
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t('Show and hide the list of categories')); ?> - - - - - ' name="categories-order" class="side-menu-setting"> -
-
-
-
- -
-

- t('Tips')); ?> -

- -
- t($labelDefault)); ?> - t($labelWithCategories)); ?> - t($labelBigMenu)); ?> - t($labelAlwaysDisplayed)); ?> -
- -

- t('Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.'); ?> -

-
- -
-
-
-
- t('The menu is enabled by default for users')); ?> -
- t('Except when the configuration is forced.')); ?> -
-
- -
-
- -
-
- t('Force this configuration to users')); ?> -
-
- -
-
-
- - -
- -
- - - - - - - - - - -
- -
- - t('You like this app and you want to support me?')); ?> - - - - - -
-
-
+
diff --git a/templates/settings/personal-form.php b/templates/settings/personal-form.php index 793feec..e2ff8e4 100644 --- a/templates/settings/personal-form.php +++ b/templates/settings/personal-form.php @@ -16,250 +16,11 @@ * along with this program. If not, see . */ -vendor_script('side_menu', 'html5sortable.min'); -script('side_menu', 'admin'); -style('side_menu', 'admin'); +use OCP\IURLGenerator; +use OCP\IConfig; +use OCA\SideMenu\AppInfo\Application; -$choicesYesNo = [ - 'No' => '0', - 'Yes' => '1', -]; - - -$labelShowHideApps = 'Show and hide the list of applications'; -$labelReset = 'Reset to default'; +script('side_menu', 'side_menu-user'); ?> -
- -
-

- t('Menu')); ?> -

-

- t('You do not have permission to change the settings.'); ?> -

-
- -
-

- t('Use the shortcut Ctrl+o to open and to hide the side menu. Use tab to navigate.'); ?> -

- -
-
-
- t('Enable the custom menu')); ?> -
-
- -
-
-
- -
-
-
- t('Open apps in new tab')); ?> -
-
- '1', - 'Use my selection' => '2', - ]; ?> - - - -

- - 🖱️ t($labelShowHideApps)); ?> - -

- - -
-
-
-
- -
-

- t('Top menu')); ?> -

- -
-
-
- t('Applications kept in the top menu')); ?> -

- - t('If there is no selection then the global configuration is applied.')); ?> - -

-
-
-

- - 🖱️ t($labelShowHideApps)); ?> - -

- - -
-
-
- -
-
-
- t('Applications kept in the top menu but also shown in side menu')); ?> -

- - t('These applications must be selected in the previous option.')); ?>
- t('If there is no selection then the global configuration is applied.')); ?> -
-

-
-
-

- - 🖱️ t($labelShowHideApps)); ?> - -

- - -
-
-
-
-
-

- t('Applications')); ?> -

- -
-
-
- t('Customize sorting')); ?> -
-
- - 🖱️ t($labelShowHideApps)); ?> - - -
- - - - ' name="apps-order" class="side-menu-setting" id="side-menu-apps-order" data-personal> -
-
-
-
- - -
- - - - - -
- - -
- - t('You like this app and you want to support me?')); ?> - - - - - -
-
-
+
diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index cd22dba..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "extends": "@vue/tsconfig/tsconfig.json", - "include": ["./src/**/*.js"], - "compilerOptions": { - "types": ["node", "vue", "vue-router"], - "outDir": "./js/", - "target": "ESNext", - "module": "ESNext", - // Set module resolution to bundler and `noEmit` to be able to set `allowImportingTsExtensions`, so we can import Typescript with .ts extension - "moduleResolution": "Bundler", - "allowImportingTsExtensions": true, - "noEmit": true, - // Allow ts to import js files - "allowJs": true, - "allowSyntheticDefaultImports": true, - "declaration": false, - "noImplicitAny": false, - "resolveJsonModule": true, - "strict": true, - }, - "vueCompilerOptions": { - "target": 2.7 - }, - "ts-node": { - // these options are overrides used only by ts-node - // same as our --compilerOptions flag and our TS_NODE_COMPILER_OPTIONS environment variable - "compilerOptions": { - "moduleResolution": "node", - "module": "commonjs", - "verbatimModuleSyntax": false - } - } -} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..d9876e8 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,93 @@ +const path = require('path') +const webpack = require('webpack') +const { VueLoaderPlugin } = require('vue-loader') + +const rules = require('./webpack.rules.js') +const NodePolyfillPlugin = require('node-polyfill-webpack-plugin') +const TerserPlugin = require('terser-webpack-plugin') + +const appName = 'side_menu' +const buildMode = process.env.NODE_ENV +const isDev = buildMode === 'development' + +module.exports = { + target: 'web', + mode: buildMode, + devtool: false, + entry: { + menu: path.resolve(path.join('src', 'menu.js')), + admin: path.resolve(path.join('src', 'admin.js')), + user: path.resolve(path.join('src', 'user.js')), + }, + output: { + path: path.resolve('./js'), + publicPath: path.join('/apps/', appName, '/js/'), + + // Output file names + filename: `${appName}-[name].js?v=[contenthash]`, + chunkFilename: `${appName}-[name].js?v=[contenthash]`, + + // Clean output before each build + clean: true, + }, + + optimization: { + chunkIds: 'named', + splitChunks: { + automaticNameDelimiter: '-', + minSize: 10000, + maxSize: 250000, + }, + minimize: !isDev, + minimizer: [ + new TerserPlugin({ + terserOptions: { + output: { + comments: false, + } + }, + extractComments: true, + }), + ], + }, + + module: { + rules: Object.values(rules), + }, + + plugins: [ + new VueLoaderPlugin(), + + // Make sure we auto-inject node polyfills on demand + // https://webpack.js.org/blog/2020-10-10-webpack-5-release/#automatic-nodejs-polyfills-removed + new NodePolyfillPlugin({ + // Console is available in the web-browser + excludeAliases: ['console'], + }), + + // @nextcloud/moment since v1.3.0 uses `moment/min/moment-with-locales.js` + // Which works only in Node.js and is not compatible with Webpack bundling + // It has an unused function `localLocale` that requires locales by invalid relative path `./locale` + // Though it is not used, Webpack tries to resolve it with `require.context` and fails + new webpack.IgnorePlugin({ + resourceRegExp: /^\.[/\\]locale$/, + contextRegExp: /moment[/\\]min$/, + }), + + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + }), + ], + + resolve: { + extensions: ['.*', '.mjs', '.js', '.vue'], + symlinks: false, + // Ensure npm does not duplicate vue dependency, and that npm link works for vue 3 + // See https://github.com/vuejs/core/issues/1503 + // See https://github.com/nextcloud/nextcloud-vue/issues/3281 + alias: { + 'vue$': path.resolve('./node_modules/vue') + }, + }, +} + diff --git a/webpack.js b/webpack.js deleted file mode 100644 index 9509a6a..0000000 --- a/webpack.js +++ /dev/null @@ -1,70 +0,0 @@ -const path = require('path') -const BabelLoaderExcludeNodeModulesExcept = require('babel-loader-exclude-node-modules-except') -const { - VueLoaderPlugin -} = require('vue-loader') -// const StyleLintPlugin = require('stylelint-webpack-plugin') - -module.exports = { - devtool: "source-map", - entry: { - 'admin': path.join(__dirname, 'src', 'admin.js'), - 'sideMenu': path.join(__dirname, 'src', 'SideMenu.js'), - }, - output: { - path: path.resolve(__dirname, './js'), - publicPath: '/js', - filename: '[name].js?v=[chunkhash]', - chunkFilename: 'chunks/[name]-[chunkhash].js', - }, - module: { - rules: [{ - test: /\.css$/, - use: ['vue-style-loader', 'css-loader'], - }, - { - test: /\.scss$/, - use: ['vue-style-loader', 'css-loader', 'sass-loader'], - }, - { - test: /\.vue$/, - loader: 'vue-loader', - }, - { - test: /\.tsx?$/, - use: [ - 'babel-loader', - { - // Fix TypeScript syntax errors in Vue - loader: 'ts-loader', - options: { - transpileOnly: true, - }, - }, - ], - exclude: BabelLoaderExcludeNodeModulesExcept([]), - }, - { - test: /\.js$/, - loader: 'babel-loader', - exclude: /node_modules/, - }, - { - test: /\.(png|jpg|gif|svg)$/, - loader: 'url-loader', - options: { - name: '[name].[ext]?[hash]', - limit: 8192, - }, - }, - ], - }, - plugins: [ - new VueLoaderPlugin(), - // new StyleLintPlugin(), - ], - resolve: { - extensions: ['.*', '.js', '.vue'], - symlinks: false, - }, -} diff --git a/webpack.rules.js b/webpack.rules.js new file mode 100644 index 0000000..4314a8f --- /dev/null +++ b/webpack.rules.js @@ -0,0 +1,23 @@ +module.exports = { + scss: { + test: /\.scss$/, + use: ['style-loader', 'css-loader', 'sass-loader'], + }, + css: { + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + vue: { + test: /\.vue$/, + loader: 'vue-loader', + }, + js: { + test: /\.js$/, + loader: 'babel-loader', + exclude: /node_modules/, + }, + assets: { + test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf)$/, + type: 'asset/inline', + }, +}