diff --git a/src/App.js b/src/App.js
index 33645c63d..2af10cc8b 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,7 +1,9 @@
import { throttle } from 'lodash'
+import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
@@ -184,9 +186,6 @@ export default {
shoutboxPosition() {
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
},
- hideShoutbox() {
- return this.$store.getters.mergedConfig.hideShoutbox
- },
layoutType() {
return useInterfaceStore().layoutType
},
@@ -214,6 +213,9 @@ export default {
return window /* this.$refs.appContentRef */
},
...mapGetters(['mergedConfig']),
+ ...mapState(useServerSideStorageStore, {
+ hideShoutbox: (store) => store.prefsStorage.simple.hideShoutbox,
+ }),
},
methods: {
resizeHandler() {
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 396aa94f0..a073a5eb8 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -8,6 +8,7 @@ import Popover from 'src/components/popover/popover.vue'
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js'
import fileTypeService from '../../services/file_type/file_type.service.js'
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
@@ -299,10 +300,11 @@ const PostStatusForm = {
return this.hasStatusLengthLimit && this.charactersLeft < 0
},
minimalScopesMode() {
- return this.$store.state.instance.minimalScopesMode
+ return useServerSideStorageStore().prefsStorage.simple.minimalScopesMode
},
alwaysShowSubject() {
- return this.mergedConfig.alwaysShowSubjectInput
+ return useServerSideStorageStore().prefsStorage.simple
+ .alwaysShowSubjectInput
},
postFormats() {
return this.$store.state.instance.postFormats || []
diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js
index c77de92b1..06ed9b2f6 100644
--- a/src/components/settings_modal/helpers/setting.js
+++ b/src/components/settings_modal/helpers/setting.js
@@ -1,5 +1,6 @@
import { cloneDeep, get, isEqual, set } from 'lodash'
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import DraftButtons from './draft_buttons.vue'
import ModifiedIndicator from './modified_indicator.vue'
import ProfileSettingIndicator from './profile_setting_indicator.vue'
@@ -226,6 +227,8 @@ export default {
},
configSource() {
switch (this.realSource) {
+ case 'server-side':
+ return useServerSideStorageStore().prefsStorage
case 'profile':
return this.$store.state.profileConfig
case 'admin':
@@ -239,6 +242,39 @@ export default {
return (k, v) => this.$emit('update:modelValue', v)
}
switch (this.realSource) {
+ case 'server-side': {
+ return (path, value, operator) => {
+ const folder = path.split('.')[0]
+ if (folder === 'collections' || folder === 'objectCollections') {
+ switch (operator) {
+ case 'add':
+ useServerSideStorageStore().addCollectionPreference({
+ path,
+ value,
+ })
+ useServerSideStorageStore().pushServerSideStorage()
+ break
+ case 'remove':
+ useServerSideStorageStore().removeCollectionPreference({
+ path,
+ value,
+ })
+ useServerSideStorageStore().pushServerSideStorage()
+ break
+ default:
+ console.error(
+ `Unknown server-side collection operator ${operator}, ignoring`,
+ )
+ break
+ }
+ } else if (folder === 'simple') {
+ useServerSideStorageStore().setPreference({ path, value })
+ useServerSideStorageStore().pushServerSideStorage()
+ } else {
+ console.error(`Unknown server-side folder ${folder}, ignoring`)
+ }
+ }
+ }
case 'profile':
return (k, v) =>
this.$store.dispatch('setProfileOption', { name: k, value: v })
@@ -262,6 +298,11 @@ export default {
switch (this.realSource) {
case 'profile':
return {}
+ case 'server-side':
+ return get(
+ this.$store.getters.defaultConfig,
+ this.path.split(/\./g).slice(1),
+ )
default:
return get(this.$store.getters.defaultConfig, this.path)
}
diff --git a/src/components/settings_modal/helpers/shared_computed_object.js b/src/components/settings_modal/helpers/shared_computed_object.js
index b8197b639..070a35b44 100644
--- a/src/components/settings_modal/helpers/shared_computed_object.js
+++ b/src/components/settings_modal/helpers/shared_computed_object.js
@@ -1,18 +1,20 @@
+import { mapState as mapPiniaState } from 'pinia'
+import { mapGetters, mapState } from 'vuex'
+
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
+
const SharedComputedObject = () => ({
- user() {
- return this.$store.state.users.currentUser
- },
+ ...mapPiniaState(useServerSideStorageStore, {
+ serverSide: (store) => store.state.prefsStorage,
+ }),
+ ...mapGetters(['mergedConfig']),
+ ...mapState({
+ adminConfig: (state) => state.adminSettings.config,
+ adminDraft: (state) => state.adminSettings.draft,
+ user: (state) => state.users.currentUser,
+ }),
expertLevel() {
- return this.$store.getters.mergedConfig.expertLevel > 0
- },
- mergedConfig() {
- return this.$store.getters.mergedConfig
- },
- adminConfig() {
- return this.$store.state.adminSettings.config
- },
- adminDraft() {
- return this.$store.state.adminSettings.draft
+ return this.mergedConfig.expertLevel > 0
},
})
diff --git a/src/components/settings_modal/tabs/clutter_tab.vue b/src/components/settings_modal/tabs/clutter_tab.vue
index daf098f5a..ef230dee0 100644
--- a/src/components/settings_modal/tabs/clutter_tab.vue
+++ b/src/components/settings_modal/tabs/clutter_tab.vue
@@ -4,41 +4,58 @@
{{ $t('settings.interface') }}
-
-
+
{{ $t('settings.subject_input_always_show') }}
-
-
+
{{ $t('settings.minimal_scopes_mode') }}
-
-
+
{{ $t('settings.hide_post_stats') }}
-
{{ $t('settings.hide_user_stats') }}
-
-
+
{{ $t('settings.hide_actor_type_indication') }}
-
-
+
{{ $t('settings.hide_scrobbles') }}
-
@@ -52,30 +69,41 @@
-
{{ $t('settings.max_thumbnails') }}
-
-
+
{{ $t('settings.hide_attachments_in_tl') }}
-
-
+
{{ $t('settings.hide_attachments_in_convo') }}
-
-
+
{{ $t('settings.user_card_hide_personal_marks') }}
-
{{ $t('settings.hide_shoutbox') }}
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 1673a6933..8cbc12c09 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -1,4 +1,5 @@
import { unescape as ldUnescape, uniqBy } from 'lodash'
+import { mapState } from 'pinia'
import MentionLink from 'src/components/mention_link/mention_link.vue'
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
@@ -254,12 +255,7 @@ const Status = {
return !!this.currentUser
},
muteFilterHits() {
- return muteFilterHits(
- Object.values(
- useServerSideStorageStore().prefsStorage.simple.muteFilters,
- ),
- this.status,
- )
+ return muteFilterHits(Object.values(this.muteFilters), this.status)
},
botStatus() {
return this.status.user.actor_type === 'Service'
@@ -452,9 +448,6 @@ const Status = {
.map((tagObj) => tagObj.name)
.join(' ')
},
- hidePostStats() {
- return this.mergedConfig.hidePostStats
- },
shouldDisplayFavsAndRepeats() {
return (
!this.hidePostStats &&
@@ -511,10 +504,10 @@ const Status = {
return this.quotedStatus && this.displayQuote
},
scrobblePresent() {
- if (this.mergedConfig.hideScrobbles) return false
+ if (this.hideScrobbles) return false
if (!this.status.user?.latestScrobble) return false
- const value = this.mergedConfig.hideScrobblesAfter.match(/\d+/gs)[0]
- const unit = this.mergedConfig.hideScrobblesAfter.match(/\D+/gs)[0]
+ const value = this.hideScrobblesAfter.match(/\d+/gs)[0]
+ const unit = this.hideScrobblesAfter.match(/\D+/gs)[0]
let multiplier = 60 * 1000 // minutes is smallest unit
switch (unit) {
case 'm':
@@ -536,6 +529,14 @@ const Status = {
scrobble() {
return this.status.user?.latestScrobble
},
+ ...mapState(useServerSideStorageStore, {
+ muteFilters: (store) => store.prefsStorage.simple.muteFilters,
+ hideBotIndicatior: (store) => store.prefsStorage.simple.hideBotIndicator,
+ hidePostStats: (store) => store.prefsStorage.simple.hidePostStats,
+ hideScrobbles: (store) => store.prefsStorage.simple.hideScrobbles,
+ hideScrobblesAfter: (store) =>
+ store.prefsStorage.simple.hideScrobblesAfter,
+ }),
},
methods: {
visibilityIcon(visibility) {
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 51bfe6f1e..c93423a7a 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -1,7 +1,9 @@
+import { mapState as mapPiniaState } from 'pinia'
import { mapGetters, mapState } from 'vuex'
import StatusBody from 'src/components/status_body/status_body.vue'
import { useMediaViewerStore } from 'src/stores/media_viewer'
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import Attachment from '../attachment/attachment.vue'
import Gallery from '../gallery/gallery.vue'
import LinkPreview from '../link-preview/link-preview.vue'
@@ -90,8 +92,8 @@ const StatusContent = {
},
hideAttachments() {
return (
- (this.mergedConfig.hideAttachments && !this.inConversation) ||
- (this.mergedConfig.hideAttachmentsInConv && this.inConversation)
+ (this.hideAttachments && !this.inConversation) ||
+ (this.hideAttachmentsInConv && this.inConversation)
)
},
nsfwClickthrough() {
@@ -110,21 +112,24 @@ const StatusContent = {
if (this.compact) {
return 'small'
} else if (
- (this.mergedConfig.hideAttachments && !this.inConversation) ||
- (this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||
+ (this.hideAttachments && !this.inConversation) ||
+ (this.hideAttachmentsInConv && this.inConversation) ||
this.status.attachments.length > this.maxThumbnails
) {
return 'hide'
}
return 'normal'
},
- maxThumbnails() {
- return this.mergedConfig.maxThumbnails
- },
...mapGetters(['mergedConfig']),
...mapState({
currentUser: (state) => state.users.currentUser,
}),
+ ...mapPiniaState(useServerSideStorageStore, {
+ maxThumbnails: (store) => store.prefsStorage.simple.maxThumbnails,
+ hideAttachments: (store) => store.prefsStorage.simple.hideAttachments,
+ hideAttachmentsInConv: (store) =>
+ store.prefsStorage.simple.hideAttachmentsInConv,
+ }),
},
components: {
Attachment,
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 0786e5b35..664b70fe3 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,6 +1,7 @@
import isEqual from 'lodash/isEqual'
import merge from 'lodash/merge'
import ldUnescape from 'lodash/unescape'
+import { mapState } from 'pinia'
import { mapGetters } from 'vuex'
import Checkbox from 'src/components/checkbox/checkbox.vue'
@@ -15,6 +16,7 @@ import { propsToNative } from 'src/services/attributes_helper/attributes_helper.
import localeService from 'src/services/locale/locale.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { usePostStatusStore } from 'src/stores/post_status'
+import { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import { useInterfaceStore } from '../../stores/interface'
import { useMediaViewerStore } from '../../stores/media_viewer'
import AccountActions from '../account_actions/account_actions.vue'
@@ -217,13 +219,11 @@ export default {
},
userHighlightType: {
get() {
- const data =
- this.$store.getters.mergedConfig.highlight[this.user.screen_name]
+ const data = this.mergedConfig.highlight[this.user.screen_name]
return (data && data.type) || 'disabled'
},
set(type) {
- const data =
- this.$store.getters.mergedConfig.highlight[this.user.screen_name]
+ const data = this.mergedConfig.highlight[this.user.screen_name]
if (type !== 'disabled') {
this.$store.dispatch('setHighlight', {
user: this.user.screen_name,
@@ -237,12 +237,10 @@ export default {
})
}
},
- ...mapGetters(['mergedConfig']),
},
userHighlightColor: {
get() {
- const data =
- this.$store.getters.mergedConfig.highlight[this.user.screen_name]
+ const data = this.mergedConfig.highlight[this.user.screen_name]
return data && data.color
},
set(color) {
@@ -386,6 +384,11 @@ export default {
})
},
...mapGetters(['mergedConfig']),
+ ...mapState(useServerSideStorageStore, {
+ hideUserStats: (store) => store.prefsStorage.simple.hideUserStats,
+ userCardHidePersonalMarks: (store) =>
+ store.prefsStorage.simple.userCardHidePersonalMarks,
+ }),
},
methods: {
muteUser() {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 66529f59b..e3b061e0c 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -293,7 +293,7 @@