enhance(frontend): デバイスのダークモードと同期するオプションが有効なときにテーマを手動で切り替えようとした際の警告を表示

This commit is contained in:
syuilo 2025-05-29 17:32:10 +09:00
parent 85c28d5cb7
commit 75dcebc341
3 changed files with 79 additions and 72 deletions

4
locales/index.d.ts vendored
View File

@ -1326,6 +1326,10 @@ export interface Locale extends ILocale {
*
*/
"syncDeviceDarkMode": string;
/**
* {x}
*/
"switchDarkModeManuallyWhenSyncEnabledConfirm": ParameterizedString<"x">;
/**
*
*/

View File

@ -327,6 +327,7 @@ dark: "ダーク"
lightThemes: "明るいテーマ"
darkThemes: "暗いテーマ"
syncDeviceDarkMode: "デバイスのダークモードと同期する"
switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」がオンになっています。同期をオフにして手動でモードを切り替えますか?"
drive: "ドライブ"
fileName: "ファイル名"
selectFile: "ファイルを選択"

View File

@ -9,8 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-adaptive-border class="rfqxtzch _panel">
<div class="toggle">
<div class="toggleWrapper">
<input id="dn" v-model="darkMode" type="checkbox" class="dn"/>
<label for="dn" class="toggle">
<div class="toggle" :class="store.r.darkMode.value ? 'checked' : null" @click="toggleDarkMode()">
<span class="before">{{ i18n.ts.light }}</span>
<span class="after">{{ i18n.ts.dark }}</span>
<span class="toggle__handler">
@ -24,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<span class="star star--4"></span>
<span class="star star--5"></span>
<span class="star star--6"></span>
</label>
</div>
</div>
</div>
<div class="sync">
@ -37,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div class="_gaps">
<template v-if="!darkMode">
<template v-if="!store.r.darkMode.value">
<SearchMarker :keywords="['light', 'theme']">
<MkFolder :defaultOpen="true" :max-height="500">
<template #icon><i class="ti ti-sun"></i></template>
@ -205,6 +204,7 @@ import JSON5 from 'json5';
import defaultLightTheme from '@@/themes/l-light.json5';
import defaultDarkTheme from '@@/themes/d-green-lime.json5';
import type { Theme } from '@/theme.js';
import * as os from '@/os.js';
import MkSwitch from '@/components/MkSwitch.vue';
import FormSection from '@/components/form/section.vue';
import FormLink from '@/components/form/link.vue';
@ -257,7 +257,6 @@ const lightThemeId = computed({
},
});
const darkMode = computed(store.makeGetterSetter('darkMode'));
const syncDeviceDarkMode = prefer.model('syncDeviceDarkMode');
const themesCount = installedThemes.value.length;
@ -267,6 +266,21 @@ watch(syncDeviceDarkMode, () => {
}
});
async function toggleDarkMode() {
const value = !store.r.darkMode.value;
if (syncDeviceDarkMode.value) {
const { canceled } = await os.confirm({
text: i18n.tsx.switchDarkModeManuallyWhenSyncEnabledConfirm({ x: i18n.ts.syncDeviceDarkMode }),
});
if (canceled) return;
syncDeviceDarkMode.value = false;
store.set('darkMode', value);
} else {
store.set('darkMode', value);
}
}
const themesSyncEnabled = ref(prefer.isSyncEnabled('themes'));
function changeThemesSyncEnabled(value: boolean) {
@ -365,16 +379,6 @@ definePage(() => ({
overflow: clip;
padding: 0 100px;
vertical-align: bottom;
input {
position: absolute;
left: -99em;
}
}
.dn:focus-visible ~ .toggle {
outline: 2px solid var(--MI_THEME-focus);
outline-offset: 2px;
}
.toggle {
@ -403,6 +407,61 @@ definePage(() => ({
right: -68px;
color: var(--MI_THEME-fg);
}
&.checked {
background-color: #749DD6;
> .before {
color: var(--MI_THEME-fg);
}
> .after {
color: var(--MI_THEME-accent);
}
.toggle__handler {
background-color: #FFE5B5;
transform: translate3d(40px, 0, 0) rotate(0);
.crater { opacity: 1; }
}
.star--1 {
width: 2px;
height: 2px;
}
.star--2 {
width: 4px;
height: 4px;
transform: translate3d(-5px, 0, 0);
}
.star--3 {
width: 2px;
height: 2px;
transform: translate3d(-7px, 0, 0);
}
.star--4,
.star--5,
.star--6 {
opacity: 1;
transform: translate3d(0,0,0);
}
.star--4 {
transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
.star--5 {
transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
.star--6 {
transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
}
}
.toggle__handler {
@ -513,63 +572,6 @@ definePage(() => ({
height: 2px;
transform: translate3d(3px,0,0);
}
input:checked {
+ .toggle {
background-color: #749DD6;
> .before {
color: var(--MI_THEME-fg);
}
> .after {
color: var(--MI_THEME-accent);
}
.toggle__handler {
background-color: #FFE5B5;
transform: translate3d(40px, 0, 0) rotate(0);
.crater { opacity: 1; }
}
.star--1 {
width: 2px;
height: 2px;
}
.star--2 {
width: 4px;
height: 4px;
transform: translate3d(-5px, 0, 0);
}
.star--3 {
width: 2px;
height: 2px;
transform: translate3d(-7px, 0, 0);
}
.star--4,
.star--5,
.star--6 {
opacity: 1;
transform: translate3d(0,0,0);
}
.star--4 {
transition: all 300ms 200ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
.star--5 {
transition: all 300ms 300ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
.star--6 {
transition: all 300ms 400ms cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
}
}
}
> .sync {