From 5b945278f976a41dc6b134c8f86b37ee01d79046 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 26 Apr 2026 21:21:04 +0900 Subject: [PATCH] wip --- locales/ja-JP.yml | 1 + packages/frontend/src/pages/room.vue | 247 +++++++++++++++------------ packages/i18n/src/autogen/locale.ts | 4 + 3 files changed, 143 insertions(+), 109 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index d966b2fa66..de4739e102 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -3557,4 +3557,5 @@ _qr: _room: snapToGrid: "グリッドにスナップ" gridScale: "グリッドサイズ" + thereAreUnsavedChanges: "未保存の変更があります" revertAllChangesConfirmation: "全ての変更を取り消し、部屋を最後に保存した状態まで戻しますか?" diff --git a/packages/frontend/src/pages/room.vue b/packages/frontend/src/pages/room.vue index 7cd3d0ba2b..932b8a46e0 100644 --- a/packages/frontend/src/pages/room.vue +++ b/packages/frontend/src/pages/room.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -198,9 +196,8 @@ function resize() { controller.resize(); } -const isZenMode = ref(false); const isRoomSettingsOpen = ref(false); -const isChanged = ref(false); +const isModified = ref(false); const graphicsQualityRaw = prefer.model('world.graphicsQuality'); const graphicsQualityAutoValue = computed(() => deviceKind === 'smartphone' ? GRAPHICS_QUALITY_LOW : GRAPHICS_QUALITY_MEDIUM); @@ -276,7 +273,7 @@ onMounted(async () => { window.addEventListener('resize', resize); watch(controller.roomState, () => { - isChanged.value = true; + isModified.value = true; }); //watch(controller.selected, (v) => { @@ -413,12 +410,19 @@ function exitEditMode() { function save() { latestData = deepClone(controller.roomState.value); localStorage.setItem('roomData', JSON.stringify(latestData)); - isChanged.value = false; + isModified.value = false; } async function revert() { + const { canceled } = await os.confirm({ + type: 'warning', + title: i18n.ts.areYouSure, + text: i18n.ts._room.revertAllChangesConfirmation, + }); + if (canceled) return; + await controller.reset(latestData); - isChanged.value = false; + isModified.value = false; } async function refresh() { @@ -590,6 +594,12 @@ definePage(() => ({ width: 100%; } +.topMain { + display: flex; + align-items: center; + gap: 16px; +} + .topMenu { margin: 16px; display: flex; @@ -607,6 +617,25 @@ definePage(() => ({ padding-right: 16px; } +.modified { + display: flex; + align-items: center; + font-size: 90%; + gap: 1em; + padding: 8px 16px; +} + +.modifiedText { + color: var(--MI_THEME-warn); + animation: modified-blink 2s infinite; +} + +@keyframes modified-blink { + 0% { opacity: 1; } + 50% { opacity: 0.5; } + 100% { opacity: 1; } +} + .overlayControls { } diff --git a/packages/i18n/src/autogen/locale.ts b/packages/i18n/src/autogen/locale.ts index b1b1d75003..38e9fe86ac 100644 --- a/packages/i18n/src/autogen/locale.ts +++ b/packages/i18n/src/autogen/locale.ts @@ -13271,6 +13271,10 @@ export interface Locale extends ILocale { * グリッドサイズ */ "gridScale": string; + /** + * 未保存の変更があります + */ + "thereAreUnsavedChanges": string; /** * 全ての変更を取り消し、部屋を最後に保存した状態まで戻しますか? */