Skip to content

Commit 7bcc971

Browse files
authored
Merge pull request #3 from FreecellRaid/refactor/focus-v3
Refactor/focus v3
2 parents fabd58b + 689a483 commit 7bcc971

18 files changed

Lines changed: 371 additions & 323 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dist
1212
dist-ssr
1313
*.local
1414
todo.md
15+
temp
1516

1617
# Editor directories and files
1718
.vscode/*

src/components/common/HelpDocument.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div
33
class="help-overlay"
44
data-focus-area="modal"
5-
@pointerdown.self="uiStore.closeHelpDocument()"
5+
@pointerdown.self="windowStore.closeHelpDocument()"
66
>
77
<div class="help-dialog" role="dialog" aria-modal="true">
88
<div class="help-header">
@@ -14,7 +14,7 @@
1414
class="close-button icon-interactive"
1515
type="button"
1616
title="关闭帮助 (Esc)"
17-
@click="uiStore.closeHelpDocument()"
17+
@click="windowStore.closeHelpDocument()"
1818
>
1919
<X class="ui-icon" />
2020
</button>
@@ -37,9 +37,9 @@
3737

3838
<script setup lang="ts">
3939
import { HelpCircle, X } from '@lucide/vue';
40-
import { useUiStore } from '@/stores/uiStore';
40+
import { useWindowStore } from '@/stores/windowStore';
4141
42-
const uiStore = useUiStore();
42+
const windowStore = useWindowStore();
4343
</script>
4444

4545
<style scoped>

src/components/layout/SidebarLeft.vue

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,68 @@
11
<template>
22
<div
33
class="sidebar-left-container"
4-
:class="{ 'is-collapsed': !uiStore.leftSidebarVisible }"
4+
:class="{ 'is-collapsed': !windowStore.leftSidebarVisible }"
55
>
66
<nav class="activity-bar">
77
<div class="nav-top">
88
<div
99
class="nav-item"
1010
:class="{
1111
active:
12-
uiStore.activeLeftPanelName === 'chunkList' &&
13-
uiStore.leftSidebarVisible,
12+
windowStore.activeLeftPanelName === 'chunkList' &&
13+
windowStore.leftSidebarVisible,
1414
}"
1515
title="文件列表"
16-
@click="uiStore.setLeftPanel('chunkList')"
16+
@click="windowStore.setLeftPanel('chunkList')"
1717
>
1818
<FolderOpen class="ui-icon" />
1919
</div>
2020
<div
2121
class="nav-item"
2222
:class="{
2323
active:
24-
uiStore.activeLeftPanelName === 'identity' &&
25-
uiStore.leftSidebarVisible,
24+
windowStore.activeLeftPanelName === 'identity' &&
25+
windowStore.leftSidebarVisible,
2626
}"
2727
title="身份管理"
28-
@click="uiStore.setLeftPanel('identity')"
28+
@click="windowStore.setLeftPanel('identity')"
2929
>
3030
<UserRound class="ui-icon" />
3131
</div>
3232
<div
3333
class="nav-item"
3434
:class="{
3535
active:
36-
uiStore.activeLeftPanelName === 'ruleEditor' &&
37-
uiStore.leftSidebarVisible,
36+
windowStore.activeLeftPanelName === 'ruleEditor' &&
37+
windowStore.leftSidebarVisible,
3838
}"
3939
title="染色规则"
40-
@click="uiStore.setLeftPanel('ruleEditor')"
40+
@click="windowStore.setLeftPanel('ruleEditor')"
4141
>
4242
<Palette class="ui-icon" />
4343
</div>
4444
<div
4545
class="nav-item"
4646
:class="{
4747
active:
48-
uiStore.activeLeftPanelName === 'search' &&
49-
uiStore.leftSidebarVisible,
48+
windowStore.activeLeftPanelName === 'search' &&
49+
windowStore.leftSidebarVisible,
5050
}"
5151
title="搜索过滤"
52-
@click="uiStore.setLeftPanel('search')"
52+
@click="windowStore.setLeftPanel('search')"
5353
>
5454
<Search class="ui-icon" />
5555
</div>
5656
<div
5757
class="nav-item"
5858
:class="{
5959
active:
60-
uiStore.activeLeftPanelName === 'exportFormat' &&
61-
uiStore.leftSidebarVisible,
60+
windowStore.activeLeftPanelName ===
61+
'exportFormat' &&
62+
windowStore.leftSidebarVisible,
6263
}"
6364
title="导出模板"
64-
@click="uiStore.setLeftPanel('exportFormat')"
65+
@click="windowStore.setLeftPanel('exportFormat')"
6566
>
6667
<TextInitial class="ui-icon" />
6768
</div>
@@ -166,37 +167,39 @@
166167
</nav>
167168

168169
<aside
169-
v-if="uiStore.leftSidebarVisible"
170+
v-if="windowStore.leftSidebarVisible"
170171
class="side-panel"
171172
:style="{ width: uiStore.leftPanelWidth + 'px' }"
172173
>
173174
<div class="panel-content">
174175
<div
175-
v-if="uiStore.activeLeftPanelName === 'chunkList'"
176+
v-if="windowStore.activeLeftPanelName === 'chunkList'"
176177
class="panel-slot"
177178
>
178179
<ChunkListPanel />
179180
</div>
180181
<div
181-
v-else-if="uiStore.activeLeftPanelName === 'identity'"
182+
v-else-if="windowStore.activeLeftPanelName === 'identity'"
182183
class="panel-slot"
183184
>
184185
<IdentityPanel />
185186
</div>
186187
<div
187-
v-else-if="uiStore.activeLeftPanelName === 'ruleEditor'"
188+
v-else-if="windowStore.activeLeftPanelName === 'ruleEditor'"
188189
class="panel-slot"
189190
>
190191
<RuleEditorPanel />
191192
</div>
192193
<div
193-
v-else-if="uiStore.activeLeftPanelName === 'search'"
194+
v-else-if="windowStore.activeLeftPanelName === 'search'"
194195
class="panel-slot"
195196
>
196197
<SearchPanel />
197198
</div>
198199
<div
199-
v-else-if="uiStore.activeLeftPanelName === 'exportFormat'"
200+
v-else-if="
201+
windowStore.activeLeftPanelName === 'exportFormat'
202+
"
200203
class="panel-slot"
201204
>
202205
<ExportFormatPanel />
@@ -205,7 +208,7 @@
205208
</aside>
206209

207210
<div
208-
v-if="uiStore.leftSidebarVisible"
211+
v-if="windowStore.leftSidebarVisible"
209212
class="resize-handle"
210213
@mousedown="startResize"
211214
></div>
@@ -226,13 +229,15 @@ import {
226229
import { ref, onMounted, onUnmounted, watch } from 'vue';
227230
import { useStyleStore } from '@/stores/styleStore';
228231
import { useUiStore, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH } from '@/stores/uiStore';
232+
import { useWindowStore } from '@/stores/windowStore';
229233
import ChunkListPanel from '@/components/panels/ChunkListPanel.vue';
230234
import IdentityPanel from '@/components/panels/IdentityPanel.vue';
231235
import RuleEditorPanel from '@/components/panels/RuleEditorPanel.vue';
232236
import ExportFormatPanel from '@/components/panels/ExportFormatPanel.vue';
233237
import SearchPanel from '@/components/panels/SearchPanel.vue';
234238
235239
const uiStore = useUiStore();
240+
const windowStore = useWindowStore();
236241
const styleStore = useStyleStore();
237242
const showSettings = ref(false);
238243
const closeSettings = () => {

src/components/layout/StatusBar.vue

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,23 @@ import {
7676
} from '@lucide/vue';
7777
import { computed } from 'vue';
7878
import { useLogStore } from '@/stores/logStore';
79-
import { useUiStore } from '@/stores/uiStore';
79+
import { useWindowStore } from '@/stores/windowStore';
8080
import { useStyleStore } from '@/stores/styleStore';
8181
import { useFilter } from '@/composables/useFilter';
8282
import { matchesMessageFilter } from '@/editor/filter';
8383
8484
const logStore = useLogStore();
85-
const uiStore = useUiStore();
85+
const windowStore = useWindowStore();
8686
const styleStore = useStyleStore();
8787
const filterTool = useFilter();
8888
8989
const activeChunk = computed(function () {
9090
if (
91-
!uiStore.currentActiveView.windowId ||
92-
uiStore.currentActiveView.windowId === 'defaultView'
91+
!windowStore.currentActiveView.windowId ||
92+
windowStore.currentActiveView.windowId === 'defaultView'
9393
)
9494
return null;
95-
return logStore.findChunkById(uiStore.currentActiveView.windowId);
95+
return logStore.findChunkById(windowStore.currentActiveView.windowId);
9696
});
9797
9898
const activeChunkName = computed(function () {

src/components/layout/TopMenuBar.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class="project-name project-entry"
55
type="button"
66
title="打开帮助文档"
7-
@click="uiStore.openHelpDocument"
7+
@click="windowStore.openHelpDocument"
88
>
99
<div class="icon-project">
1010
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
@@ -157,7 +157,7 @@ import { useLogStore } from '@/stores/logStore';
157157
import { useStyleStore } from '@/stores/styleStore';
158158
import { useClipboardStore } from '@/stores/clipboardStore';
159159
import { useHistoryStore } from '@/stores/historyStore';
160-
import { useUiStore } from '@/stores/uiStore';
160+
import { useWindowStore } from '@/stores/windowStore';
161161
import { useFilter } from '@/composables/useFilter';
162162
import { useFileImport } from '@/composables/useImporter';
163163
import { useProjectManager } from '@/composables/useProjectManager';
@@ -171,7 +171,7 @@ const logStore = useLogStore();
171171
const styleStore = useStyleStore();
172172
const clipboardStore = useClipboardStore();
173173
const historyStore = useHistoryStore();
174-
const uiStore = useUiStore();
174+
const windowStore = useWindowStore();
175175
176176
const filterTool = useFilter();
177177
const { importAndApply } = useFileImport();
@@ -210,8 +210,8 @@ const hasWorkspaceState = computed(() => {
210210
filterTool.hasSelection.value ||
211211
historyStore.undoStack.length > 0 ||
212212
historyStore.redoStack.length > 0 ||
213-
!uiStore.currentActiveView.windowId ||
214-
uiStore.currentActiveView.windowId === 'defaultView'
213+
!windowStore.currentActiveView.windowId ||
214+
windowStore.currentActiveView.windowId === 'defaultView'
215215
);
216216
});
217217
@@ -333,7 +333,7 @@ function handleClearAll() {
333333
clipboardStore.clearClipboard();
334334
filterTool.clearSelection();
335335
historyStore.clearHistory();
336-
uiStore.setFocus({ type: 'window', id: 'default' });
336+
windowStore.setFocus('default');
337337
}
338338
339339
/** 点击元素外部触发回调 (用于关闭下拉菜单) */

