sss -> sc

This commit is contained in:
Henry Jameson 2026-02-13 13:59:00 +02:00
commit 29e71c8a26
13 changed files with 204 additions and 128 deletions

View file

@ -13,7 +13,7 @@ import SideDrawer from '../side_drawer/side_drawer.vue'
import { useAnnouncementsStore } from 'src/stores/announcements.js' import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -75,15 +75,15 @@ const MobileNav = {
return this.$route.name === 'chat' return this.$route.name === 'chat'
}, },
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']), ...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
...mapState(useServerSideStorageStore, { ...mapState(useSyncConfigStore, {
pinnedItems: (store) => pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'), new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'),
}), }),
shouldConfirmLogout() { shouldConfirmLogout() {
return this.$store.getters.mergedConfig.modalOnLogout return useSyncConfigStore().mergedConfig.modalOnLogout
}, },
closingDrawerMarksAsSeen() { closingDrawerMarksAsSeen() {
return this.$store.getters.mergedConfig.closingDrawerMarksAsSeen return useSyncConfigStore().mergedConfig.closingDrawerMarksAsSeen
}, },
...mapGetters(['unreadChatCount']), ...mapGetters(['unreadChatCount']),
}, },

View file

@ -12,7 +12,7 @@ import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import { useAnnouncementsStore } from 'src/stores/announcements' import { useAnnouncementsStore } from 'src/stores/announcements'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -84,28 +84,28 @@ const NavPanel = {
this.editMode = !this.editMode this.editMode = !this.editMode
}, },
toggleCollapse() { toggleCollapse() {
useServerSideStorageStore().setPreference({ useSyncConfigStore().setPreference({
path: 'simple.collapseNav', path: 'simple.collapseNav',
value: !this.collapsed, value: !this.collapsed,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
isPinned(item) { isPinned(item) {
return this.pinnedItems.has(item) return this.pinnedItems.has(item)
}, },
togglePin(item) { togglePin(item) {
if (this.isPinned(item)) { if (this.isPinned(item)) {
useServerSideStorageStore().removeCollectionPreference({ useSyncConfigStore().removeCollectionPreference({
path: 'collections.pinnedNavItems', path: 'collections.pinnedNavItems',
value: item, value: item,
}) })
} else { } else {
useServerSideStorageStore().addCollectionPreference({ useSyncConfigStore().addCollectionPreference({
path: 'collections.pinnedNavItems', path: 'collections.pinnedNavItems',
value: item, value: item,
}) })
} }
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
}, },
computed: { computed: {
@ -122,7 +122,7 @@ const NavPanel = {
...mapPiniaState(useInstanceStore, { ...mapPiniaState(useInstanceStore, {
privateMode: (store) => store.private, privateMode: (store) => store.private,
}), }),
...mapPiniaState(useServerSideStorageStore, { ...mapPiniaState(useSyncConfigStore, {
collapsed: (store) => store.prefsStorage.simple.collapseNav, collapsed: (store) => store.prefsStorage.simple.collapseNav,
pinnedItems: (store) => pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems), new Set(store.prefsStorage.collections.pinnedNavItems),

View file

@ -5,7 +5,7 @@ import { routeTo } from 'src/components/navigation/navigation.js'
import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue' import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue'
import { useAnnouncementsStore } from 'src/stores/announcements.js' import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faThumbtack } from '@fortawesome/free-solid-svg-icons' import { faThumbtack } from '@fortawesome/free-solid-svg-icons'
@ -23,17 +23,17 @@ const NavigationEntry = {
}, },
togglePin(value) { togglePin(value) {
if (this.isPinned(value)) { if (this.isPinned(value)) {
useServerSideStorageStore().removeCollectionPreference({ useSyncConfigStore().removeCollectionPreference({
path: 'collections.pinnedNavItems', path: 'collections.pinnedNavItems',
value, value,
}) })
} else { } else {
useServerSideStorageStore().addCollectionPreference({ useSyncConfigStore().addCollectionPreference({
path: 'collections.pinnedNavItems', path: 'collections.pinnedNavItems',
value, value,
}) })
} }
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
}, },
computed: { computed: {
@ -47,7 +47,7 @@ const NavigationEntry = {
...mapState({ ...mapState({
currentUser: (state) => state.users.currentUser, currentUser: (state) => state.users.currentUser,
}), }),
...mapPiniaState(useServerSideStorageStore, { ...mapPiniaState(useSyncConfigStore, {
pinnedItems: (store) => pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems), new Set(store.prefsStorage.collections.pinnedNavItems),
}), }),

View file

@ -18,7 +18,7 @@ import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useListsStore } from 'src/stores/lists' import { useListsStore } from 'src/stores/lists'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
@ -70,7 +70,7 @@ const NavPanel = {
...mapPiniaState(useBookmarkFoldersStore, { ...mapPiniaState(useBookmarkFoldersStore, {
bookmarks: getBookmarkFolderEntries, bookmarks: getBookmarkFolderEntries,
}), }),
...mapPiniaState(useServerSideStorageStore, { ...mapPiniaState(useSyncConfigStore, {
pinnedItems: (store) => pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems), new Set(store.prefsStorage.collections.pinnedNavItems),
}), }),

View file

@ -12,7 +12,7 @@ import UnitSetting from '../helpers/unit_setting.vue'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
const ClutterTab = { const ClutterTab = {
components: { components: {
@ -33,7 +33,7 @@ const ClutterTab = {
store.instanceIdentity.showInstanceSpecificPanel && store.instanceIdentity.showInstanceSpecificPanel &&
store.instanceIdentity.instanceSpecificPanelContent, store.instanceIdentity.instanceSpecificPanelContent,
}), }),
...mapState(useServerSideStorageStore, { ...mapState(useSyncConfigStore, {
muteFilters: (store) => muteFilters: (store) =>
Object.entries(store.prefsStorage.simple.muteFilters), Object.entries(store.prefsStorage.simple.muteFilters),
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters, muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
@ -89,10 +89,10 @@ const ClutterTab = {
}, },
}, },
methods: { methods: {
...mapActions(useServerSideStorageStore, [ ...mapActions(useSyncConfigStore, [
'setPreference', 'setPreference',
'unsetPreference', 'unsetPreference',
'pushServerSideStorage', 'pushSyncConfig',
]), ]),
getDatetimeLocal(timestamp) { getDatetimeLocal(timestamp) {
const date = new Date(timestamp) const date = new Date(timestamp)
@ -139,7 +139,7 @@ const ClutterTab = {
filter.order = this.muteFilters.length + 2 filter.order = this.muteFilters.length + 2
this.muteFiltersDraftObject[newId] = filter this.muteFiltersDraftObject[newId] = filter
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter }) this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
exportFilter(id) { exportFilter(id) {
this.exportedFilter = { ...this.muteFiltersDraftObject[id] } this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
@ -155,19 +155,19 @@ const ClutterTab = {
this.muteFiltersDraftObject[newId] = filter this.muteFiltersDraftObject[newId] = filter
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter }) this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
deleteFilter(id) { deleteFilter(id) {
delete this.muteFiltersDraftObject[id] delete this.muteFiltersDraftObject[id]
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null }) this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
purgeExpiredFilters() { purgeExpiredFilters() {
this.muteFiltersExpired.forEach(([id]) => { this.muteFiltersExpired.forEach(([id]) => {
delete this.muteFiltersDraftObject[id] delete this.muteFiltersDraftObject[id]
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null }) this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
}) })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
updateFilter(id, field, value) { updateFilter(id, field, value) {
const filter = { ...this.muteFiltersDraftObject[id] } const filter = { ...this.muteFiltersDraftObject[id] }
@ -193,7 +193,7 @@ const ClutterTab = {
path: 'simple.muteFilters.' + id, path: 'simple.muteFilters.' + id,
value: this.muteFiltersDraftObject[id], value: this.muteFiltersDraftObject[id],
}) })
this.pushServerSideStorage() this.pushSyncConfig()
this.muteFiltersDraftDirty[id] = false this.muteFiltersDraftDirty[id] = false
}, },
}, },

View file

@ -13,7 +13,7 @@ import UnitSetting from '../helpers/unit_setting.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface' import { useInterfaceStore } from 'src/stores/interface'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { import {
newExporter, newExporter,
@ -36,11 +36,11 @@ const FilteringTab = {
label: this.$t(`user_card.mute_block_${mode}`), label: this.$t(`user_card.mute_block_${mode}`),
})), })),
muteFiltersDraftObject: cloneDeep( muteFiltersDraftObject: cloneDeep(
useServerSideStorageStore().prefsStorage.simple.muteFilters, useSyncConfigStore().prefsStorage.simple.muteFilters,
), ),
muteFiltersDraftDirty: Object.fromEntries( muteFiltersDraftDirty: Object.fromEntries(
Object.entries( Object.entries(
useServerSideStorageStore().prefsStorage.simple.muteFilters, useSyncConfigStore().prefsStorage.simple.muteFilters,
).map(([k]) => [k, false]), ).map(([k]) => [k, false]),
), ),
exportedFilter: null, exportedFilter: null,
@ -92,7 +92,7 @@ const FilteringTab = {
}, },
computed: { computed: {
...SharedComputedObject(), ...SharedComputedObject(),
...mapState(useServerSideStorageStore, { ...mapState(useSyncConfigStore, {
muteFilters: (store) => muteFilters: (store) =>
Object.entries(store.prefsStorage.simple.muteFilters), Object.entries(store.prefsStorage.simple.muteFilters),
muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters, muteFiltersObject: (store) => store.prefsStorage.simple.muteFilters,
@ -149,10 +149,10 @@ const FilteringTab = {
}, },
}, },
methods: { methods: {
...mapActions(useServerSideStorageStore, [ ...mapActions(useSyncConfigStore, [
'setPreference', 'setPreference',
'unsetPreference', 'unsetPreference',
'pushServerSideStorage', 'pushSyncConfig',
]), ]),
getDatetimeLocal(timestamp) { getDatetimeLocal(timestamp) {
const date = new Date(timestamp) const date = new Date(timestamp)
@ -199,7 +199,7 @@ const FilteringTab = {
filter.order = this.muteFilters.length + 2 filter.order = this.muteFilters.length + 2
this.muteFiltersDraftObject[newId] = filter this.muteFiltersDraftObject[newId] = filter
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter }) this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
exportFilter(id) { exportFilter(id) {
this.exportedFilter = { ...this.muteFiltersDraftObject[id] } this.exportedFilter = { ...this.muteFiltersDraftObject[id] }
@ -215,19 +215,19 @@ const FilteringTab = {
this.muteFiltersDraftObject[newId] = filter this.muteFiltersDraftObject[newId] = filter
this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter }) this.setPreference({ path: 'simple.muteFilters.' + newId, value: filter })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
deleteFilter(id) { deleteFilter(id) {
delete this.muteFiltersDraftObject[id] delete this.muteFiltersDraftObject[id]
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null }) this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
purgeExpiredFilters() { purgeExpiredFilters() {
this.muteFiltersExpired.forEach(([id]) => { this.muteFiltersExpired.forEach(([id]) => {
delete this.muteFiltersDraftObject[id] delete this.muteFiltersDraftObject[id]
this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null }) this.unsetPreference({ path: 'simple.muteFilters.' + id, value: null })
}) })
this.pushServerSideStorage() this.pushSyncConfig()
}, },
updateFilter(id, field, value) { updateFilter(id, field, value) {
const filter = { ...this.muteFiltersDraftObject[id] } const filter = { ...this.muteFiltersDraftObject[id] }
@ -253,7 +253,7 @@ const FilteringTab = {
path: 'simple.muteFilters.' + id, path: 'simple.muteFilters.' + id,
value: this.muteFiltersDraftObject[id], value: this.muteFiltersDraftObject[id],
}) })
this.pushServerSideStorage() this.pushSyncConfig()
this.muteFiltersDraftDirty[id] = false this.muteFiltersDraftDirty[id] = false
}, },
}, },

View file

@ -22,7 +22,7 @@ import UserPopover from '../user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@ -259,9 +259,7 @@ const Status = {
}, },
muteFilterHits() { muteFilterHits() {
return muteFilterHits( return muteFilterHits(
Object.values( Object.values(useSyncConfigStore().prefsStorage.simple.muteFilters),
useServerSideStorageStore().prefsStorage.simple.muteFilters,
),
this.status, this.status,
) )
}, },

View file

@ -5,7 +5,7 @@ import Popover from 'src/components/popover/popover.vue'
import ActionButtonContainer from './action_button_container.vue' import ActionButtonContainer from './action_button_container.vue'
import { BUTTONS } from './buttons_definitions.js' import { BUTTONS } from './buttons_definitions.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js' import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
@ -36,7 +36,7 @@ const StatusActionButtons = {
ActionButtonContainer, ActionButtonContainer,
}, },
computed: { computed: {
...mapState(useServerSideStorageStore, { ...mapState(useSyncConfigStore, {
pinnedItems: (store) => pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedStatusActions), new Set(store.prefsStorage.collections.pinnedStatusActions),
}), }),
@ -111,18 +111,18 @@ const StatusActionButtons = {
return this.pinnedItems.has(button.name) return this.pinnedItems.has(button.name)
}, },
unpin(button) { unpin(button) {
useServerSideStorageStore().removeCollectionPreference({ useSyncConfigStore().removeCollectionPreference({
path: 'collections.pinnedStatusActions', path: 'collections.pinnedStatusActions',
value: button.name, value: button.name,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
pin(button) { pin(button) {
useServerSideStorageStore().addCollectionPreference({ useSyncConfigStore().addCollectionPreference({
path: 'collections.pinnedStatusActions', path: 'collections.pinnedStatusActions',
value: button.name, value: button.name,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
getComponent(button) { getComponent(button) {
if (!this.$store.state.users.currentUser && button.anonLink) { if (!this.$store.state.users.currentUser && button.anonLink) {

View file

@ -1,7 +1,7 @@
import Modal from 'src/components/modal/modal.vue' import Modal from 'src/components/modal/modal.vue'
import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceStore } from 'src/stores/instance.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png' import pleromaTanFoxMask from 'src/assets/pleromatan_apology_fox_mask.png'
import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png' import pleromaTanMask from 'src/assets/pleromatan_apology_mask.png'
@ -41,9 +41,9 @@ const UpdateNotification = {
return ( return (
!useInstanceStore().disableUpdateNotification && !useInstanceStore().disableUpdateNotification &&
this.$store.state.users.currentUser && this.$store.state.users.currentUser &&
useServerSideStorageStore().flagStorage.updateCounter < useSyncConfigStore().flagStorage.updateCounter <
CURRENT_UPDATE_COUNTER && CURRENT_UPDATE_COUNTER &&
!useServerSideStorageStore().prefsStorage.simple.dontShowUpdateNotifs !useSyncConfigStore().prefsStorage.simple.dontShowUpdateNotifs
) )
}, },
}, },
@ -53,22 +53,22 @@ const UpdateNotification = {
}, },
neverShowAgain() { neverShowAgain() {
this.toggleShow() this.toggleShow()
useServerSideStorageStore().setFlag({ useSyncConfigStore().setFlag({
flag: 'updateCounter', flag: 'updateCounter',
value: CURRENT_UPDATE_COUNTER, value: CURRENT_UPDATE_COUNTER,
}) })
useServerSideStorageStore().setPreference({ useSyncConfigStore().setPreference({
path: 'simple.dontShowUpdateNotifs', path: 'simple.dontShowUpdateNotifs',
value: true, value: true,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
dismiss() { dismiss() {
useServerSideStorageStore().setFlag({ useSyncConfigStore().setFlag({
flag: 'updateCounter', flag: 'updateCounter',
value: CURRENT_UPDATE_COUNTER, value: CURRENT_UPDATE_COUNTER,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}, },
}, },
mounted() { mounted() {

View file

@ -10,7 +10,7 @@ import {
} from '../services/notification_utils/notification_utils.js' } from '../services/notification_utils/notification_utils.js'
import { useReportsStore } from 'src/stores/reports.js' import { useReportsStore } from 'src/stores/reports.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage.js' import { useSyncConfigStore } from 'src/stores/sync_config.js'
const emptyNotifications = () => ({ const emptyNotifications = () => ({
desktopNotificationSilence: true, desktopNotificationSilence: true,
@ -119,9 +119,7 @@ export const notifications = {
maybeShowNotification( maybeShowNotification(
store, store,
Object.values( Object.values(useSyncConfigStore().prefsStorage.simple.muteFilters),
useServerSideStorageStore().prefsStorage.simple.muteFilters,
),
notification, notification,
) )
} else if (notification.seen) { } else if (notification.seen) {

View file

@ -26,7 +26,7 @@ import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js' import { useInterfaceStore } from 'src/stores/interface.js'
import { useOAuthStore } from 'src/stores/oauth.js' import { useOAuthStore } from 'src/stores/oauth.js'
import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { declarations } from 'src/modules/config_declaration' import { declarations } from 'src/modules/config_declaration'
@ -682,7 +682,7 @@ const users = {
useInterfaceStore().setLastTimeline('public-timeline') useInterfaceStore().setLastTimeline('public-timeline')
useInterfaceStore().setLayoutWidth(windowWidth()) useInterfaceStore().setLayoutWidth(windowWidth())
useInterfaceStore().setLayoutHeight(windowHeight()) useInterfaceStore().setLayoutHeight(windowHeight())
store.commit('clearServerSideStorage') //useSyncConfigStore().clearSyncConfig()
}) })
}, },
loginUser(store, accessToken) { loginUser(store, accessToken) {
@ -702,7 +702,7 @@ const users = {
user.domainMutes = [] user.domainMutes = []
commit('setCurrentUser', user) commit('setCurrentUser', user)
useServerSideStorageStore().setServerSideStorage(user) useSyncConfigStore().setSyncConfig(user)
commit('addNewUsers', [user]) commit('addNewUsers', [user])
useEmojiStore().fetchEmoji() useEmojiStore().fetchEmoji()
@ -723,17 +723,16 @@ const users = {
/* /*
// Reset wordfilter // Reset wordfilter
Object.keys( Object.keys(
useServerSideStorageStore().prefsStorage.simple.muteFilters useSyncConfigStore().prefsStorage.simple.muteFilters
).forEach(key => { ).forEach(key => {
useServerSideStorageStore().unsetPreference({ path: 'simple.muteFilters.' + key, value: null }) useSyncConfigStore().unsetPreference({ path: 'simple.muteFilters.' + key, value: null })
}) })
// Reset flag to 0 to re-run migrations // Reset flag to 0 to re-run migrations
useServerSideStorageStore().setFlag({ flag: 'configMigration', value: 0 }) useSyncConfigStore().setFlag({ flag: 'configMigration', value: 0 })
/**/ /**/
const { configMigration } = const { configMigration } = useSyncConfigStore().flagStorage
useServerSideStorageStore().flagStorage
declarations declarations
.filter((x) => { .filter((x) => {
return ( return (
@ -744,12 +743,12 @@ const users = {
}) })
.toSorted((a, b) => a.configMigration - b.configMigration) .toSorted((a, b) => a.configMigration - b.configMigration)
.forEach((value) => { .forEach((value) => {
value.migration(useServerSideStorageStore(), store.rootState) value.migration(useSyncConfigStore(), store.rootState)
useServerSideStorageStore().setFlag({ useSyncConfigStore().setFlag({
flag: 'configMigration', flag: 'configMigration',
value: value.migrationNum, value: value.migrationNum,
}) })
useServerSideStorageStore().pushServerSideStorage() useSyncConfigStore().pushSyncConfig()
}) })
if (user.token) { if (user.token) {

View file

@ -17,7 +17,11 @@ import { toRaw } from 'vue'
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js' import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
export const VERSION = 1 import { useInstanceStore } from 'src/stores/instance'
import { defaultState as configDefaultState } from 'src/modules/default_config_state'
export const VERSION = 2
export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically
export const COMMAND_TRIM_FLAGS = 1000 export const COMMAND_TRIM_FLAGS = 1000
@ -41,6 +45,7 @@ export const defaultState = {
dontShowUpdateNotifs: false, dontShowUpdateNotifs: false,
collapseNav: false, collapseNav: false,
muteFilters: {}, muteFilters: {},
...configDefaultState,
}, },
collections: { collections: {
pinnedStatusActions: ['reply', 'retweet', 'favorite', 'emoji'], pinnedStatusActions: ['reply', 'retweet', 'favorite', 'emoji'],
@ -128,13 +133,13 @@ export const _getRecentData = (cache, live, isTest) => {
live._version === cache._version live._version === cache._version
) { ) {
console.debug( console.debug(
'Same version/timestamp on both source, source of truth irrelevant', 'Same version/timestamp on both sources, source of truth irrelevant',
) )
result.recent = cache result.recent = cache
result.stale = live result.stale = live
} else { } else {
console.debug( console.debug(
'Different timestamp, figuring out which one is more recent', 'Different timestamp or version, figuring out which one is more recent',
) )
if (live._timestamp < cache._timestamp) { if (live._timestamp < cache._timestamp) {
result.recent = cache result.recent = cache
@ -208,7 +213,7 @@ const _mergeJournal = (...journals) => {
// side effect // side effect
journal.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1)) journal.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
if (path.startsWith('collections')) { if (path.startsWith('collections') || path.startsWith('objectCollection')) {
const lastRemoveIndex = findLastIndex( const lastRemoveIndex = findLastIndex(
journal, journal,
({ operation }) => operation === 'removeFromCollection', ({ operation }) => operation === 'removeFromCollection',
@ -229,6 +234,7 @@ const _mergeJournal = (...journals) => {
return false return false
} }
if (a.operation === 'addToCollection') { if (a.operation === 'addToCollection') {
// TODO check how objectCollections behaves here
return a.args[0] === b.args[0] return a.args[0] === b.args[0]
} }
return false return false
@ -368,21 +374,21 @@ export const _resetFlags = (
return result return result
} }
export const _doMigrations = (cache) => { export const _doMigrations = (cache, live) => {
if (!cache) return cache const data = cache ?? live
if (cache._version < VERSION) { if (data._version < VERSION) {
console.debug( console.debug(
'Local cached data has older version, seeing if there any migrations that can be applied', 'Data has older version, seeing if there any migrations that can be applied',
) )
// no migrations right now since we only have one version // no migrations right now since we only have one version
console.debug('No migrations found') console.debug('No migrations found')
} }
if (cache._version > VERSION) { if (data._version > VERSION) {
console.debug( console.debug(
'Local cached data has newer version, seeing if there any reverse migrations that can be applied', 'Data has newer version, seeing if there any reverse migrations that can be applied',
) )
// no reverse migrations right now but we leave a possibility of loading a hotpatch if need be // no reverse migrations right now but we leave a possibility of loading a hotpatch if need be
@ -391,9 +397,9 @@ export const _doMigrations = (cache) => {
console.debug('Found hotpatch migration, applying') console.debug('Found hotpatch migration, applying')
return window._PLEROMA_HOTPATCH.reverseMigrations.call( return window._PLEROMA_HOTPATCH.reverseMigrations.call(
{}, {},
'serverSideStorage', 'syncConfigStore',
{ from: cache._version, to: VERSION }, { from: data._version, to: VERSION },
cache, data,
) )
} }
} }
@ -402,7 +408,7 @@ export const _doMigrations = (cache) => {
return cache return cache
} }
export const useServerSideStorageStore = defineStore('serverSideStorage', { export const useSyncConfigStore = defineStore('sync_config', {
state() { state() {
return cloneDeep(defaultState) return cloneDeep(defaultState)
}, },
@ -510,19 +516,40 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
`tried to edit internal (starts with _) field '${path}', ignoring.`, `tried to edit internal (starts with _) field '${path}', ignoring.`,
) )
} }
const collection = new Set(get(this.prefsStorage, path))
collection.delete(value) const { _key } = value
set(this.prefsStorage, path, [...collection]) if (path.startsWith('collection')) {
this.prefsStorage._journal = [ const collection = new Set(get(this.prefsStorage, path))
...this.prefsStorage._journal, collection.delete(value)
{ set(this.prefsStorage, path, [...collection])
operation: 'removeFromCollection',
path, this.prefsStorage._journal = [
args: [value], ...this.prefsStorage._journal,
timestamp: Date.now(), {
}, operation: 'removeFromCollection',
] path,
this.dirty = true args: [value],
timestamp: Date.now(),
},
]
this.dirty = true
} else if (path.startsWith('objectCollection')) {
const collection = new Set(get(this.prefsStorage, path + '.index'))
collection.delete(_key)
set(this.prefsStorage, path + '.index', [...collection])
const data = get(this.prefsStorage, path + '.data')
delete data[_key]
this.prefsStorage._journal = [
...this.prefsStorage._journal,
{
operation: 'removeFromCollection',
path,
args: [{ _key }],
timestamp: Date.now(),
},
]
}
}, },
reorderCollectionPreference({ path, value, movement }) { reorderCollectionPreference({ path, value, movement }) {
if (path.startsWith('_')) { if (path.startsWith('_')) {
@ -554,24 +581,23 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
username, username,
) )
}, },
clearServerSideStorage() { clearSyncConfig() {
const blankState = { ...cloneDeep(defaultState) } const blankState = { ...cloneDeep(defaultState) }
Object.keys(this).forEach((k) => { Object.keys(this).forEach((k) => {
this[k] = blankState[k] this[k] = blankState[k]
}) })
}, },
setServerSideStorage(userData) { setSyncConfig(userData) {
const live = userData.storage const live = userData.storage
this.raw = live this.raw = live
let cache = this.cache let cache = this.cache
if (cache && cache._user !== userData.fqn) { if (cache?._user !== userData.fqn) {
console.warn( console.warn(
'Cache belongs to another user! reinitializing local cache!', 'Cache belongs to another user! reinitializing local cache!',
) )
cache = null cache = null
} }
console.log(cache, live)
cache = _doMigrations(cache)
let { recent, stale, needUpload } = _getRecentData(cache, live) let { recent, stale, needUpload } = _getRecentData(cache, live)
@ -589,6 +615,9 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
}) })
} }
recent = recent && _doMigrations(recent)
stale = stale && _doMigrations(stale)
if (!needUpload && recent && stale) { if (!needUpload && recent && stale) {
console.debug('Checking if data needs merging...') console.debug('Checking if data needs merging...')
// discarding timestamps and versions // discarding timestamps and versions
@ -627,7 +656,7 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
this.flagStorage = this.cache.flagStorage this.flagStorage = this.cache.flagStorage
this.prefsStorage = this.cache.prefsStorage this.prefsStorage = this.cache.prefsStorage
}, },
pushServerSideStorage({ force = false } = {}) { pushSyncConfig({ force = false } = {}) {
const needPush = this.dirty || force const needPush = this.dirty || force
if (!needPush) return if (!needPush) return
this.updateCache({ username: window.vuex.state.users.currentUser.fqn }) this.updateCache({ username: window.vuex.state.users.currentUser.fqn })
@ -635,9 +664,26 @@ export const useServerSideStorageStore = defineStore('serverSideStorage', {
window.vuex.state.api.backendInteractor window.vuex.state.api.backendInteractor
.updateProfileJSON({ params }) .updateProfileJSON({ params })
.then((user) => { .then((user) => {
this.setServerSideStorage(user) this.setSyncConfig(user)
this.dirty = false this.dirty = false
}) })
}, },
}, },
getters: {
mergedConfig: (state) => {
const instancePrefs = useInstanceStore().prefsStorage
const result = Object.fromEntries(
Object.entries(state.prefsStorage.simple).map(([k, v]) => [
k,
v ?? instancePrefs[k],
]),
)
return result
},
},
persist: {
afterLoad(state) {
return state
},
},
}) })

View file

@ -12,25 +12,25 @@ import {
COMMAND_TRIM_FLAGS_AND_RESET, COMMAND_TRIM_FLAGS_AND_RESET,
defaultState, defaultState,
newUserFlags, newUserFlags,
useServerSideStorageStore, useSyncConfigStore,
VERSION, VERSION,
} from 'src/stores/serverSideStorage.js' } from 'src/stores/sync_config.js'
describe('The serverSideStorage module', () => { describe('The SyncConfig module', () => {
beforeEach(() => { beforeEach(() => {
setActivePinia(createPinia()) setActivePinia(createPinia())
}) })
describe('mutations', () => { describe('mutations', () => {
describe('setServerSideStorage', () => { describe('setSyncConfig', () => {
const user = { const user = {
created_at: new Date('1999-02-09'), created_at: new Date('1999-02-09'),
storage: {}, storage: {},
} }
it('should initialize storage if none present', () => { it('should initialize storage if none present', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setServerSideStorage(store, user) store.setSyncConfig({ ...user })
expect(store.cache._version).to.eql(VERSION) expect(store.cache._version).to.eql(VERSION)
expect(store.cache._timestamp).to.be.a('number') expect(store.cache._timestamp).to.be.a('number')
expect(store.cache.flagStorage).to.eql(defaultState.flagStorage) expect(store.cache.flagStorage).to.eql(defaultState.flagStorage)
@ -38,8 +38,8 @@ describe('The serverSideStorage module', () => {
}) })
it('should initialize storage with proper flags for new users if none present', () => { it('should initialize storage with proper flags for new users if none present', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setServerSideStorage({ ...user, created_at: new Date() }) store.setSyncConfig({ ...user, created_at: new Date() })
expect(store.cache._version).to.eql(VERSION) expect(store.cache._version).to.eql(VERSION)
expect(store.cache._timestamp).to.be.a('number') expect(store.cache._timestamp).to.be.a('number')
expect(store.cache.flagStorage).to.eql(newUserFlags) expect(store.cache.flagStorage).to.eql(newUserFlags)
@ -47,14 +47,14 @@ describe('The serverSideStorage module', () => {
}) })
it('should merge flags even if remote timestamp is older', () => { it('should merge flags even if remote timestamp is older', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.cache = { store.cache = {
_timestamp: Date.now(), _timestamp: Date.now(),
_version: VERSION, _version: VERSION,
...cloneDeep(defaultState), ...cloneDeep(defaultState),
} }
store.setServerSideStorage({ store.setSyncConfig({
...user, ...user,
storage: { storage: {
_timestamp: 123, _timestamp: 123,
@ -76,10 +76,10 @@ describe('The serverSideStorage module', () => {
}) })
it('should reset local timestamp to remote if contents are the same', () => { it('should reset local timestamp to remote if contents are the same', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.cache = null store.cache = null
store.setServerSideStorage({ store.setSyncConfig({
...user, ...user,
storage: { storage: {
_timestamp: 123, _timestamp: 123,
@ -95,9 +95,9 @@ describe('The serverSideStorage module', () => {
expect(store.cache.flagStorage.updateCounter).to.eql(999) expect(store.cache.flagStorage.updateCounter).to.eql(999)
}) })
it('should remote version if local missing', () => { it('should use remote version if local missing', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setServerSideStorage(store, user) store.setSyncConfig(store, user)
expect(store.cache._version).to.eql(VERSION) expect(store.cache._version).to.eql(VERSION)
expect(store.cache._timestamp).to.be.a('number') expect(store.cache._timestamp).to.be.a('number')
expect(store.cache.flagStorage).to.eql(defaultState.flagStorage) expect(store.cache.flagStorage).to.eql(defaultState.flagStorage)
@ -105,7 +105,7 @@ describe('The serverSideStorage module', () => {
}) })
describe('setPreference', () => { describe('setPreference', () => {
it('should set preference and update journal log accordingly', () => { it('should set preference and update journal log accordingly', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 1 })
expect(store.prefsStorage.simple.testing).to.eql(1) expect(store.prefsStorage.simple.testing).to.eql(1)
expect(store.prefsStorage._journal.length).to.eql(1) expect(store.prefsStorage._journal.length).to.eql(1)
@ -119,18 +119,34 @@ describe('The serverSideStorage module', () => {
}) })
it('should keep journal to a minimum', () => { it('should keep journal to a minimum', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 1 })
store.setPreference({ path: 'simple.testing', value: 2 }) store.setPreference({ path: 'simple.testing', value: 2 })
store.addCollectionPreference({ path: 'collections.testing', value: 2 }) store.addCollectionPreference({ path: 'collections.testing', value: 2 })
store.addCollectionPreference({
path: 'objectCollections.testing',
value: { _key: 'a', foo: 1 },
})
expect(store.prefsStorage.objectCollections.testing).to.eql({
data: { a: { _key: 'a', foo: 1 } },
index: ['a'],
})
store.removeCollectionPreference({ store.removeCollectionPreference({
path: 'collections.testing', path: 'collections.testing',
value: 2, value: 2,
}) })
store.removeCollectionPreference({
path: 'objectCollections.testing',
value: { _key: 'a' },
})
store.updateCache({ username: 'test' }) store.updateCache({ username: 'test' })
expect(store.prefsStorage.simple.testing).to.eql(2) expect(store.prefsStorage.simple.testing).to.eql(2)
expect(store.prefsStorage.collections.testing).to.eql([]) expect(store.prefsStorage.collections.testing).to.eql([])
expect(store.prefsStorage._journal.length).to.eql(2) expect(store.prefsStorage.objectCollections.testing).to.eql({
data: {},
index: [],
})
expect(store.prefsStorage._journal.length).to.eql(3)
expect(store.prefsStorage._journal[0]).to.eql({ expect(store.prefsStorage._journal[0]).to.eql({
path: 'simple.testing', path: 'simple.testing',
operation: 'set', operation: 'set',
@ -145,22 +161,41 @@ describe('The serverSideStorage module', () => {
// should have A timestamp, we don't really care what it is // should have A timestamp, we don't really care what it is
timestamp: store.prefsStorage._journal[1].timestamp, timestamp: store.prefsStorage._journal[1].timestamp,
}) })
expect(store.prefsStorage._journal[2]).to.eql({
path: 'objectCollections.testing',
operation: 'removeFromCollection',
args: [{ _key: 'a' }],
// should have A timestamp, we don't really care what it is
timestamp: store.prefsStorage._journal[2].timestamp,
})
}) })
it('should remove duplicate entries from journal', () => { it('should remove duplicate entries from journal', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 1 })
store.setPreference({ path: 'simple.testing', value: 1 }) store.setPreference({ path: 'simple.testing', value: 1 })
store.addCollectionPreference({ path: 'collections.testing', value: 2 }) store.addCollectionPreference({ path: 'collections.testing', value: 2 })
store.addCollectionPreference({ path: 'collections.testing', value: 2 }) store.addCollectionPreference({ path: 'collections.testing', value: 2 })
store.addCollectionPreference({
path: 'objectCollections.testing',
value: { _key: 'a', foo: 1 },
})
store.addCollectionPreference({
path: 'objectCollections.testing',
value: { _key: 'a', foo: 1 },
})
store.updateCache({ username: 'test' }) store.updateCache({ username: 'test' })
expect(store.prefsStorage.simple.testing).to.eql(1) expect(store.prefsStorage.simple.testing).to.eql(1)
expect(store.prefsStorage.collections.testing).to.eql([2]) expect(store.prefsStorage.collections.testing).to.eql([2])
expect(store.prefsStorage._journal.length).to.eql(2) expect(store.prefsStorage.objectCollections.testing).to.eql({
data: { a: { _key: 'a', foo: 1 } },
index: ['a'],
})
expect(store.prefsStorage._journal.length).to.eql(4)
}) })
it('should remove depth = 3 set/unset entries from journal', () => { it('should remove depth = 3 set/unset entries from journal', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.object.foo', value: 1 }) store.setPreference({ path: 'simple.object.foo', value: 1 })
store.unsetPreference({ path: 'simple.object.foo' }) store.unsetPreference({ path: 'simple.object.foo' })
store.updateCache(store, { username: 'test' }) store.updateCache(store, { username: 'test' })
@ -169,7 +204,7 @@ describe('The serverSideStorage module', () => {
}) })
it('should not allow unsetting depth <= 2', () => { it('should not allow unsetting depth <= 2', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.object.foo', value: 1 }) store.setPreference({ path: 'simple.object.foo', value: 1 })
expect(() => store.unsetPreference({ path: 'simple' })).to.throw() expect(() => store.unsetPreference({ path: 'simple' })).to.throw()
expect(() => expect(() =>
@ -178,7 +213,7 @@ describe('The serverSideStorage module', () => {
}) })
it('should not allow (un)setting depth > 3', () => { it('should not allow (un)setting depth > 3', () => {
const store = useServerSideStorageStore() const store = useSyncConfigStore()
store.setPreference({ path: 'simple.object', value: {} }) store.setPreference({ path: 'simple.object', value: {} })
expect(() => expect(() =>
store.setPreference({ path: 'simple.object.lv3', value: 1 }), store.setPreference({ path: 'simple.object.lv3', value: 1 }),