From 75dcebc3412526cfd657ed8251448df0acc23b11 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Thu, 29 May 2025 17:32:10 +0900
Subject: [PATCH] =?UTF-8?q?enhance(frontend):=20=E3=83=87=E3=83=90?=
=?UTF-8?q?=E3=82=A4=E3=82=B9=E3=81=AE=E3=83=80=E3=83=BC=E3=82=AF=E3=83=A2?=
=?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=A8=E5=90=8C=E6=9C=9F=E3=81=99=E3=82=8B?=
=?UTF-8?q?=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=8C=E6=9C=89?=
=?UTF-8?q?=E5=8A=B9=E3=81=AA=E3=81=A8=E3=81=8D=E3=81=AB=E3=83=86=E3=83=BC?=
=?UTF-8?q?=E3=83=9E=E3=82=92=E6=89=8B=E5=8B=95=E3=81=A7=E5=88=87=E3=82=8A?=
=?UTF-8?q?=E6=9B=BF=E3=81=88=E3=82=88=E3=81=86=E3=81=A8=E3=81=97=E3=81=9F?=
=?UTF-8?q?=E9=9A=9B=E3=81=AE=E8=AD=A6=E5=91=8A=E3=82=92=E8=A1=A8=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
locales/index.d.ts | 4 +
locales/ja-JP.yml | 1 +
.../frontend/src/pages/settings/theme.vue | 146 +++++++++---------
3 files changed, 79 insertions(+), 72 deletions(-)
diff --git a/locales/index.d.ts b/locales/index.d.ts
index cecda4d44e..21da0c171a 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1326,6 +1326,10 @@ export interface Locale extends ILocale {
* デバイスのダークモードと同期する
*/
"syncDeviceDarkMode": string;
+ /**
+ * 「{x}」がオンになっています。同期をオフにして手動でモードを切り替えますか?
+ */
+ "switchDarkModeManuallyWhenSyncEnabledConfirm": ParameterizedString<"x">;
/**
* ドライブ
*/
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index e059fc99ee..b81529790f 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -327,6 +327,7 @@ dark: "ダーク"
lightThemes: "明るいテーマ"
darkThemes: "暗いテーマ"
syncDeviceDarkMode: "デバイスのダークモードと同期する"
+switchDarkModeManuallyWhenSyncEnabledConfirm: "「{x}」がオンになっています。同期をオフにして手動でモードを切り替えますか?"
drive: "ドライブ"
fileName: "ファイル名"
selectFile: "ファイルを選択"
diff --git a/packages/frontend/src/pages/settings/theme.vue b/packages/frontend/src/pages/settings/theme.vue
index 45b97e19c4..f3a6458109 100644
--- a/packages/frontend/src/pages/settings/theme.vue
+++ b/packages/frontend/src/pages/settings/theme.vue
@@ -9,8 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
@@ -37,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
@@ -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 {