web/settings: move migration to separate file, rename v7 migration
This commit is contained in:
parent
44f842997e
commit
b125894b7e
3 changed files with 144 additions and 136 deletions
109
web/src/lib/settings/migrate-v7.ts
Normal file
109
web/src/lib/settings/migrate-v7.ts
Normal file
|
@ -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 = <T extends LegacySwitchers>(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;
|
||||||
|
}
|
|
@ -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 = {
|
type Migrator = (
|
||||||
theme: ['auto', 'light', 'dark'],
|
s: AllPartialSettingsWithSchema
|
||||||
vCodec: ['h264', 'av1', 'vp9'],
|
) => AllPartialSettingsWithSchema;
|
||||||
vQuality: ['720', 'max', '2160', '1440', '1080', '480', '360', '240', '144'],
|
const migrations: Record<number, Migrator> = {
|
||||||
aFormat: ['mp3', 'best', 'ogg', 'wav', 'opus'],
|
[3]: (settings: AllPartialSettingsWithSchema) => {
|
||||||
filenamePattern: ['classic', 'pretty', 'basic', 'nerdy']
|
const out = settings as RecursivePartial<CobaltSettingsV3>;
|
||||||
} as const;
|
out.schemaVersion = 3;
|
||||||
|
|
||||||
const oldCheckboxes = [
|
if (settings?.save && "youtubeDubBrowserLang" in settings.save) {
|
||||||
'audioMode',
|
if (settings.save.youtubeDubBrowserLang) {
|
||||||
'fullTikTokAudio',
|
out.save!.youtubeDubLang = getBrowserLanguage();
|
||||||
'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) => {
|
delete settings.save.youtubeDubBrowserLang;
|
||||||
const value = _get(name);
|
|
||||||
|
|
||||||
if (value !== undefined) {
|
|
||||||
return value === 'true';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getLiteral = <T extends LegacySwitchers>(name: T) => {
|
return out as AllPartialSettingsWithSchema;
|
||||||
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();
|
export const migrate = (
|
||||||
return migrated;
|
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;
|
||||||
|
};
|
||||||
|
|
|
@ -4,13 +4,11 @@ import { merge } from 'ts-deepmerge';
|
||||||
import type {
|
import type {
|
||||||
PartialSettings,
|
PartialSettings,
|
||||||
AllPartialSettingsWithSchema,
|
AllPartialSettingsWithSchema,
|
||||||
CobaltSettings,
|
CobaltSettings
|
||||||
CobaltSettingsV3
|
|
||||||
} from '../types/settings';
|
} from '../types/settings';
|
||||||
import { getBrowserLanguage } from '$lib/settings/youtube-lang';
|
import { migrateOldSettings } from '../settings/migrate-v7';
|
||||||
import { migrateOldSettings } from '../settings/migrate';
|
|
||||||
import defaultSettings from '../settings/defaults';
|
import defaultSettings from '../settings/defaults';
|
||||||
import type { RecursivePartial } from '$lib/types/generic';
|
import { migrate } from '$lib/settings/migrate';
|
||||||
|
|
||||||
const updatePlausiblePreference = (settings: PartialSettings) => {
|
const updatePlausiblePreference = (settings: PartialSettings) => {
|
||||||
if (settings.privacy?.disableAnalytics) {
|
if (settings.privacy?.disableAnalytics) {
|
||||||
|
@ -29,34 +27,6 @@ const writeToStorage = (settings: PartialSettings) => {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Migrator = (s: AllPartialSettingsWithSchema) => AllPartialSettingsWithSchema;
|
|
||||||
const migrations: Record<number, Migrator> = {
|
|
||||||
[3]: (settings: AllPartialSettingsWithSchema) => {
|
|
||||||
const out = settings as RecursivePartial<CobaltSettingsV3>;
|
|
||||||
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 = () => {
|
const loadFromStorage = () => {
|
||||||
if (!browser)
|
if (!browser)
|
||||||
return {};
|
return {};
|
||||||
|
|
Loading…
Reference in a new issue