attempt to do migration in a different way

This commit is contained in:
Henry Jameson 2026-03-15 17:59:13 +02:00
commit de7844cbaa
3 changed files with 227 additions and 147 deletions

View file

@ -45,7 +45,6 @@ export const instanceDefaultConfig = {
muteSensitiveStatuses: false,
collapseMessageWithSubject: false,
padEmoji: true,
hideAttachments: false,
hideAttachmentsInConv: false,
hideScrobbles: false,
hideScrobblesAfter: '2d',
@ -133,19 +132,8 @@ export const instanceDefaultConfig = {
userPopoverOverlay: false,
userCardLeftJustify: false,
userCardHidePersonalMarks: false,
sidebarColumnWidth: '25rem',
contentColumnWidth: '45rem',
notifsColumnWidth: '25rem',
themeEditorMinWidth: '0rem',
emojiReactionsScale: 0.5,
textSize: '1rem',
emojiSize: '2.2rem',
navbarSize: '3.5rem',
panelHeaderSize: '3.2rem',
forcedRoundness: -1,
navbarColumnStretch: false,
greentext: false,
mentionLinkDisplay: 'short',
mentionLinkShowTooltip: true,
mentionLinkShowAvatar: false,
mentionLinkFadeDomain: true,
@ -175,8 +163,24 @@ export const instanceDefaultConfig = {
useAbsoluteTimeFormat: false,
absoluteTimeFormatMinAge: '0d',
absoluteTime12h: '24h',
imageCompression: true,
}
export const defaultConfigLocal = {
hideAttachments: false,
hideAttachmentsInConv: false,
sidebarColumnWidth: '25rem',
contentColumnWidth: '45rem',
notifsColumnWidth: '25rem',
themeEditorMinWidth: '0rem',
emojiReactionsScale: 0.5,
textSize: '1rem',
emojiSize: '2.2rem',
navbarSize: '3.5rem',
panelHeaderSize: '3.2rem',
navbarColumnStretch: false,
mentionLinkDisplay: 'short',
alwaysUseJpeg: false,
imageCompression: true,
}
export const makeUndefined = (c) =>

View file

@ -1,129 +1,187 @@
// this is a snapshot of config keys used prior to sync config.
// used to migrate from old config.
export const defaultStateKeys = [
'expertLevel',
'hideISP',
'hideInstanceWallpaper',
'hideShoutbox',
'hideMutedPosts',
'hideMutedThreads',
'hideWordFilteredPosts',
'muteBotStatuses',
'muteSensitiveStatuses',
'collapseMessageWithSubject',
'padEmoji',
'hideAttachments',
'hideAttachmentsInConv',
'hideScrobbles',
'hideScrobblesAfter',
'maxThumbnails',
'hideNsfw',
'preloadImage',
'loopVideo',
'loopVideoSilentOnly',
'streaming',
'emojiReactionsOnTimeline',
'alwaysShowNewPostButton',
'autohideFloatingPostButton',
'pauseOnUnfocused',
'stopGifs',
'replyVisibility',
'thirdColumnMode',
'notificationVisibility',
'notificationNative',
'webPushNotifications',
'webPushAlwaysShowNotifications',
'interfaceLanguage',
'hideScopeNotice',
'useStreamingApi',
'sidebarRight',
'scopeCopy',
'subjectLineBehavior',
'alwaysShowSubjectInput',
'postContentType',
'minimalScopesMode',
'hideFilteredStatuses',
'modalOnRepeat',
'modalOnUnfollow',
'modalOnBlock',
'modalOnMute',
'modalOnMuteConversation',
'modalOnMuteDomain',
'modalOnDelete',
'modalOnLogout',
'modalOnApproveFollow',
'modalOnDenyFollow',
'modalOnRemoveUserFromFollowers',
'onMuteDefaultAction',
'onBlockDefaultAction',
'modalMobileCenter',
'playVideosInModal',
'useOneClickNsfw',
'useContainFit',
'disableStickyHeaders',
'showScrollbars',
'userPopoverAvatarAction',
'userPopoverOverlay',
'userCardLeftJustify',
'userCardHidePersonalMarks',
'sidebarColumnWidth',
'contentColumnWidth',
'notifsColumnWidth',
'themeEditorMinWidth',
'emojiReactionsScale',
'textSize',
'emojiSize',
'navbarSize',
'panelHeaderSize',
'forcedRoundness',
'navbarColumnStretch',
'greentext',
'mentionLinkDisplay',
'mentionLinkShowTooltip',
'mentionLinkShowAvatar',
'mentionLinkFadeDomain',
'mentionLinkShowYous',
'mentionLinkBoldenYou',
'hidePostStats',
'hideBotIndication',
'hideUserStats',
'virtualScrolling',
'sensitiveByDefault',
'conversationDisplay',
'conversationTreeAdvanced',
'conversationOtherRepliesButton',
'conversationTreeFadeAncestors',
'showExtraNotifications',
'showExtraNotificationsTip',
'showChatsInExtraNotifications',
'showAnnouncementsInExtraNotifications',
'showFollowRequestsInExtraNotifications',
'maxDepthInThread',
'autocompleteSelect',
'closingDrawerMarksAsSeen',
'unseenAtTop',
'ignoreInactionableSeen',
'unsavedPostAction',
'autoSaveDraft',
'useAbsoluteTimeFormat',
'absoluteTimeFormatMinAge',
'absoluteTime12h',
'imageCompression',
'alwaysUseJpeg',
'theme',
'colors',
// commented entries are unsynced stuff
export const defaultConfigSync = {
expertLevel: 0, // used to track which settings to show and hide
hideISP: false,
hideInstanceWallpaper: false,
hideShoutbox: false,
// bad name: actually hides posts of muted USERS
hideMutedPosts: false,
hideMutedThreads: true,
hideWordFilteredPosts: false,
muteBotStatuses: false,
muteSensitiveStatuses: false,
collapseMessageWithSubject: false,
padEmoji: true,
hideScrobbles: false,
hideScrobblesAfter: '2d',
maxThumbnails: 16,
hideNsfw: true,
preloadImage: true,
loopVideo: true,
loopVideoSilentOnly: true,
/// This is not the streaming API configuration, but rather an option
/// for automatically loading new posts into the timeline without
/// the user clicking the Show New button.
streaming: false,
emojiReactionsOnTimeline: true,
alwaysShowNewPostButton: false,
autohideFloatingPostButton: false,
pauseOnUnfocused: true,
stopGifs: true,
replyVisibility: 'all',
thirdColumnMode: 'notifications',
notificationVisibility: {
follows: true,
mentions: true,
statuses: true,
likes: true,
repeats: true,
moves: true,
emojiReactions: true,
followRequest: true,
reports: true,
chatMention: true,
polls: true,
},
notificationNative: {
follows: true,
mentions: true,
statuses: true,
likes: false,
repeats: false,
moves: false,
emojiReactions: false,
followRequest: true,
reports: true,
chatMention: true,
polls: true,
},
webPushNotifications: false,
webPushAlwaysShowNotifications: false,
//interfaceLanguage: '',
hideScopeNotice: false,
useStreamingApi: false,
sidebarRight: false,
scopeCopy: true,
subjectLineBehavior: 'email',
alwaysShowSubjectInput: true,
postContentType: 'text/plain',
minimalScopesMode: false,
'customTheme',
'customThemeSource',
// This hides statuses filtered via a word filter
hideFilteredStatuses: false,
'style',
'styleCustomData',
'palette',
'paletteCustomData',
'themeDebug',
'forceThemeRecompilation',
'theme3hacks',
// 'muteWords', // mutes migrated separately
// 'highlight', // highlight migration is done separately
]
// Confirmations
modalOnRepeat: false,
modalOnUnfollow: false,
modalOnBlock: true,
modalOnMute: false,
modalOnMuteConversation: false,
modalOnMuteDomain: true,
modalOnDelete: true,
modalOnLogout: true,
modalOnApproveFollow: false,
modalOnDenyFollow: false,
modalOnRemoveUserFromFollowers: false,
// Expiry confirmations/default actions
onMuteDefaultAction: 'ask',
onBlockDefaultAction: 'ask',
modalMobileCenter: false,
playVideosInModal: false,
useOneClickNsfw: false,
useContainFit: true,
disableStickyHeaders: false,
showScrollbars: false,
userPopoverAvatarAction: 'open',
userPopoverOverlay: false,
userCardLeftJustify: false,
userCardHidePersonalMarks: false,
forcedRoundness: -1,
greentext: false,
mentionLinkShowTooltip: true,
mentionLinkShowAvatar: false,
mentionLinkFadeDomain: true,
mentionLinkShowYous: false,
mentionLinkBoldenYou: true,
hidePostStats: false,
hideBotIndication: false,
hideUserStats: false,
virtualScrolling: true,
sensitiveByDefault: false,
conversationDisplay: 'linear',
conversationTreeAdvanced: false,
conversationOtherRepliesButton: 'below',
conversationTreeFadeAncestors: false,
showExtraNotifications: true,
showExtraNotificationsTip: true,
showChatsInExtraNotifications: true,
showAnnouncementsInExtraNotifications: true,
showFollowRequestsInExtraNotifications: true,
maxDepthInThread: 6,
autocompleteSelect: false,
closingDrawerMarksAsSeen: true,
unseenAtTop: false,
ignoreInactionableSeen: false,
unsavedPostAction: 'confirm',
autoSaveDraft: false,
useAbsoluteTimeFormat: false,
absoluteTimeFormatMinAge: '0d',
absoluteTime12h: '24h',
theme3hacks: {
// Hacks, user overrides that are independent of theme used
underlay: 'none',
fonts: {
interface: undefined,
input: undefined,
post: undefined,
monospace: undefined,
},
},
// Special processing
// Theme stuff
theme: undefined, // Very old theme store, stores preset name, still in use
// V1
colors: {}, // VERY old theme store, just colors of V1, probably not even used anymore
// V2
customTheme: undefined, // "snapshot", previously was used as actual theme store for V2 so it's still used in case of PleromaFE downgrade event.
customThemeSource: undefined, // "source", stores original theme data
// V3
style: null,
styleCustomData: null,
palette: null,
paletteCustomData: null,
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
// Those are handled outside config now
// muteWords: [],
// highlight: {},
}
export const defaultConfigLocal = {
hideAttachments: false,
hideAttachmentsInConv: false,
sidebarColumnWidth: '25rem',
contentColumnWidth: '45rem',
notifsColumnWidth: '25rem',
themeEditorMinWidth: '0rem',
emojiReactionsScale: 0.5,
textSize: '1rem',
emojiSize: '2.2rem',
navbarSize: '3.5rem',
panelHeaderSize: '3.2rem',
navbarColumnStretch: false,
mentionLinkDisplay: 'short',
imageCompression: true,
alwaysUseJpeg: false,
imageCompression: true,
alwaysUseJpeg: false,
}

View file

@ -7,6 +7,7 @@ import {
get,
groupBy,
isEqual,
deepEqual,
set,
takeRight,
uniqWith,
@ -22,7 +23,7 @@ import { useLocalConfigStore } from 'src/stores/local_config.js'
import { storage } from 'src/lib/storage.js'
import { defaultState as configDefaultState } from 'src/modules/default_config_state.js'
import { defaultStateKeys } from 'src/modules/old_default_config_state.js'
import { defaultConfigSync } from 'src/modules/old_default_config_state.js'
export const VERSION = 2
export const NEW_USER_DATE = new Date('2022-08-04') // date of writing this, basically
@ -38,7 +39,6 @@ export const defaultState = {
// storage of flags - stuff that can only be set and incremented
flagStorage: {
updateCounter: 0, // Counter for most recent update notification seen
configMigration: 0, // Counter for config -> server-side migrations
reset: 0, // special flag that can be used to force-reset all data, debug purposes only
// special reset codes:
// 1000: trim keys to those known by currently running FE
@ -417,14 +417,6 @@ export const _doMigrations = async (data, setPreference) => {
console.debug(
'Data has older version, seeing if there any migrations that can be applied',
)
if (data._version === 1) {
// Migrate old config to sync config
const vuexState = await storage.getItem('vuex-lz')
defaultStateKeys.forEach((key) => {
setPreference({ path: `simple.${key}`, value: vuexState.config[key] })
})
}
}
if (data._version > VERSION) {
@ -623,6 +615,30 @@ export const useSyncConfigStore = defineStore('sync_config', {
const flagsTemplate = userNew ? newUserFlags : defaultState.flagStorage
let dirty = false
console.debug('Migrating from old config')
const vuexState = await storage.getItem('vuex-lz')
const { config } = vuexState
const migratedEntries = new Set(config._syncMigration ?? [])
Object.entries(defaultConfigSync).forEach(([key, value]) => {
const oldValue = config[key]
const defaultValue = value
const present = oldValue !== undefined
const migrated = migratedEntries.has(key)
const different = !deepEqual(oldValue, defaultValue)
if (present && !migrated && different) {
console.debug(`Migrating config ${key}: ${oldValue}`,)
// this.setPreference({ path: `simple.${key}`, oldValue })
migratedEntries.add(key)
console.debug(`Migrating config ${key}: ${oldValue}`,)
}
})
vuexState.config._syncMigration = [...migratedEntries]
storage.setItem('vuex-lz', vuexState)
if (recent === null) {
console.debug(
`Data is empty, initializing for ${userNew ? 'new' : 'existing'} user`,
@ -642,6 +658,8 @@ export const useSyncConfigStore = defineStore('sync_config', {
const { _timestamp: _0, _version: _1, ...recentData } = recent
const { _timestamp: _2, _version: _3, ...staleData } = stale
dirty = !isEqual(recentData, staleData)
console.log(JSON.stringify(recentData))
console.log(JSON.stringify(staleData))
console.debug(`Data ${dirty ? 'needs' : "doesn't need"} merging`)
}