Skip to content

Commit 60d8d93

Browse files
committed
realtime effective; undo/redo
1 parent 62e043f commit 60d8d93

File tree

8 files changed

+127
-115
lines changed

8 files changed

+127
-115
lines changed

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
"build": "vite build && vue-tsc -d --emitDeclarationOnly"
1212
},
1313
"devDependencies": {
14-
"@antfu/eslint-config": "^5.2.1",
14+
"@antfu/eslint-config": "^5.4.1",
1515
"@vitejs/plugin-vue": "^6.0.1",
16-
"eslint": "^9.33.0",
16+
"eslint": "^9.36.0",
1717
"fcitx5-js": "file:cache/fcitx5-js.tgz",
18-
"naive-ui": "^2.42.0",
18+
"naive-ui": "^2.43.1",
1919
"typescript": "5.9.2",
20-
"vite": "^7.1.2",
20+
"vite": "^7.1.7",
2121
"vooks": "^0.2.12",
22-
"vue": "^3.5.18",
22+
"vue": "^3.5.22",
2323
"vue-i18n": "11",
24-
"vue-tsc": "^3.0.5"
24+
"vue-tsc": "^3.0.8"
2525
}
2626
}

src/AdvancedConfig.vue

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script setup lang="ts">
22
import { NLayout, NLayoutFooter, NLayoutSider, NMenu } from 'naive-ui'
3-
import { computed, ref, watchEffect } from 'vue'
3+
import { computed, ref } from 'vue'
44
import BasicConfig from './BasicConfig.vue'
55
import FooterButtons from './FooterButtons.vue'
6-
import { extractValue } from './util'
6+
import { ConfigManager } from './manager'
77
88
defineProps<{
99
onClose: () => void
@@ -21,25 +21,9 @@ const options = window.fcitx.getAddons().map(category => ({
2121
2222
const addon = ref(options[0].children[0].key)
2323
24-
const uri = computed(() => `fcitx://config/addon/${addon.value}`)
25-
26-
const config = computed(() => window.fcitx.getConfig(uri.value))
24+
const manager = computed(() => new ConfigManager(`fcitx://config/addon/${addon.value}`))
2725
2826
const collapsed = ref(false)
29-
30-
const form = ref({})
31-
32-
watchEffect(() => {
33-
form.value = extractValue(config.value, false)
34-
})
35-
36-
function reset() {
37-
form.value = extractValue(config.value, true)
38-
}
39-
40-
function apply() {
41-
window.fcitx.setConfig(uri.value, form.value)
42-
}
4327
</script>
4428

4529
<template>
@@ -67,17 +51,16 @@ function apply() {
6751
>
6852
<BasicConfig
6953
:path="addon"
70-
:config="config"
71-
:value="form"
54+
:config="manager.config"
55+
:value="manager.form.value"
7256
style="margin: 16px"
73-
@update="v => form = v"
57+
@update="(v) => manager.set(v)"
7458
/>
7559
</NLayout>
7660
<NLayoutFooter position="absolute">
7761
<FooterButtons
78-
:reset="reset"
79-
:apply="apply"
80-
:close="onClose"
62+
:manager="manager"
63+
@close="onClose"
8164
/>
8265
</NLayoutFooter>
8366
</NLayout>

src/FooterButtons.vue

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<script setup lang="ts">
2+
import type { ConfigManager } from './manager'
23
import { NButton, NFlex } from 'naive-ui'
34
import { t } from './i18n'
45
56
defineProps<{
6-
reset: () => void
7-
close: () => void
8-
apply: () => void
7+
manager: ConfigManager
8+
}>()
9+
10+
defineEmits<{
11+
close: []
912
}>()
1013
</script>
1114

@@ -16,30 +19,31 @@ defineProps<{
1619
<NFlex>
1720
<NButton
1821
secondary
19-
@click="reset"
22+
:disabled="manager.undoStack.value.length === 0"
23+
@click="manager.undo()"
2024
>
21-
{{ t('Reset to default') }}
25+
{{ t('Undo') }}
2226
</NButton>
2327
<NButton
2428
secondary
25-
@click="close"
29+
:disabled="manager.redoStack.value.length === 0"
30+
@click="manager.redo()"
2631
>
27-
{{ t('Cancel') }}
32+
{{ t('Redo') }}
2833
</NButton>
29-
</NFlex>
30-
<NFlex>
3134
<NButton
3235
secondary
33-
@click="apply"
36+
@click="manager.reset()"
3437
>
35-
Apply
38+
{{ t('Reset to default') }}
3639
</NButton>
40+
</NFlex>
41+
<NFlex>
3742
<NButton
3843
secondary
39-
type="info"
40-
@click="apply(); close()"
44+
@click="$emit('close')"
4145
>
42-
OK
46+
{{ t('Close') }}
4347
</NButton>
4448
</NFlex>
4549
</NFlex>

src/InputMethodConfig.vue

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { computed, h, ref, watchEffect } from 'vue'
55
import BasicConfig from './BasicConfig.vue'
66
import FooterButtons from './FooterButtons.vue'
77
import { t } from './i18n'
8+
import { ConfigManager } from './manager'
89
import MinusButton from './MinusButton.vue'
910
import PlusButton from './PlusButton.vue'
10-
import { extractValue } from './util'
1111
1212
const languageName = new Intl.DisplayNames(navigator.language, { type: 'language' })
1313
@@ -34,9 +34,7 @@ const props = defineProps<{
3434
const enabledIMs = computed(() => props.inputMethods.map(({ name }) => name))
3535
3636
const selectedInputMethod = ref(props.inputMethod)
37-
const uri = computed(() => `fcitx://config/inputmethod/${selectedInputMethod.value}`)
38-
39-
const config = computed(() => window.fcitx.getConfig(uri.value))
37+
const manager = computed(() => new ConfigManager(`fcitx://config/inputmethod/${selectedInputMethod.value}`))
4038
4139
const options = computed(() =>
4240
props.inputMethods.map(({ displayName, name }) => ({
@@ -151,20 +149,6 @@ const filteredLanguageOptions = computed(() => {
151149
}
152150
return languageOptions.value
153151
})
154-
155-
const form = ref({})
156-
157-
watchEffect(() => {
158-
form.value = extractValue(config.value, false)
159-
})
160-
161-
function reset() {
162-
form.value = extractValue(config.value, true)
163-
}
164-
165-
function apply() {
166-
window.fcitx.setConfig(uri.value, form.value)
167-
}
168152
</script>
169153

170154
<template>
@@ -272,17 +256,16 @@ function apply() {
272256
>
273257
<BasicConfig
274258
:path="selectedInputMethod"
275-
:config="config"
276-
:value="form"
259+
:config="manager.config"
260+
:value="manager.form.value"
277261
style="margin: 16px"
278-
@update="v => form = v"
262+
@update="(v) => manager.set(v)"
279263
/>
280264
</NLayout>
281265
<NLayoutFooter position="absolute">
282266
<FooterButtons
283-
:reset="reset"
284-
:apply="apply"
285-
:close="onClose"
267+
:manager="manager"
268+
@close="onClose"
286269
/>
287270
</NLayoutFooter>
288271
</template>

src/SplitConfig.vue

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,24 @@
11
<script setup lang="ts">
2-
import type { Config } from 'fcitx5-js'
32
import { NLayout, NLayoutFooter, NLayoutSider, NMenu } from 'naive-ui'
4-
import { ref } from 'vue'
3+
import { computed, ref } from 'vue'
54
import BasicConfig from './BasicConfig.vue'
65
import FooterButtons from './FooterButtons.vue'
7-
import { extractValue } from './util'
6+
import { ConfigManager } from './manager'
87
98
const props = defineProps<{
109
uri: string
1110
onClose: () => void
1211
}>()
1312
14-
const index = ref(0)
15-
const config = {
16-
Children: [],
17-
...window.fcitx.getConfig(props.uri),
18-
}
19-
const options = config.Children.map((child, i) => ({
13+
const options = { Children: [], ...window.fcitx.getConfig(props.uri) }.Children.map((child, i) => ({
2014
key: i,
2115
label: child.Description,
2216
}))
2317
24-
const collapsed = ref(false)
25-
26-
function childToConfig(child: typeof config.Children[0]): Config {
27-
return { Children: child.Children || [] }
28-
}
29-
30-
const form = ref(extractValue(config, false))
31-
32-
function reset() {
33-
form.value[config.Children[index.value].Option] = extractValue(childToConfig(config.Children[index.value]), true)
34-
}
18+
const index = ref(0)
19+
const manager = computed(() => new ConfigManager(props.uri, index.value))
3520
36-
function apply() {
37-
window.fcitx.setConfig(props.uri, form.value)
38-
}
21+
const collapsed = ref(false)
3922
</script>
4023

4124
<template>
@@ -62,18 +45,17 @@ function apply() {
6245
style="bottom: 50px"
6346
>
6447
<BasicConfig
65-
:path="config.Children[index].Option"
66-
:config="childToConfig(config.Children[index])"
67-
:value="form[config.Children[index].Option]"
48+
:path="{ Option: '', ...manager.config }.Option"
49+
:config="manager.config"
50+
:value="manager.form.value"
6851
style="margin: 16px"
69-
@update="v => form[config.Children[index].Option] = v"
52+
@update="(v) => manager.set(v)"
7053
/>
7154
</NLayout>
7255
<NLayoutFooter position="absolute">
7356
<FooterButtons
74-
:reset="reset"
75-
:apply="apply"
76-
:close="onClose"
57+
:manager="manager"
58+
@close="onClose"
7759
/>
7860
</NLayoutFooter>
7961
</NLayout>

src/locales/zh-CN.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
"Add": "添加",
33
"Available": "可用",
44
"Cancel": "取消",
5+
"Close": "关闭",
56
"Download and drag zip to this area": "下载并拖拽 zip 到此区域",
67
"Installed": "已安装",
78
"Mozc doesn't work on Chrome unless start the process with": "Mozc 在 Chrome 下不工作,除非用如下参数启动进程",
89
"Only show current language": "只显示当前语言",
10+
"Redo": "重做",
911
"Reset to default": "重设为默认值",
1012
"Select a language from the left list": "从左侧列表中选择一个语言",
11-
"Warning": "警告"
13+
"Warning": "警告",
14+
"Undo": "撤销"
1215
}

src/manager.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { Config } from 'fcitx5-js'
2+
import type { Ref } from 'vue'
3+
import { ref } from 'vue'
4+
import { extractValue } from './util'
5+
6+
export class ConfigManager {
7+
uri: string
8+
index: number | undefined
9+
config: Config
10+
form: Ref<any>
11+
undoStack: Ref<any[]>
12+
redoStack: Ref<any[]>
13+
14+
constructor(uri: string, index?: number) {
15+
this.uri = uri
16+
this.index = index
17+
const configForUri = window.fcitx.getConfig(uri)
18+
if (index === undefined) {
19+
this.config = configForUri
20+
}
21+
else {
22+
this.config = { Children: [], ...configForUri }.Children[index] as Config
23+
}
24+
this.form = ref(extractValue(this.config, false))
25+
this.undoStack = ref([])
26+
this.redoStack = ref([])
27+
}
28+
29+
save(value: any) {
30+
this.form.value = value
31+
if (this.index === undefined) {
32+
window.fcitx.setConfig(this.uri, value)
33+
}
34+
else {
35+
window.fcitx.setConfig(this.uri, { [{ Option: '', ...this.config }.Option]: value })
36+
}
37+
}
38+
39+
set(value: any) {
40+
this.undoStack.value.push(this.form.value)
41+
this.redoStack.value = []
42+
this.save(value)
43+
}
44+
45+
undo() {
46+
const last = this.undoStack.value.pop()
47+
if (last) {
48+
this.redoStack.value.push(this.form.value)
49+
this.save(last)
50+
}
51+
}
52+
53+
redo() {
54+
const last = this.redoStack.value.pop()
55+
if (last) {
56+
this.undoStack.value.push(this.form.value)
57+
this.save(last)
58+
}
59+
}
60+
61+
reset() {
62+
this.set(extractValue(this.config, true))
63+
}
64+
}

0 commit comments

Comments
 (0)