diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index df2d47160..000000000 --- a/.browserslistrc +++ /dev/null @@ -1,7 +0,0 @@ ->0.2% -not op_mini all -Safari > 15 -Firefox >= 115 -Firefox ESR -Android > 4 -not dead diff --git a/.gitignore b/.gitignore index 0d5befd28..4df5ec838 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,3 @@ selenium-debug.log .idea/ config/local.json static/emoji.json -logs/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4c5cf43a..2b4452d53 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,9 +43,6 @@ lint: test: stage: test - tags: - - amd64 - - himem variables: APT_CACHE_DIR: apt-cache script: @@ -57,9 +54,6 @@ test: build: stage: build - tags: - - amd64 - - himem script: - yarn - npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md index 9844319e3..444a863c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,74 +3,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## 2.7.1 -Bugfix release. Added small optimizations to emoji picker that should make it a bit more responsive, however it needs rather large change to make it more performant which might come in a major release. - -### Fixed -- Instance default theme not respected -- Nested panel header having wrong sticky position if navbar height != panel header height -- Toggled buttons having bad contrast (when using v2 theme) - -### Changed -- Simplify the OAuth client_name to 'PleromaFE' -- Small optimizations to emoji picker - - -## 2.7.0 - -### Known issues -We got some reports related to emoji picker performance, this hopefully will be fixed in 2.7.1. - -### Notes -This release overhauls how themes work, themes now need to be "compiled", which can cause some delay when loading for the first time and temporarily look "wrong" in some places (popups, menus, dialogs). Please do report any issues, especially if your theme looks wrong or breaks interface when loading. Also report issues if you're experiencing constant performance issues. - -To admins: remember that you can update PleromaFE to recent `master` or `develop` in admin dashboard in "Front-ends" tab, scroll down to find PleromaFE box and click "Reinstall `master`" or dropdown and then "Reinstall `develop`". Currently there is no mechanism to check if there is an update or not. - -### Changed -- Overhauled the way themes work, migrating to new Pleroma Interface Style Sheets system aka "Themes 3". -- Notifications are no longer sorted by "seen" status since interacting with them can change their read status and makes UI jumpy. Old behavior can be restored in settings. -- Notifications are now shown through a ServiceWorker (since mobile chrome does not allow them otherwise), it's always enabled, even if previously we only enabled it for WebPush notifications only. If you don't like websites "running" while closed, check how to disable them in your browser. Old way to show notifications will be used as a fallback but might not have all the new features. -- Reorganized Settings modal to move out visual stuff into Appearance tab - -### Added -- Emoji pack management to the admin panel -- Support `status` notification type (subscriptions/bell, fixes PleromaFE on newer PleromaBE versions) -- Poll end notifications. -- Added option to not mark all notifications when closing notifications drawer on mobile, this creates a new button to mark all as seen. -- Option to always "show" notifications when using web push for better compatibility with some browsers (chrome, edge, safari) -- Option to toggle what notification types appear in native notifications, by default less important ones (likes, repeats, etc) will no longer show up in native notifications. -- Option to treat non-interactive notifications (likes, repeats et all) as seen for visual purposes (no read mark, ignored in counters, still can show in native notifications) -- Ability to resize UI (and certain components) scale independent of browser/text scale -- Ability to override certain aspects of UI style independent of theme used (UI roundness, fonts, underlay) -- Theme selector with visual previews of the theme -- Display loading and error indicator for conversation page -- Option to only show scrobbles that are recent enough -- Interacting (opening reply box etc) or simply clicking on non-interactive notifications now marks them as read. Clicking on native notifications for non-interactive ones also marks them as seen. -- Support group actors -- Focusing into a tab clears all current desktop notifications -- Ability to change size of emoji -- Ability to view APNG (Animated PNG) attachments. -- Support showing extra notifications in the notifications column -- Create a link to the URL of the scrobble when it's present -- Allow hiding custom emojis in picker. -- Ability to mute sensitive posts (ported from eintei). -- Native notifications now also have "badge" property that matches instance's favicon (visible in Android Chromium at least) -- Display public favorites on user profiles -- Display quotes count on posts and add quotes list page -- Show a dedicated registration notice page when further action is required after registering - -### Fixed -- Synchronized requested notification types with backend, hopefully should fix missing notifications for polls and follow requests -- Error that appeared on mobile Chromium (and derivatives) when native notifications are allowed -- Being unable to set notification visibility for reports and follow requests -- Native notifications appearing as many times as there are open tabs. Clicking on notification will focus last focused tab. -- The expiry date indication won't be shown if the poll never expires -- Profile mentions causing a 422 error on newer PleromaBE versions. -- Color inputs are less ugly now -- Unread notifications should now properly catch up between sessions (eventually) in polling mode -- Video posters on Safari - - ## 2.6.1 ### Fixed - fix admin dashboard not having any feedback on frontend installation diff --git a/changelog.d/add-apng.add b/changelog.d/add-apng.add new file mode 100644 index 000000000..cdec58afc --- /dev/null +++ b/changelog.d/add-apng.add @@ -0,0 +1 @@ +Make Pleroma FE to also view apng (Animated PNG) attachment. diff --git a/changelog.d/better-shadow-control.fix b/changelog.d/better-shadow-control.fix deleted file mode 100644 index 585ef6d26..000000000 --- a/changelog.d/better-shadow-control.fix +++ /dev/null @@ -1 +0,0 @@ -Updated shadow editor, hopefully fixed long-standing bugs, added ability to specify shadow's name. diff --git a/changelog.d/bookmark-folders.add b/changelog.d/bookmark-folders.add deleted file mode 100644 index f22966602..000000000 --- a/changelog.d/bookmark-folders.add +++ /dev/null @@ -1 +0,0 @@ -Support bookmark folders diff --git a/changelog.d/browsers-support.change b/changelog.d/browsers-support.change deleted file mode 100644 index a62e50240..000000000 --- a/changelog.d/browsers-support.change +++ /dev/null @@ -1,9 +0,0 @@ -Updated our build system to support browsers: - Safari >= 15 - Firefox >= 115 - Android > 4 - no Opera Mini support - no IE support - no "dead" (unmaintained) browsers support - -This does not guarantee that browsers will or will not work. diff --git a/changelog.d/create-link-when-url-present.add b/changelog.d/create-link-when-url-present.add new file mode 100644 index 000000000..11aa37583 --- /dev/null +++ b/changelog.d/create-link-when-url-present.add @@ -0,0 +1 @@ +Create a link to the URL of the scrobble when it's present diff --git a/changelog.d/date-absolute.add b/changelog.d/date-absolute.add deleted file mode 100644 index d9365f464..000000000 --- a/changelog.d/date-absolute.add +++ /dev/null @@ -1 +0,0 @@ -Support displaying time in absolute format diff --git a/changelog.d/double-notifications.fix b/changelog.d/double-notifications.fix new file mode 100644 index 000000000..24e08c0ff --- /dev/null +++ b/changelog.d/double-notifications.fix @@ -0,0 +1 @@ +Fix native notifications appearing as many times as there are open tabs. Clicking on notification will focus last focused tab. diff --git a/changelog.d/extra-notifications.add b/changelog.d/extra-notifications.add new file mode 100644 index 000000000..90f21f540 --- /dev/null +++ b/changelog.d/extra-notifications.add @@ -0,0 +1 @@ +Support showing extra notifications in the notifications column diff --git a/changelog.d/focus-clear.add b/changelog.d/focus-clear.add new file mode 100644 index 000000000..70f54ab69 --- /dev/null +++ b/changelog.d/focus-clear.add @@ -0,0 +1 @@ +Focusing into a tab clears all current desktop notifications diff --git a/changelog.d/mobile-chrome-notifs.fix b/changelog.d/mobile-chrome-notifs.fix new file mode 100644 index 000000000..7db10c56a --- /dev/null +++ b/changelog.d/mobile-chrome-notifs.fix @@ -0,0 +1 @@ +Fixed error that appeared on mobile Chrome(ium) (and derivatives) when native notifications are allowed diff --git a/changelog.d/mobile-drawer-notifications.change b/changelog.d/mobile-drawer-notifications.change new file mode 100644 index 000000000..9353c709d --- /dev/null +++ b/changelog.d/mobile-drawer-notifications.change @@ -0,0 +1 @@ +Added option to not mark all notifications when closing notifications drawer on mobile, this creates a new button to mark all as seen. diff --git a/changelog.d/more-notification-types-setting.fix b/changelog.d/more-notification-types-setting.fix new file mode 100644 index 000000000..2d71b5993 --- /dev/null +++ b/changelog.d/more-notification-types-setting.fix @@ -0,0 +1 @@ +Fixed being unable to set notification visibility for reports and follow requests diff --git a/changelog.d/multiple-status-mute-reasons.fix b/changelog.d/multiple-status-mute-reasons.fix deleted file mode 100644 index 952ccea82..000000000 --- a/changelog.d/multiple-status-mute-reasons.fix +++ /dev/null @@ -1 +0,0 @@ -Fix whitespaces for multiple status mute reasons, display bot status reason diff --git a/changelog.d/native-filtering.add b/changelog.d/native-filtering.add new file mode 100644 index 000000000..82ab9a23a --- /dev/null +++ b/changelog.d/native-filtering.add @@ -0,0 +1 @@ +Added option to toggle what notification types appear in native notifications, by default less important ones (likes, repeats, etc) will no longer show up in native notifications. diff --git a/changelog.d/native-notifications.add b/changelog.d/native-notifications.add new file mode 100644 index 000000000..d896e7c04 --- /dev/null +++ b/changelog.d/native-notifications.add @@ -0,0 +1 @@ +Native notifications now also have "badge" property that matches instance's favicon (visible in Android Chromium at least) diff --git a/changelog.d/non-anonymous-polls.add b/changelog.d/non-anonymous-polls.add deleted file mode 100644 index 9ff7f3adc..000000000 --- a/changelog.d/non-anonymous-polls.add +++ /dev/null @@ -1 +0,0 @@ -Inform users that Smithereen public polls are public \ No newline at end of file diff --git a/changelog.d/noninteractive-ignore-read.add b/changelog.d/noninteractive-ignore-read.add new file mode 100644 index 000000000..5e8710cf0 --- /dev/null +++ b/changelog.d/noninteractive-ignore-read.add @@ -0,0 +1 @@ +Added option to treat non-interactive notifications (likes, repeats et all) as seen for visual purposes (no read mark, ignored in counters, still can show in native notifications) diff --git a/changelog.d/notification-read.add b/changelog.d/notification-read.add new file mode 100644 index 000000000..e5027a954 --- /dev/null +++ b/changelog.d/notification-read.add @@ -0,0 +1 @@ +Interacting (opening reply box etc) or simply clicking on non-interactive notifications now marks them as read. Clicking on native notifications for non-interactive ones also marks them as seen. diff --git a/changelog.d/notifications-sorting.change b/changelog.d/notifications-sorting.change new file mode 100644 index 000000000..3a6162441 --- /dev/null +++ b/changelog.d/notifications-sorting.change @@ -0,0 +1 @@ +Notifications are no longer sorted by "seen" status since interacting with them can change their read status and makes UI jumpy. Old behavior can be restored in settings. diff --git a/changelog.d/oauth-app-name.change b/changelog.d/oauth-app-name.change deleted file mode 100644 index 15d6f87ee..000000000 --- a/changelog.d/oauth-app-name.change +++ /dev/null @@ -1 +0,0 @@ -Simplify the OAuth client_name to 'PleromaFE' diff --git a/changelog.d/piss-fix.skip b/changelog.d/piss-fix.skip deleted file mode 100644 index e69de29bb..000000000 diff --git a/changelog.d/piss-serialization.skip b/changelog.d/piss-serialization.skip deleted file mode 100644 index e69de29bb..000000000 diff --git a/changelog.d/serviceworkers.change b/changelog.d/serviceworkers.change new file mode 100644 index 000000000..b3b64f6d8 --- /dev/null +++ b/changelog.d/serviceworkers.change @@ -0,0 +1 @@ +Notifications are now shown through a serviceworker (since mobile chrome does not allow them otherwise), it's always enabled, even if previously we only enabled it for WebPush notifications only. If you don't like websites "running" while closed, check how to disable them in your browser. Old way to show notifications will be used as a fallback but might not have all the new features. diff --git a/changelog.d/show-recent-scrobble.skip b/changelog.d/show-recent-scrobble.skip new file mode 100644 index 000000000..9227de069 --- /dev/null +++ b/changelog.d/show-recent-scrobble.skip @@ -0,0 +1 @@ +Shows the most recent scrobble under each post when available diff --git a/changelog.d/splashscreen.add b/changelog.d/splashscreen.add deleted file mode 100644 index f1f56551a..000000000 --- a/changelog.d/splashscreen.add +++ /dev/null @@ -1 +0,0 @@ -Splash screen + loading indicator to make process of identifying initialization issues and load performance diff --git a/changelog.d/unreads-sync.fix b/changelog.d/unreads-sync.fix new file mode 100644 index 000000000..1eac33649 --- /dev/null +++ b/changelog.d/unreads-sync.fix @@ -0,0 +1 @@ +unread notifications should now properly catch up (eventually) in polling mode diff --git a/changelog.d/video-poster.fix b/changelog.d/video-poster.fix new file mode 100644 index 000000000..43e95f6e1 --- /dev/null +++ b/changelog.d/video-poster.fix @@ -0,0 +1 @@ +Video posters on Safari diff --git a/changelog.d/web-push-always.add b/changelog.d/web-push-always.add new file mode 100644 index 000000000..f8b8888a2 --- /dev/null +++ b/changelog.d/web-push-always.add @@ -0,0 +1 @@ +Added option to always "show" notifications when using web push for better compatibility with some browsers (chrome, edge, safari) diff --git a/index.html b/index.html index 461f5acc1..e790fb57a 100644 --- a/index.html +++ b/index.html @@ -4,138 +4,11 @@ - - - - - + -
- - -
- -
- - - -
-
-
- +
diff --git a/package.json b/package.json index 403a2b231..fa41beb3a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pleroma_fe", - "version": "2.7.1", + "version": "2.6.1", "description": "Pleroma frontend, the default frontend of Pleroma social network server", "author": "Pleroma contributors ", "private": false, @@ -24,16 +24,15 @@ "@fortawesome/vue-fontawesome": "3.0.3", "@kazvmoe-infra/pinch-zoom-element": "1.2.0", "@kazvmoe-infra/unicode-emoji-json": "0.4.0", - "@ruffle-rs/ruffle": "0.1.0-nightly.2024.8.21", + "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", "@vuelidate/core": "2.0.3", - "@vuelidate/validators": "2.0.4", + "@vuelidate/validators": "2.0.0", "body-scroll-lock": "3.1.5", "chromatism": "3.0.0", "click-outside-vue3": "4.0.1", "cropperjs": "1.5.13", "escape-html": "1.0.3", - "hash-sum": "^2.0.0", - "js-cookie": "3.0.5", + "js-cookie": "3.0.1", "localforage": "1.10.0", "parse-link-header": "2.0.0", "phoenix": "1.7.7", @@ -56,13 +55,13 @@ "@babel/preset-env": "7.21.5", "@babel/register": "7.21.0", "@intlify/vue-i18n-loader": "5.0.1", - "@ungap/event-target": "0.2.4", + "@ungap/event-target": "0.2.3", "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", - "@vue/babel-plugin-jsx": "1.2.2", + "@vue/babel-plugin-jsx": "1.1.1", "@vue/compiler-sfc": "3.2.45", "@vue/test-utils": "2.2.8", - "autoprefixer": "10.4.19", - "babel-loader": "9.1.3", + "autoprefixer": "10.4.14", + "babel-loader": "9.1.2", "babel-plugin-lodash": "3.3.4", "chai": "4.3.7", "chalk": "1.1.3", @@ -70,7 +69,7 @@ "connect-history-api-fallback": "2.0.0", "copy-webpack-plugin": "11.0.0", "cross-spawn": "7.0.3", - "css-loader": "6.10.0", + "css-loader": "6.7.3", "css-minimizer-webpack-plugin": "4.2.2", "custom-event-polyfill": "1.0.7", "eslint": "8.33.0", @@ -88,9 +87,9 @@ "http-proxy-middleware": "2.0.6", "iso-639-1": "2.1.15", "json-loader": "0.5.7", - "karma": "6.4.4", + "karma": "6.4.2", "karma-coverage": "2.2.0", - "karma-firefox-launcher": "2.1.3", + "karma-firefox-launcher": "2.1.2", "karma-mocha": "2.0.1", "karma-mocha-reporter": "2.2.5", "karma-sinon-chai": "2.0.2", @@ -100,7 +99,7 @@ "lodash": "4.17.21", "mini-css-extract-plugin": "2.7.6", "mocha": "10.2.0", - "nightwatch": "2.6.25", + "nightwatch": "2.6.20", "opn": "5.5.0", "ora": "0.4.1", "postcss": "8.4.23", @@ -132,6 +131,5 @@ "engines": { "node": ">= 16.0.0", "npm": ">= 3.0.0" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } diff --git a/preview.style.js b/preview.style.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/App.js b/src/App.js index e87108dd9..b7eb2f72e 100644 --- a/src/App.js +++ b/src/App.js @@ -44,29 +44,16 @@ export default { data: () => ({ mobileActivePanel: 'timeline' }), - watch: { - themeApplied (value) { - this.removeSplash() - } - }, created () { // Load the locale from the storage const val = this.$store.getters.mergedConfig.interfaceLanguage this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) window.addEventListener('resize', this.updateMobileState) }, - mounted () { - if (this.$store.state.interface.themeApplied) { - this.removeSplash() - } - }, unmounted () { window.removeEventListener('resize', this.updateMobileState) }, computed: { - themeApplied () { - return this.$store.state.interface.themeApplied - }, classes () { return [ { @@ -143,15 +130,6 @@ export default { updateMobileState () { this.$store.dispatch('setLayoutWidth', windowWidth()) this.$store.dispatch('setLayoutHeight', windowHeight()) - }, - removeSplash () { - document.querySelector('#status').textContent = this.$t('splash.fun_' + Math.ceil(Math.random() * 4)) - const splashscreenRoot = document.querySelector('#splash') - splashscreenRoot.addEventListener('transitionend', () => { - splashscreenRoot.remove() - }) - splashscreenRoot.classList.add('hidden') - document.querySelector('#app').classList.remove('hidden') } } } diff --git a/src/App.scss b/src/App.scss index f52ba06b9..ef68ac50b 100644 --- a/src/App.scss +++ b/src/App.scss @@ -1,9 +1,10 @@ // stylelint-disable rscss/class-format /* stylelint-disable no-descending-specificity */ +@import "./variables"; @import "./panel"; :root { - --status-margin: 0.75em; + --navbar-height: 3.5rem; --post-line-height: 1.4; // Z-Index stuff --ZI_media_modal: 9000; @@ -12,25 +13,19 @@ --ZI_navbar_popovers: 7500; --ZI_navbar: 7000; --ZI_popovers: 6000; - - // Fallback for when stuff is loading - --background: var(--bg); } html { - font-size: var(--textSize, 14px); - - --navbar-height: var(--navbarSize, 3.5rem); - --emoji-size: var(--emojiSize, 32px); - --panel-header-height: var(--panelHeaderSize, 3.2rem); + font-size: 14px; // overflow-x: clip causes my browser's tab to crash with SIGILL lul } body { font-family: sans-serif; - font-family: var(--font); + font-family: var(--interfaceFont, sans-serif); margin: 0; - color: var(--text); + color: $fallback--text; + color: var(--text, $fallback--text); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overscroll-behavior-y: none; @@ -47,35 +42,17 @@ body { // have a cursor/pointer to operate them @media (any-pointer: fine) { * { - scrollbar-color: var(--fg) transparent; + scrollbar-color: var(--btn) transparent; &::-webkit-scrollbar { background: transparent; } - &::-webkit-scrollbar-corner { - background: transparent; - } - - &::-webkit-resizer { - /* stylelint-disable-next-line declaration-no-important */ - background-color: transparent !important; - background-image: - linear-gradient( - 135deg, - transparent calc(50% - 1px), - var(--textFaint) 50%, - transparent calc(50% + 1px), - transparent calc(75% - 1px), - var(--textFaint) 75%, - transparent calc(75% + 1px), - ); - } - &::-webkit-scrollbar-button, &::-webkit-scrollbar-thumb { - box-shadow: var(--shadow); - border-radius: var(--roundness); + background-color: var(--btn); + box-shadow: var(--buttonShadow); + border-radius: var(--btnRadius); } // horizontal/vertical/increment/decrement are webkit-specific stuff @@ -84,7 +61,7 @@ body { &::-webkit-scrollbar-button { --___bgPadding: 2px; - color: var(--text); + color: var(--btnText); background-repeat: no-repeat, no-repeat; &:horizontal { @@ -92,15 +69,15 @@ body { &:increment { background-image: - linear-gradient(45deg, var(--text) 50%, transparent 51%), - linear-gradient(-45deg, transparent 50%, var(--text) 51%); + linear-gradient(45deg, var(--btnText) 50%, transparent 51%), + linear-gradient(-45deg, transparent 50%, var(--btnText) 51%); background-position: top var(--___bgPadding) left 50%, right 50% bottom var(--___bgPadding); } &:decrement { background-image: - linear-gradient(45deg, transparent 50%, var(--text) calc(50% + 1px)), - linear-gradient(-45deg, var(--text) 50%, transparent 51%); + linear-gradient(45deg, transparent 50%, var(--btnText) 51%), + linear-gradient(-45deg, var(--btnText) 50%, transparent 51%); background-position: bottom var(--___bgPadding) right 50%, left 50% top var(--___bgPadding); } } @@ -110,15 +87,15 @@ body { &:increment { background-image: - linear-gradient(-45deg, transparent 50%, var(--text) 51%), - linear-gradient(45deg, transparent 50%, var(--text) 51%); + linear-gradient(-45deg, transparent 50%, var(--btnText) 51%), + linear-gradient(45deg, transparent 50%, var(--btnText) 51%); background-position: right var(--___bgPadding) top 50%, left var(--___bgPadding) top 50%; } &:decrement { background-image: - linear-gradient(-45deg, var(--text) 50%, transparent 51%), - linear-gradient(45deg, var(--text) 50%, transparent 51%); + linear-gradient(-45deg, var(--btnText) 50%, transparent 51%), + linear-gradient(45deg, var(--btnText) 50%, transparent 51%); background-position: left var(--___bgPadding) top 50%, right var(--___bgPadding) top 50%; } } @@ -127,14 +104,15 @@ body { } // Body should have background to scrollbar otherwise it will use white (body color?) html { - scrollbar-color: var(--fg) var(--wallpaper); + scrollbar-color: var(--selectedMenu) var(--wallpaper); background: var(--wallpaper); } } a { text-decoration: none; - color: var(--link); + color: $fallback--link; + color: var(--link, $fallback--link); } h4 { @@ -150,15 +128,29 @@ h4 { i[class*="icon-"], .svg-inline--fa, .iconLetter { - color: var(--icon); + color: $fallback--icon; + color: var(--icon, $fallback--icon); +} + +.button-unstyled:hover, +a:hover { + > i[class*="icon-"], + > .svg-inline--fa, + > .iconLetter { + color: var(--text); + } } nav { z-index: var(--ZI_navbar); - box-shadow: var(--shadow); + background-color: $fallback--fg; + background-color: var(--topBar, $fallback--fg); + color: $fallback--faint; + color: var(--faint, $fallback--faint); + box-shadow: 0 0 4px rgb(0 0 0 / 60%); + box-shadow: var(--topBarShadow); box-sizing: border-box; height: var(--navbar-height); - font-size: calc(var(--navbar-height) / 3.5); position: fixed; } @@ -203,14 +195,16 @@ nav { grid-column: 1 / span 3; grid-row: 1 / 1; pointer-events: none; - background-color: var(--underlay); + background-color: rgb(0 0 0 / 15%); + background-color: var(--underlay, rgb(0 0 0 / 15%)); z-index: -1000; } .app-layout { --miniColumn: 25rem; --maxiColumn: 45rem; - --columnGap: 1rem; + --columnGap: 1em; + --status-margin: 0.75em; --effectiveSidebarColumnWidth: minmax(var(--miniColumn), var(--sidebarColumnWidth, var(--miniColumn))); --effectiveNotifsColumnWidth: minmax(var(--miniColumn), var(--notifsColumnWidth, var(--miniColumn))); --effectiveContentColumnWidth: minmax(var(--miniColumn), var(--contentColumnWidth, var(--maxiColumn))); @@ -372,112 +366,106 @@ nav { .button-default { user-select: none; - color: var(--text); + color: $fallback--text; + color: var(--btnText, $fallback--text); + background-color: $fallback--fg; + background-color: var(--btn, $fallback--fg); border: none; + border-radius: $fallback--btnRadius; + border-radius: var(--btnRadius, $fallback--btnRadius); cursor: pointer; - background-color: var(--background); - box-shadow: var(--shadow); + box-shadow: $fallback--buttonShadow; + box-shadow: var(--buttonShadow); font-size: 1em; font-family: sans-serif; - font-family: var(--font); + font-family: var(--interfaceFont, sans-serif); + + &.-sublime { + background: transparent; + } + + i[class*="icon-"], + .svg-inline--fa { + color: $fallback--text; + color: var(--btnText, $fallback--text); + } &::-moz-focus-inner { border: none; } + &:hover { + box-shadow: 0 0 4px rgb(255 255 255 / 30%); + box-shadow: var(--buttonHoverShadow); + } + + &:active { + box-shadow: + 0 0 4px 0 rgb(255 255 255 / 30%), + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset; + box-shadow: var(--buttonPressedShadow); + color: $fallback--text; + color: var(--btnPressedText, $fallback--text); + background-color: $fallback--fg; + background-color: var(--btnPressed, $fallback--fg); + + svg, + i { + color: $fallback--text; + color: var(--btnPressedText, $fallback--text); + } + } + &:disabled { cursor: not-allowed; - } -} + color: $fallback--text; + color: var(--btnDisabledText, $fallback--text); + background-color: $fallback--fg; + background-color: var(--btnDisabled, $fallback--fg); -.menu-item, -.list-item { - display: block; - box-sizing: border-box; - border: none; - outline: none; - text-align: initial; - font-size: inherit; - font-family: inherit; - font-weight: 400; - cursor: pointer; - color: inherit; - clear: both; - position: relative; - white-space: nowrap; - border-color: var(--border); - border-style: solid; - border-width: 0; - border-top-width: 1px; - width: 100%; - line-height: var(--__line-height); - padding: var(--__vertical-gap) var(--__horizontal-gap); - background: transparent; - - --__line-height: 1.5em; - --__horizontal-gap: 0.75em; - --__vertical-gap: 0.5em; - - &.-non-interactive { - cursor: auto; + svg, + i { + color: $fallback--text; + color: var(--btnDisabledText, $fallback--text); + } } - &.-active, - &:hover { - border-top-width: 1px; - border-bottom-width: 1px; + &.toggled { + color: $fallback--text; + color: var(--btnToggledText, $fallback--text); + background-color: $fallback--fg; + background-color: var(--btnToggled, $fallback--fg); + box-shadow: + 0 0 4px 0 rgb(255 255 255 / 30%), + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset; + box-shadow: var(--buttonPressedShadow); + + svg, + i { + color: $fallback--text; + color: var(--btnToggledText, $fallback--text); + } } - &.-active + &, - &:hover + & { - border-top-width: 0; - } - - &:hover + .menu-item-collapsible:not(.-expanded) + &, - &.-active + .menu-item-collapsible:not(.-expanded) + & { - border-top-width: 0; - } - - &[aria-expanded="true"] { - border-bottom-width: 1px; - } - - a, - button:not(.button-default) { - text-align: initial; - padding: 0; - background: none; - border: none; - outline: none; - display: inline; - font-size: 100%; - font-family: inherit; - line-height: unset; - color: var(--text); - } - - &:first-child { - border-top-right-radius: var(--roundness); - border-top-left-radius: var(--roundness); - border-top-width: 0; - } - - &:last-child { - border-bottom-right-radius: var(--roundness); - border-bottom-left-radius: var(--roundness); - border-bottom-width: 0; + &.danger { + // TODO: add better color variable + color: $fallback--text; + color: var(--alertErrorPanelText, $fallback--text); + background-color: $fallback--alertError; + background-color: var(--alertError, $fallback--alertError); } } .button-unstyled { + background: none; border: none; outline: none; display: inline; text-align: initial; font-size: 100%; font-family: inherit; - box-shadow: var(--shadow); - background-color: transparent; padding: 0; line-height: unset; cursor: pointer; @@ -485,23 +473,28 @@ nav { color: inherit; &.-link { - /* stylelint-disable-next-line declaration-no-important */ - color: var(--link) !important; + color: $fallback--link; + color: var(--link, $fallback--link); + } + + &.-fullwidth { + width: 100%; + } + + &.-hover-highlight { + &:hover svg { + color: $fallback--lightText; + color: var(--lightText, $fallback--lightText); + } } } input, -textarea { - border: none; - display: inline-block; - outline: none; -} - +textarea, .input { &.unstyled { border-radius: 0; - /* stylelint-disable-next-line declaration-no-important */ - background: none !important; + background: none; box-shadow: none; height: unset; } @@ -509,10 +502,19 @@ textarea { --_padding: 0.5em; border: none; - background-color: var(--background); - color: var(--text); - box-shadow: var(--shadow); - font-family: var(--font); + border-radius: $fallback--inputRadius; + border-radius: var(--inputRadius, $fallback--inputRadius); + box-shadow: + 0 1px 0 0 rgb(0 0 0 / 20%) inset, + 0 -1px 0 0 rgb(255 255 255 / 20%) inset, + 0 0 2px 0 rgb(0 0 0 / 100%) inset; + box-shadow: var(--inputShadow); + background-color: $fallback--fg; + background-color: var(--input, $fallback--fg); + color: $fallback--lightText; + color: var(--inputText, $fallback--lightText); + font-family: sans-serif; + font-family: var(--inputFont, sans-serif); font-size: 1em; margin: 0; box-sizing: border-box; @@ -526,6 +528,7 @@ textarea { &[disabled="disabled"], &.disabled { cursor: not-allowed; + opacity: 0.5; } &[type="range"] { @@ -540,9 +543,9 @@ textarea { display: none; &:checked + label::before { - box-shadow: var(--shadow); - background-color: var(--background); - color: var(--text); + box-shadow: 0 0 2px black inset, 0 0 0 4px $fallback--fg inset; + box-shadow: var(--inputShadow), 0 0 0 4px var(--fg, $fallback--fg) inset; + background-color: var(--accent, $fallback--link); } &:disabled { @@ -556,14 +559,16 @@ textarea { + label::before { flex-shrink: 0; display: inline-block; - content: "•"; + content: ""; transition: box-shadow 200ms; width: 1.1em; height: 1.1em; border-radius: 100%; // Radio buttons should always be circle - background-color: var(--background); - box-shadow: var(--shadow); + box-shadow: 0 0 2px black inset; + box-shadow: var(--inputShadow); margin-right: 0.5em; + background-color: $fallback--fg; + background-color: var(--input, $fallback--fg); vertical-align: top; text-align: center; line-height: 1.1; @@ -576,9 +581,8 @@ textarea { &[type="checkbox"] { &:checked + label::before { - color: var(--text); - background-color: var(--background); - box-shadow: var(--shadow); + color: $fallback--text; + color: var(--inputText, $fallback--text); } &:disabled { @@ -596,9 +600,13 @@ textarea { transition: color 200ms; width: 1.1em; height: 1.1em; - border-radius: var(--roundness); - box-shadow: var(--shadow); + border-radius: $fallback--checkboxRadius; + border-radius: var(--checkboxRadius, $fallback--checkboxRadius); + box-shadow: 0 0 2px black inset; + box-shadow: var(--inputShadow); margin-right: 0.5em; + background-color: $fallback--fg; + background-color: var(--input, $fallback--fg); vertical-align: top; text-align: center; line-height: 1.1; @@ -614,26 +622,17 @@ textarea { } } -.input, -.button-default { - --_roundness-left: var(--roundness); - --_roundness-right: var(--roundness); - - border-top-left-radius: var(--_roundness-left); - border-bottom-left-radius: var(--_roundness-left); - border-top-right-radius: var(--_roundness-right); - border-bottom-right-radius: var(--_roundness-right); -} - // Textareas should have stock line-height + vertical padding instead of huge line-height -textarea.input { +textarea { padding: var(--_padding); line-height: var(--post-line-height); } option { - color: var(--text); - background-color: var(--background); + color: $fallback--text; + color: var(--text, $fallback--text); + background-color: $fallback--bg; + background-color: var(--bg, $fallback--bg); } .hide-number-spinner { @@ -654,7 +653,7 @@ option { li { border: 1px solid var(--border); - border-radius: var(--roundness); + border-radius: var(--inputRadius); padding: 0.5em; margin: 0.25em; } @@ -670,23 +669,22 @@ option { display: inline-flex; vertical-align: middle; - > *, - > * .button-default { - --_roundness-left: 0; - --_roundness-right: 0; - + button, + .button-dropdown { position: relative; flex: 1 1 auto; - } - > *:first-child, - > *:first-child .button-default { - --_roundness-left: var(--roundness); - } + &:not(:last-child), + &:not(:last-child) .button-default { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } - > *:last-child, - > *:last-child .button-default { - --_roundness-right: var(--roundness); + &:not(:first-child), + &:not(:first-child) .button-default { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } } } @@ -716,58 +714,74 @@ option { overflow: hidden; text-overflow: ellipsis; - &.-dot, - &.-counter { - margin: 0; - position: absolute; - } - - &.-dot { - min-height: 8px; - max-height: 8px; - min-width: 8px; - max-width: 8px; - padding: 0; - line-height: 0; - font-size: 0; - left: calc(50% - 4px); - top: calc(50% - 4px); - margin-left: 6px; - margin-top: -6px; - } - - &.-counter { - border-radius: var(--roundness); - font-size: 0.75em; - line-height: 1; - text-align: right; - padding: 0.2em; - min-width: 0; - left: calc(50% - 0.5em); - top: calc(50% - 0.4em); - margin-left: 0.7em; - margin-top: -1em; + &.badge-notification { + background-color: $fallback--cRed; + background-color: var(--badgeNotification, $fallback--cRed); + color: white; + color: var(--badgeNotificationText, white); } } .alert { margin: 0 0.35em; padding: 0 0.25em; - border-radius: var(--roundness); - border: 1px solid var(--border); + border-radius: $fallback--tooltipRadius; + border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + + &.error { + background-color: $fallback--alertError; + background-color: var(--alertError, $fallback--alertError); + color: $fallback--text; + color: var(--alertErrorText, $fallback--text); + + .panel-heading & { + color: $fallback--text; + color: var(--alertErrorPanelText, $fallback--text); + } + } + + &.warning { + background-color: $fallback--alertWarning; + background-color: var(--alertWarning, $fallback--alertWarning); + color: $fallback--text; + color: var(--alertWarningText, $fallback--text); + + .panel-heading & { + color: $fallback--text; + color: var(--alertWarningPanelText, $fallback--text); + } + } + + &.success { + background-color: var(--alertSuccess, $fallback--alertWarning); + color: var(--alertSuccessText, $fallback--text); + + .panel-heading & { + color: var(--alertSuccessPanelText, $fallback--text); + } + } } .faint { - --text: var(--textFaint); - --link: var(--linkFaint); + color: $fallback--faint; + color: var(--faint, $fallback--faint); +} - color: var(--text); +.faint-link { + color: $fallback--faint; + color: var(--faint, $fallback--faint); + + &:hover { + text-decoration: underline; + } } .visibility-notice { padding: 0.5em; - border: 1px solid var(--textFaint); - border-radius: var(--roundness); + border: 1px solid $fallback--faint; + border: 1px solid var(--faint, $fallback--faint); + border-radius: $fallback--inputRadius; + border-radius: var(--inputRadius, $fallback--inputRadius); } .notice-dismissible { @@ -788,10 +802,6 @@ option { &.iconLetter { font-size: 1.1em; } - - &.svg-inline--fa { - vertical-align: -0.15em; - } } .fa-old-padding { @@ -806,11 +816,6 @@ option { opacity: 0.25; } -.timeago { - --link: var(--text); - --linkFaint: var(--textFaint); -} - .login-hint { text-align: center; @@ -909,174 +914,3 @@ option { padding: 0; position: absolute; } - -*::selection { - color: var(--selectionText); - background-color: var(--selectionBackground); -} - -#splash { - pointer-events: none; - transition: opacity 2s; - opacity: 1; - - &.hidden { - opacity: 0; - } - - #status { - &.css-ok { - &::before { - display: inline-block; - content: "CSS OK"; - } - } - - .initial-text { - display: none; - } - } - - #throbber { - animation-duration: 3s; - animation-name: bounce; - animation-iteration-count: infinite; - animation-direction: normal; - transform-origin: bottom center; - - &.dead { - animation-name: dead; - animation-duration: 2s; - animation-iteration-count: 1; - transform: rotateX(90deg) rotateY(0) rotateZ(-45deg); - } - - @keyframes dead { - 0% { - transform: rotateX(0) rotateY(0) rotateZ(0); - } - - 5% { - transform: rotateX(0) rotateY(0) rotateZ(1deg); - } - - 10% { - transform: rotateX(0) rotateY(0) rotateZ(-2deg); - } - - 15% { - transform: rotateX(0) rotateY(0) rotateZ(3deg); - } - - 20% { - transform: rotateX(0) rotateY(0) rotateZ(0); - } - - 25% { - transform: rotateX(0) rotateY(0) rotateZ(0); - } - - 30% { - transform: rotateX(10deg) rotateY(0) rotateZ(0); - } - - 35% { - transform: rotateX(-10deg) rotateY(0) rotateZ(0); - } - - 40% { - transform: rotateX(10deg) rotateY(0) rotateZ(0); - } - - 45% { - transform: rotateX(-10deg) rotateY(0) rotateZ(0); - } - - 50% { - transform: rotateX(10deg) rotateY(0) rotateZ(0); - } - - 100% { - transform: rotateX(90deg) rotateY(0) rotateZ(-45deg); - transition-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06); /* easeInQuint */ - } - } - - @keyframes bounce { - 0% { - scale: 1 1; - translate: 0 0; - animation-timing-function: ease-out; - } - - 10% { - scale: 1.2 0.8; - translate: 0 0; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-out; - } - - 30% { - scale: 0.9 1.1; - translate: 0 -40%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in; - } - - 40% { - scale: 1.1 0.9; - translate: 0 -50%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in; - } - - 45% { - scale: 0.9 1.1; - translate: 0 -45%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in; - } - - 50% { - scale: 1.05 0.95; - translate: 0 -40%; - animation-timing-function: ease-in; - } - - 55% { - scale: 0.985 1.025; - translate: 0 -35%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in; - } - - 60% { - scale: 1.0125 0.9985; - translate: 0 -30%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in; - } - - 80% { - scale: 1.0063 0.9938; - translate: 0 -10%; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-in-ou; - } - - 90% { - scale: 1.2 0.8; - translate: 0 0; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-out; - } - - 100% { - scale: 1 1; - translate: 0 0; - transform: rotateZ(var(--defaultZ)); - animation-timing-function: ease-out; - } - } - } -} diff --git a/src/App.vue b/src/App.vue index 9d7ad9129..fe214ce71 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,6 +1,5 @@ @@ -33,13 +33,7 @@ library.add( export default { components: { Popover }, - props: { - changed: Boolean, - messageKey: { - type: String, - default: 'settings.setting_changed' - } - } + props: ['changed'] } diff --git a/src/components/settings_modal/helpers/number_setting.vue b/src/components/settings_modal/helpers/number_setting.vue index 32dc6f83f..93f113318 100644 --- a/src/components/settings_modal/helpers/number_setting.vue +++ b/src/components/settings_modal/helpers/number_setting.vue @@ -15,10 +15,9 @@ - {{ ' ' }} this.$store.dispatch('pushAdminSetting', { path: k, value: v }) default: - if (this.timedApplyMode) { - return (k, v) => this.$store.dispatch('setOptionTemporarily', { name: k, value: v }) - } else { - return (k, v) => this.$store.dispatch('setOption', { name: k, value: v }) - } + return (k, v) => this.$store.dispatch('setOption', { name: k, value: v }) } }, defaultState () { @@ -203,8 +195,7 @@ export default { } }, canHardReset () { - return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths && - this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) + return this.realSource === 'admin' && this.$store.state.adminSettings.modifiedPaths.has(this.canonPath.join(' -> ')) }, matchesExpertLevel () { return (this.expert || 0) <= this.$store.state.config.expertLevel > 0 diff --git a/src/components/settings_modal/helpers/size_setting.js b/src/components/settings_modal/helpers/size_setting.js new file mode 100644 index 000000000..12cef705a --- /dev/null +++ b/src/components/settings_modal/helpers/size_setting.js @@ -0,0 +1,40 @@ +import Select from 'src/components/select/select.vue' +import Setting from './setting.js' + +export const allCssUnits = ['cm', 'mm', 'in', 'px', 'pt', 'pc', 'em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', '%'] +export const defaultHorizontalUnits = ['px', 'rem', 'vw'] +export const defaultVerticalUnits = ['px', 'rem', 'vh'] + +export default { + ...Setting, + components: { + ...Setting.components, + Select + }, + props: { + ...Setting.props, + min: Number, + units: { + type: Array, + default: () => allCssUnits + } + }, + computed: { + ...Setting.computed, + stateUnit () { + return this.state.replace(/\d+/, '') + }, + stateValue () { + return this.state.replace(/\D+/, '') + } + }, + methods: { + ...Setting.methods, + updateValue (e) { + this.configSink(this.path, parseInt(e.target.value) + this.stateUnit) + }, + updateUnit (e) { + this.configSink(this.path, this.stateValue + e.target.value) + } + } +} diff --git a/src/components/settings_modal/helpers/unit_setting.vue b/src/components/settings_modal/helpers/size_setting.vue similarity index 72% rename from src/components/settings_modal/helpers/unit_setting.vue rename to src/components/settings_modal/helpers/size_setting.vue index 40ab68801..6c3fbaeba 100644 --- a/src/components/settings_modal/helpers/unit_setting.vue +++ b/src/components/settings_modal/helpers/size_setting.vue @@ -1,7 +1,7 @@ - + diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index fbace15df..7c37f0bcb 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -1,7 +1,6 @@ import { filter, trim, debounce } from 'lodash' import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' -import UnitSetting from '../helpers/unit_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' @@ -20,7 +19,6 @@ const FilteringTab = { components: { BooleanSetting, ChoiceSetting, - UnitSetting, IntegerSetting }, computed: { diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index c86810d5b..89fdef1a8 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -44,11 +44,6 @@ {{ $t('settings.mute_bot_posts') }} -
  • - - {{ $t('settings.mute_sensitive_posts') }} - -
  • {{ $t('settings.hide_post_stats') }} @@ -56,7 +51,7 @@
  • - {{ $t('settings.hide_actor_type_indication') }} + {{ $t('settings.hide_bot_indication') }}
  • {{ $t('settings.filtering_explanation') }}
    @@ -101,17 +96,6 @@ {{ $t('settings.hide_scrobbles') }} -
  • - - {{ $t('settings.hide_scrobbles_after') }} - -
  • ({ + key: mode, + value: mode, + label: this.$t(`settings.third_column_mode_${mode}`) + })), userPopoverAvatarActionOptions: ['close', 'zoom', 'open'].map(mode => ({ key: mode, value: mode, @@ -59,12 +64,15 @@ const GeneralTab = { ChoiceSetting, IntegerSetting, FloatSetting, - UnitSetting, + SizeSetting, InterfaceLanguageSwitcher, ScopeSelector, ProfileSettingIndicator }, computed: { + horizontalUnits () { + return defaultHorizontalUnits + }, postFormats () { return this.$store.state.instance.postFormats || [] }, @@ -75,6 +83,23 @@ const GeneralTab = { label: this.$t(`post_status.content_type["${format}"]`) })) }, + columns () { + const mode = this.$store.getters.mergedConfig.thirdColumnMode + + const notif = mode === 'none' ? [] : ['notifs'] + + if (this.$store.getters.mergedConfig.sidebarRight || mode === 'postform') { + return [...notif, 'content', 'sidebar'] + } else { + return ['sidebar', 'content', ...notif] + } + }, + instanceSpecificPanelPresent () { return this.$store.state.instance.showInstanceSpecificPanel }, + instanceWallpaperUsed () { + return this.$store.state.instance.background && + !this.$store.state.users.currentUser.background_image + }, + instanceShoutboxPresent () { return this.$store.state.instance.shoutAvailable }, language: { get: function () { return this.$store.getters.mergedConfig.interfaceLanguage }, set: function (val) { diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index 82d5da89c..f56fa8e0e 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -15,6 +15,11 @@ {{ $t('settings.hide_isp') }} +
  • + + {{ $t('settings.hide_wallpaper') }} + +
  • {{ $t('settings.stop_gifs') }} @@ -93,6 +98,53 @@ {{ $t('settings.hide_shoutbox') }}
  • +
  • +

    {{ $t('settings.columns') }}

    +
  • +
  • + + {{ $t('settings.disable_sticky_headers') }} + +
  • +
  • + + {{ $t('settings.show_scrollbars') }} + +
  • +
  • + + {{ $t('settings.right_sidebar') }} + +
  • +
  • + + {{ $t('settings.navbar_column_stretch') }} + +
  • +
  • + + {{ $t('settings.third_column_mode') }} + +
  • +
  • + {{ $t('settings.column_sizes') }} +
    + + {{ $t('settings.column_sizes_' + column) }} + +
    +
  • {{ $t('settings.confirm_dialogs') }}
  • - + {{ $t('settings.notification_setting_unseen_at_top') }}
  • @@ -41,9 +38,7 @@
  • {{ $t('settings.notification_visibility') }}

    -

    - {{ $t('settings.notification_setting_filters_chrome_push') }} -

    +

    {{ $t('settings.notification_setting_filters_chrome_push') }}

  • -
  • -

    {{ $t('settings.notification_visibility_statuses') }}

    - -
  • {{ $t('settings.notification_visibility_likes') }}