enhance(frontend): improve theme settings

This commit is contained in:
syuilo 2025-06-25 10:23:39 +09:00
parent 43abbce2af
commit 36fde67992
3 changed files with 33 additions and 7 deletions

4
locales/index.d.ts vendored
View File

@ -8366,6 +8366,10 @@ export interface Locale extends ILocale {
*
*/
"code": string;
/**
*
*/
"copyThemeCode": string;
/**
*
*/

View File

@ -2193,6 +2193,7 @@ _theme:
install: "テーマのインストール"
manage: "テーマの管理"
code: "テーマコード"
copyThemeCode: "テーマコードをコピー"
description: "説明"
installed: "{name}をインストールしました"
installedThemes: "インストールされたテーマ"

View File

@ -56,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="instanceLightTheme.id"
/>
<label :for="`themeRadio_${instanceLightTheme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${instanceLightTheme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(instanceLightTheme, $event)">
<MkThemePreview :theme="instanceLightTheme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ instanceLightTheme.name }}</div>
</label>
@ -76,7 +76,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="theme.id"
/>
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(theme, $event)">
<MkThemePreview :theme="theme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ theme.name }}</div>
</label>
@ -96,7 +96,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="theme.id"
/>
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(theme, $event)">
<MkThemePreview :theme="theme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ theme.name }}</div>
</label>
@ -127,7 +127,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="instanceDarkTheme.id"
/>
<label :for="`themeRadio_${instanceDarkTheme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${instanceDarkTheme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(instanceDarkTheme, $event)">
<MkThemePreview :theme="instanceDarkTheme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ instanceDarkTheme.name }}</div>
</label>
@ -147,7 +147,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="theme.id"
/>
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(theme, $event)">
<MkThemePreview :theme="theme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ theme.name }}</div>
</label>
@ -167,7 +167,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:class="$style.themeRadio"
:value="theme.id"
/>
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button">
<label :for="`themeRadio_${theme.id}`" :class="$style.themeItemRoot" class="_button" @contextmenu.prevent.stop="onThemeContextmenu(theme, $event)">
<MkThemePreview :theme="theme" :class="$style.themeItemPreview"/>
<div :class="$style.themeItemCaption">{{ theme.name }}</div>
</label>
@ -210,7 +210,7 @@ import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue';
import MkFolder from '@/components/MkFolder.vue';
import MkThemePreview from '@/components/MkThemePreview.vue';
import { getBuiltinThemesRef, getThemesRef } from '@/theme.js';
import { getBuiltinThemesRef, getThemesRef, removeTheme } from '@/theme.js';
import { isDeviceDarkmode } from '@/utility/is-device-darkmode.js';
import { store } from '@/store.js';
import { i18n } from '@/i18n.js';
@ -218,6 +218,7 @@ import { instance } from '@/instance.js';
import { uniqueBy } from '@/utility/array.js';
import { definePage } from '@/page.js';
import { prefer } from '@/preferences.js';
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
const installedThemes = getThemesRef();
const builtinThemes = getBuiltinThemesRef();
@ -295,6 +296,26 @@ function changeThemesSyncEnabled(value: boolean) {
}
}
function onThemeContextmenu(theme: Theme, ev: MouseEvent) {
os.contextMenu([{
type: 'label',
text: theme.name,
}, {
icon: 'ti ti-clipboard',
text: i18n.ts._theme.copyThemeCode,
action: () => {
copyToClipboard(JSON5.stringify(theme, null, '\t'));
},
}, {
icon: 'ti ti-trash',
text: i18n.ts.delete,
danger: true,
action: () => {
removeTheme(theme);
},
}], ev);
}
const headerActions = computed(() => []);
const headerTabs = computed(() => []);