テーマをレジストリに保存するように
This commit is contained in:
parent
20e67e7edd
commit
114a9fbdb2
|
@ -56,6 +56,7 @@ import { defaultStore, ColdDeviceStorage } from '@/store';
|
||||||
import { fetchInstance, instance } from '@/instance';
|
import { fetchInstance, instance } from '@/instance';
|
||||||
import { makeHotkey } from './scripts/hotkey';
|
import { makeHotkey } from './scripts/hotkey';
|
||||||
import { search } from './scripts/search';
|
import { search } from './scripts/search';
|
||||||
|
import { getThemes } from './theme-store';
|
||||||
|
|
||||||
console.info(`Misskey v${version}`);
|
console.info(`Misskey v${version}`);
|
||||||
|
|
||||||
|
@ -211,7 +212,7 @@ app.mount('body');
|
||||||
|
|
||||||
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
|
watch(defaultStore.reactiveState.darkMode, (darkMode) => {
|
||||||
import('@/scripts/theme').then(({ builtinThemes }) => {
|
import('@/scripts/theme').then(({ builtinThemes }) => {
|
||||||
const themes = builtinThemes.concat(ColdDeviceStorage.get('themes'));
|
const themes = builtinThemes.concat(getThemes());
|
||||||
applyTheme(themes.find(x => x.id === (darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'))));
|
applyTheme(themes.find(x => x.id === (darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme'))));
|
||||||
});
|
});
|
||||||
}, { immediate: localStorage.theme == null });
|
}, { immediate: localStorage.theme == null });
|
||||||
|
|
|
@ -25,6 +25,7 @@ import FormButton from '@/components/form/button.vue';
|
||||||
import { applyTheme, validateTheme } from '@/scripts/theme';
|
import { applyTheme, validateTheme } from '@/scripts/theme';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { ColdDeviceStorage } from '@/store';
|
import { ColdDeviceStorage } from '@/store';
|
||||||
|
import { addTheme, getThemes } from '@/theme-store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -74,7 +75,7 @@ export default defineComponent({
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ColdDeviceStorage.get('themes').some(t => t.id === theme.id)) {
|
if (getThemes().some(t => t.id === theme.id)) {
|
||||||
os.dialog({
|
os.dialog({
|
||||||
type: 'info',
|
type: 'info',
|
||||||
text: this.$ts._theme.alreadyInstalled
|
text: this.$ts._theme.alreadyInstalled
|
||||||
|
@ -90,11 +91,10 @@ export default defineComponent({
|
||||||
if (theme) applyTheme(theme, false);
|
if (theme) applyTheme(theme, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
install(code) {
|
async install(code) {
|
||||||
const theme = this.parseThemeCode(code);
|
const theme = this.parseThemeCode(code);
|
||||||
if (!theme) return;
|
if (!theme) return;
|
||||||
const themes = ColdDeviceStorage.get('themes').concat(theme);
|
await addTheme(theme);
|
||||||
ColdDeviceStorage.set('themes', themes);
|
|
||||||
os.dialog({
|
os.dialog({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
text: this.$t('_theme.installed', { name: theme.name })
|
text: this.$t('_theme.installed', { name: theme.name })
|
||||||
|
|
|
@ -37,6 +37,7 @@ import { Theme, builtinThemes } from '@/scripts/theme';
|
||||||
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
import copyToClipboard from '@/scripts/copy-to-clipboard';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { ColdDeviceStorage } from '@/store';
|
import { ColdDeviceStorage } from '@/store';
|
||||||
|
import { getThemes, removeTheme } from '@/theme-store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -57,7 +58,7 @@ export default defineComponent({
|
||||||
title: this.$ts._theme.manage,
|
title: this.$ts._theme.manage,
|
||||||
icon: faFolderOpen
|
icon: faFolderOpen
|
||||||
},
|
},
|
||||||
installedThemes: ColdDeviceStorage.ref('themes'),
|
installedThemes: getThemes(),
|
||||||
builtinThemes,
|
builtinThemes,
|
||||||
selectedThemeId: null,
|
selectedThemeId: null,
|
||||||
faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
|
faPalette, faDownload, faFolderOpen, faCheck, faTrashAlt, faEye
|
||||||
|
@ -91,10 +92,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
uninstall() {
|
uninstall() {
|
||||||
const theme = this.selectedTheme;
|
removeTheme(this.selectedTheme);
|
||||||
const themes = ColdDeviceStorage.get('themes').filter(t => t.id != theme.id);
|
|
||||||
ColdDeviceStorage.set('themes', themes);
|
|
||||||
os.success();
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -77,6 +77,7 @@ import { isDeviceDarkmode } from '@/scripts/is-device-darkmode';
|
||||||
import { ColdDeviceStorage } from '@/store';
|
import { ColdDeviceStorage } from '@/store';
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
|
import { fetchThemes, getThemes } from '@/theme-store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -96,7 +97,7 @@ export default defineComponent({
|
||||||
icon: faPalette
|
icon: faPalette
|
||||||
};
|
};
|
||||||
|
|
||||||
const installedThemes = ColdDeviceStorage.ref('themes');
|
const installedThemes = ref(getThemes());
|
||||||
const themes = computed(() => builtinThemes.concat(installedThemes.value));
|
const themes = computed(() => builtinThemes.concat(installedThemes.value));
|
||||||
const darkThemes = computed(() => themes.value.filter(t => t.base == 'dark' || t.kind == 'dark'));
|
const darkThemes = computed(() => themes.value.filter(t => t.base == 'dark' || t.kind == 'dark'));
|
||||||
const lightThemes = computed(() => themes.value.filter(t => t.base == 'light' || t.kind == 'light'));
|
const lightThemes = computed(() => themes.value.filter(t => t.base == 'light' || t.kind == 'light'));
|
||||||
|
@ -137,6 +138,10 @@ export default defineComponent({
|
||||||
emit('info', INFO);
|
emit('info', INFO);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fetchThemes().then(() => {
|
||||||
|
installedThemes.value = getThemes();
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
INFO,
|
INFO,
|
||||||
darkThemes,
|
darkThemes,
|
||||||
|
|
|
@ -208,7 +208,7 @@ type Plugin = {
|
||||||
*/
|
*/
|
||||||
export class ColdDeviceStorage {
|
export class ColdDeviceStorage {
|
||||||
public static default = {
|
public static default = {
|
||||||
themes: [] as Theme[],
|
themes: [] as Theme[], // TODO: そのうち消す
|
||||||
darkTheme: '8050783a-7f63-445a-b270-36d0f6ba1677',
|
darkTheme: '8050783a-7f63-445a-b270-36d0f6ba1677',
|
||||||
lightTheme: '4eea646f-7afa-4645-83e9-83af0333cd37',
|
lightTheme: '4eea646f-7afa-4645-83e9-83af0333cd37',
|
||||||
syncDeviceDarkMode: true,
|
syncDeviceDarkMode: true,
|
||||||
|
|
62
src/client/theme-store.ts
Normal file
62
src/client/theme-store.ts
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import { api } from '@/os';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
import { ColdDeviceStorage } from './store';
|
||||||
|
import { Theme } from './scripts/theme';
|
||||||
|
|
||||||
|
const lsCacheKey = $i ? `themes:${$i.id}` : '';
|
||||||
|
|
||||||
|
export function getThemes(): Theme[] {
|
||||||
|
return JSON.parse(localStorage.getItem(lsCacheKey) || '[]');
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchThemes(): Promise<void> {
|
||||||
|
if ($i == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const themes = await api('i/registry/get', { scope: ['client'], key: 'themes' });
|
||||||
|
localStorage.setItem(lsCacheKey, JSON.stringify(themes));
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === 'NO_SUCH_KEY') return;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addTheme(theme: Theme): Promise<void> {
|
||||||
|
await fetchThemes();
|
||||||
|
const themes = getThemes().concat(theme);
|
||||||
|
await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes });
|
||||||
|
localStorage.setItem(lsCacheKey, JSON.stringify(themes));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function removeTheme(theme: Theme): Promise<void> {
|
||||||
|
const themes = getThemes().filter(t => t.id != theme.id);
|
||||||
|
await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes });
|
||||||
|
localStorage.setItem(lsCacheKey, JSON.stringify(themes));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: そのうち消す
|
||||||
|
if (ColdDeviceStorage.get('themes').length > 0) {
|
||||||
|
const lsThemes = ColdDeviceStorage.get('themes');
|
||||||
|
let registryThemes;
|
||||||
|
try {
|
||||||
|
registryThemes = await api('i/registry/get', { scope: ['client'], key: 'themes' });
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === 'NO_SUCH_KEY') {
|
||||||
|
registryThemes = [];
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const themes = [] as Theme[];
|
||||||
|
for (const theme of lsThemes) {
|
||||||
|
if (themes.some(x => x.id === theme.id)) continue;
|
||||||
|
themes.push(theme);
|
||||||
|
}
|
||||||
|
for (const theme of registryThemes) {
|
||||||
|
if (themes.some(x => x.id === theme.id)) continue;
|
||||||
|
themes.push(theme);
|
||||||
|
}
|
||||||
|
await api('i/registry/set', { scope: ['client'], key: 'themes', value: themes });
|
||||||
|
localStorage.setItem(lsCacheKey, JSON.stringify(themes));
|
||||||
|
ColdDeviceStorage.set('themes', []);
|
||||||
|
}
|
Loading…
Reference in a new issue