diff --git a/web/src/lib/settings/migrate-v7.ts b/web/src/lib/settings/migrate-v7.ts new file mode 100644 index 00000000..98dd86b4 --- /dev/null +++ b/web/src/lib/settings/migrate-v7.ts @@ -0,0 +1,109 @@ +import type { AllPartialSettingsWithSchema } from "$lib/types/settings"; + +const oldSwitcherValues = { + theme: ['auto', 'light', 'dark'], + vCodec: ['h264', 'av1', 'vp9'], + vQuality: ['720', 'max', '2160', '1440', '1080', '480', '360', '240', '144'], + aFormat: ['mp3', 'best', 'ogg', 'wav', 'opus'], + filenamePattern: ['classic', 'pretty', 'basic', 'nerdy'] +} as const; + +const oldCheckboxes = [ + 'audioMode', + 'fullTikTokAudio', + 'muteAudio', + 'reduceTransparency', + 'disableAnimations', + 'disableMetadata', + 'plausible_ignore', + 'ytDub', + 'tiktokH265' +] as const; + +type LegacySwitchers = keyof typeof oldSwitcherValues; +type LegacyCheckboxes = typeof oldCheckboxes[number]; + +const _get = (name: LegacyCheckboxes | LegacySwitchers) => { + const value = localStorage.getItem(name); + if (value !== null) { + return value; + } +} + +const getBool = (name: LegacyCheckboxes) => { + const value = _get(name); + + if (value !== undefined) { + return value === 'true'; + } +} + +const getLiteral = (name: T) => { + const value = _get(name); + if (value === undefined) { + return; + } + + const values = oldSwitcherValues[name] as readonly string[]; + if (values.includes(value)) { + type SwitcherOptions = typeof oldSwitcherValues[T][number]; + return value as SwitcherOptions; + } +} + +const getDownloadMode = () => { + if (getBool('muteAudio')) { + return 'mute'; + } + + if (getBool('audioMode')) { + return 'audio'; + } + + return 'auto'; +} + +const cleanup = () => { + for (const key of Object.keys(localStorage)) { + // plausible script needs this value, so we keep it if migrating + if (key !== 'plausible_ignore') { + localStorage.removeItem(key); + } + } +} + +export const migrateOldSettings = () => { + if (getLiteral('vCodec') === undefined) { + /* on the old frontend, preferences such as "vCodec" are set right + * when you open it. so, if this preference does not exist, we can + * assume that the user never used the old frontend, and abort the + * migration early. */ + return; + } + + const migrated: AllPartialSettingsWithSchema = { + schemaVersion: 2, + appearance: { + theme: getLiteral('theme'), + reduceTransparency: getBool('reduceTransparency'), + reduceMotion: getBool('disableAnimations'), + }, + privacy: { + disableAnalytics: getBool('plausible_ignore') + }, + save: { + youtubeVideoCodec: getLiteral('vCodec'), + videoQuality: getLiteral('vQuality'), + audioFormat: getLiteral('aFormat'), + downloadMode: getDownloadMode(), + filenameStyle: getLiteral('filenamePattern'), + tiktokFullAudio: getBool('fullTikTokAudio'), + tiktokH265: getBool('tiktokH265'), + disableMetadata: getBool('disableMetadata'), + youtubeDubBrowserLang: getBool('ytDub'), + } + }; + + cleanup(); + return migrated; +} diff --git a/web/src/lib/settings/migrate.ts b/web/src/lib/settings/migrate.ts index 98dd86b4..e452b6f8 100644 --- a/web/src/lib/settings/migrate.ts +++ b/web/src/lib/settings/migrate.ts @@ -1,109 +1,38 @@ -import type { AllPartialSettingsWithSchema } from "$lib/types/settings"; +import type { RecursivePartial } from "$lib/types/generic"; +import type { + AllPartialSettingsWithSchema, + CobaltSettingsV3, + PartialSettings, +} from "$lib/types/settings"; +import { getBrowserLanguage } from "$lib/settings/youtube-lang"; -const oldSwitcherValues = { - theme: ['auto', 'light', 'dark'], - vCodec: ['h264', 'av1', 'vp9'], - vQuality: ['720', 'max', '2160', '1440', '1080', '480', '360', '240', '144'], - aFormat: ['mp3', 'best', 'ogg', 'wav', 'opus'], - filenamePattern: ['classic', 'pretty', 'basic', 'nerdy'] -} as const; +type Migrator = ( + s: AllPartialSettingsWithSchema +) => AllPartialSettingsWithSchema; +const migrations: Record = { + [3]: (settings: AllPartialSettingsWithSchema) => { + const out = settings as RecursivePartial; + out.schemaVersion = 3; -const oldCheckboxes = [ - 'audioMode', - 'fullTikTokAudio', - 'muteAudio', - 'reduceTransparency', - 'disableAnimations', - 'disableMetadata', - 'plausible_ignore', - 'ytDub', - 'tiktokH265' -] as const; + if (settings?.save && "youtubeDubBrowserLang" in settings.save) { + if (settings.save.youtubeDubBrowserLang) { + out.save!.youtubeDubLang = getBrowserLanguage(); + } -type LegacySwitchers = keyof typeof oldSwitcherValues; -type LegacyCheckboxes = typeof oldCheckboxes[number]; - -const _get = (name: LegacyCheckboxes | LegacySwitchers) => { - const value = localStorage.getItem(name); - if (value !== null) { - return value; - } -} - -const getBool = (name: LegacyCheckboxes) => { - const value = _get(name); - - if (value !== undefined) { - return value === 'true'; - } -} - -const getLiteral = (name: T) => { - const value = _get(name); - if (value === undefined) { - return; + delete settings.save.youtubeDubBrowserLang; } - const values = oldSwitcherValues[name] as readonly string[]; - if (values.includes(value)) { - type SwitcherOptions = typeof oldSwitcherValues[T][number]; - return value as SwitcherOptions; - } -} + return out as AllPartialSettingsWithSchema; + }, +}; -const getDownloadMode = () => { - if (getBool('muteAudio')) { - return 'mute'; - } - - if (getBool('audioMode')) { - return 'audio'; - } - - return 'auto'; -} - -const cleanup = () => { - for (const key of Object.keys(localStorage)) { - // plausible script needs this value, so we keep it if migrating - if (key !== 'plausible_ignore') { - localStorage.removeItem(key); - } - } -} - -export const migrateOldSettings = () => { - if (getLiteral('vCodec') === undefined) { - /* on the old frontend, preferences such as "vCodec" are set right - * when you open it. so, if this preference does not exist, we can - * assume that the user never used the old frontend, and abort the - * migration early. */ - return; - } - - const migrated: AllPartialSettingsWithSchema = { - schemaVersion: 2, - appearance: { - theme: getLiteral('theme'), - reduceTransparency: getBool('reduceTransparency'), - reduceMotion: getBool('disableAnimations'), - }, - privacy: { - disableAnalytics: getBool('plausible_ignore') - }, - save: { - youtubeVideoCodec: getLiteral('vCodec'), - videoQuality: getLiteral('vQuality'), - audioFormat: getLiteral('aFormat'), - downloadMode: getDownloadMode(), - filenameStyle: getLiteral('filenamePattern'), - tiktokFullAudio: getBool('fullTikTokAudio'), - tiktokH265: getBool('tiktokH265'), - disableMetadata: getBool('disableMetadata'), - youtubeDubBrowserLang: getBool('ytDub'), - } - }; - - cleanup(); - return migrated; -} +export const migrate = ( + settings: AllPartialSettingsWithSchema +): PartialSettings => { + return Object.keys(migrations) + .map(Number) + .filter((version) => version > settings.schemaVersion) + .reduce((settings, migrationVersion) => { + return migrations[migrationVersion](settings); + }, settings as AllPartialSettingsWithSchema) as PartialSettings; +}; diff --git a/web/src/lib/state/settings.ts b/web/src/lib/state/settings.ts index 76a87105..db41915c 100644 --- a/web/src/lib/state/settings.ts +++ b/web/src/lib/state/settings.ts @@ -4,13 +4,11 @@ import { merge } from 'ts-deepmerge'; import type { PartialSettings, AllPartialSettingsWithSchema, - CobaltSettings, - CobaltSettingsV3 + CobaltSettings } from '../types/settings'; -import { getBrowserLanguage } from '$lib/settings/youtube-lang'; -import { migrateOldSettings } from '../settings/migrate'; +import { migrateOldSettings } from '../settings/migrate-v7'; import defaultSettings from '../settings/defaults'; -import type { RecursivePartial } from '$lib/types/generic'; +import { migrate } from '$lib/settings/migrate'; const updatePlausiblePreference = (settings: PartialSettings) => { if (settings.privacy?.disableAnalytics) { @@ -29,34 +27,6 @@ const writeToStorage = (settings: PartialSettings) => { return settings; } -type Migrator = (s: AllPartialSettingsWithSchema) => AllPartialSettingsWithSchema; -const migrations: Record = { - [3]: (settings: AllPartialSettingsWithSchema) => { - const out = settings as RecursivePartial; - out.schemaVersion = 3; - - if (settings?.save && 'youtubeDubBrowserLang' in settings.save) { - if (settings.save.youtubeDubBrowserLang) { - out.save!.youtubeDubLang = getBrowserLanguage(); - } - - delete settings.save.youtubeDubBrowserLang; - } - - return out as AllPartialSettingsWithSchema; - } -} - -const migrate = (settings: AllPartialSettingsWithSchema): PartialSettings => { - return Object.keys(migrations) - .map(Number) - .filter(version => version > settings.schemaVersion) - .reduce((settings, migrationVersion) => { - return migrations[migrationVersion](settings); - }, settings as AllPartialSettingsWithSchema) as PartialSettings; -} - - const loadFromStorage = () => { if (!browser) return {};