Skip to content

Commit b55e0e0

Browse files
committed
pin languages and popular input methods
1 parent 7f10dc5 commit b55e0e0

File tree

3 files changed

+55
-20
lines changed

3 files changed

+55
-20
lines changed

src/InputMethodConfig.vue

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script lang="ts">
22
import type { MenuOption } from 'naive-ui'
3-
import { NButton, NCheckbox, NCheckboxGroup, NFlex, NLayout, NLayoutFooter, NLayoutSider, NMenu } from 'naive-ui'
3+
import { NButton, NCheckbox, NCheckboxGroup, NFlex, NLayout, NLayoutFooter, NLayoutSider, NMenu, NText } from 'naive-ui'
44
import { computed, h, ref, watchEffect } from 'vue'
55
import BasicConfig from './BasicConfig.vue'
66
import FooterButtons from './FooterButtons.vue'
@@ -13,11 +13,17 @@ const languageName = new Intl.DisplayNames(navigator.language, { type: 'language
1313
1414
function getNameOf(code: string) {
1515
try {
16-
return languageName.of(code) ?? code
16+
const name = languageName.of(code)
17+
if (name && name !== code) {
18+
return name
19+
}
1720
}
18-
catch { // e.g. code === '*' (m17n math-latex)
19-
return code
21+
catch {}
22+
const name = window.fcitx.getLanguageName(code)
23+
if (name) {
24+
return name
2025
}
26+
return `${t('Unknown')} - ${code}`
2127
}
2228
</script>
2329

@@ -31,6 +37,9 @@ const props = defineProps<{
3137
onClose: () => void
3238
}>()
3339
40+
const EN = 'en'
41+
const popularIMs = ['keyboard-us', 'pinyin', 'shuangpin', 'wbx', 'rime', 'mozc', 'hallelujah']
42+
3443
const enabledIMs = computed(() => props.inputMethods.map(({ name }) => name))
3544
3645
const selectedInputMethod = ref(props.inputMethod)
@@ -70,6 +79,7 @@ function labelWithMinus(option: MenuOption) {
7079
const collapsed = ref(false)
7180
const adding = ref(false)
7281
82+
const currentLanguages = navigator.languages.map(lang => lang.split('-')[0])
7383
const selectedLanguage = ref<string | null>(null)
7484
7585
const languageOptions = ref<{
@@ -90,7 +100,7 @@ watchEffect(() => {
90100
map = {}
91101
languageOfIM = {}
92102
for (const im of window.fcitx.getAllInputMethods()) {
93-
const code = im.languageCode.replace('_', '-');
103+
const code = im.languageCode.replace('_', '-') || 'und';
94104
(map[code] = map[code] || []).push({
95105
name: im.name,
96106
displayName: im.displayName,
@@ -99,25 +109,29 @@ watchEffect(() => {
99109
}
100110
languageOptions.value = []
101111
const sortedLanguageCodes = Object.keys(map).sort((a: string, b: string) => {
102-
if (!a) {
103-
return 1
104-
}
105-
if (!b) {
112+
// Pin English.
113+
if (a === EN) {
106114
return -1
107115
}
108-
const la = getNameOf(a)
109-
const lb = getNameOf(b)
110-
if (a === la && b !== lb) {
116+
if (b === EN) {
111117
return 1
112118
}
113-
if (a !== la && b === lb) {
119+
// Pin browser languages.
120+
const aIsCurrent = currentLanguages.includes(a.split('-')[0])
121+
const bIsCurrent = currentLanguages.includes(b.split('-')[0])
122+
if (aIsCurrent && !bIsCurrent) {
114123
return -1
115124
}
125+
if (!aIsCurrent && bIsCurrent) {
126+
return 1
127+
}
128+
const la = getNameOf(a)
129+
const lb = getNameOf(b)
116130
return la.localeCompare(lb)
117131
})
118132
for (const languageCode of sortedLanguageCodes) {
119133
languageOptions.value.push({
120-
label: languageCode ? getNameOf(languageCode) : 'Unknown',
134+
label: getNameOf(languageCode),
121135
key: languageCode,
122136
})
123137
}
@@ -127,7 +141,21 @@ const inputMethodsForLanguage = computed(() => {
127141
if (selectedLanguage.value === null) {
128142
return []
129143
}
130-
return map[selectedLanguage.value].filter(({ name }) => !enabledIMs.value.includes(name))
144+
return map[selectedLanguage.value].filter(({ name }) => !enabledIMs.value.includes(name)).sort((a, b) => {
145+
// Pin popular input methods.
146+
const ia = popularIMs.indexOf(a.name)
147+
const ib = popularIMs.indexOf(b.name)
148+
if (ia >= 0 && ib < 0) {
149+
return -1
150+
}
151+
if (ia < 0 && ib >= 0) {
152+
return 1
153+
}
154+
if (ia >= 0 && ib >= 0) {
155+
return ia - ib
156+
}
157+
return a.displayName.localeCompare(b.displayName)
158+
})
131159
})
132160
133161
const imsToAdd = ref<string[]>([])
@@ -142,9 +170,11 @@ const onlyShowCurrentLanguage = ref(false)
142170
143171
const filteredLanguageOptions = computed(() => {
144172
if (onlyShowCurrentLanguage.value) {
145-
const currentLanguage = navigator.language.split('-')[0]
146173
const languages = new Set(enabledIMs.value.map(name => languageOfIM[name]).filter(code => code))
147-
languages.add(currentLanguage)
174+
languages.add(EN)
175+
for (const lang of currentLanguages) {
176+
languages.add(lang)
177+
}
148178
return languageOptions.value.filter(({ key }) => languages.has(key.split('-')[0]))
149179
}
150180
return languageOptions.value
@@ -225,8 +255,11 @@ const filteredLanguageOptions = computed(() => {
225255
v-for="im of inputMethodsForLanguage"
226256
:key="im.name"
227257
:value="im.name"
228-
:label="im.displayName"
229-
/>
258+
>
259+
<NText :strong="popularIMs.includes(im.name)">
260+
{{ im.displayName }}
261+
</NText>
262+
</NCheckbox>
230263
</NFlex>
231264
</NCheckboxGroup>
232265
</NLayout>

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { default as AdvancedConfig } from './AdvancedConfig.vue'
2+
export { default as FileEditor } from './FileEditor.vue'
23
export { default as GearButton } from './GearButton.vue'
34
export { default as GlobalConfig } from './GlobalConfig.vue'
45
export { getLocale } from './i18n'

src/locales/zh-CN.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
"Reset to default": "重设为默认值",
1313
"Select a language from the left list": "从左侧列表中选择一个语言",
1414
"Warning": "警告",
15-
"Undo": "撤销"
15+
"Undo": "撤销",
16+
"Unknown": "未知"
1617
}

0 commit comments

Comments
 (0)