src/components/panels/ChunkListPanel.vue

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@
103103
<div
104104
class="chunk-item"
105105
:class="{
106-
// uiStore的焦点判断
106+
// windowStore的焦点判断
107107
'is-active':
108-
uiStore.currentActiveView.windowId ===
108+
windowStore.currentActiveView.windowId ===
109109
chunk.chunkId,
110110
// useFilter的选中判断
111111
'is-selected':
@@ -209,16 +209,16 @@ import { useChunkDragDrop } from '@/composables/useDragDrop';
209209
import { useChunkEditorStore } from '@/stores/editorStore/chunkStore';
210210
import { useLogStore } from '@/stores/logStore';
211211
import { useStyleStore } from '@/stores/styleStore';
212-
import { useUiStore } from '@/stores/uiStore';
212+
import { useWindowStore } from '@/stores/windowStore';
213213
import type { Chunk, LogDocument } from '@/types/log';
214214
import { useFilter } from '@/composables/useFilter';
215215
216216
const logStore = useLogStore();
217217
const styleStore = useStyleStore();
218-
const uiStore = useUiStore();
218+
const windowStore = useWindowStore();
219219
const chunkEditorStore = useChunkEditorStore();
220220
const chunkDrag = useChunkDragDrop();
221-
const filterTool = useFilter();
221+
const filterTool = useFilter('chunkList');
222222
223223
const editingDocId = ref('');
224224
const editingChunkId = ref('');
@@ -330,13 +330,14 @@ function handleMerge(currentChunkId: string, nextChunkId: string) {
330330
}
331331
332332
function handleChunkSelect(chunkId: string, event: MouseEvent) {
333-
uiStore.registerWindow({
333+
windowStore.registerWindow({
334334
windowId: chunkId,
335335
windowName: 'chunkView',
336+
windowType: 'view',
336337
});
337338
// 这里切换两次,用来保证显示正常再把焦点拉回panel
338-
uiStore.setFocus({ type: 'window', id: chunkId });
339-
uiStore.setFocus({ type: 'window', id: 'chunkList' });
339+
windowStore.setFocus(chunkId);
340+
windowStore.setFocus('chunkList');
340341
341342
// 如果没有按住 Ctrl/Meta/Shift,则视为普通单选,清空其他选中
342343
if (!event.ctrlKey && !event.metaKey && !event.shiftKey) {
@@ -365,9 +366,9 @@ function handleDelete(chunkId: string) {
365366
targets.forEach((id) => {
366367
chunkEditorStore.deleteChunk(id);
367368
368-
// UI 同步:从 uiStore 中彻底注销窗口
369-
if (uiStore.isWindowOpen(id)) {
370-
uiStore.unregisterWindow(id);
369+
// UI 同步:从 windowStore 中彻底注销窗口
370+
if (windowStore.isWindowOpen(id)) {
371+
windowStore.unregisterWindow(id);
371372
}
372373
});
373374

0 commit comments

Comments
 (0)