forked from Mirrors/elk
feat(publish): hoist selected language and none
This commit is contained in:
parent
154885ca96
commit
b0d6f310a8
2 changed files with 73 additions and 50 deletions
72
components/publish/PublishLanguagePicker.vue
Normal file
72
components/publish/PublishLanguagePicker.vue
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import ISO6391 from 'iso-639-1'
|
||||||
|
import Fuse from 'fuse.js'
|
||||||
|
|
||||||
|
let { modelValue } = $defineModel<{
|
||||||
|
modelValue: string | null | undefined
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const languageKeyword = $ref('')
|
||||||
|
|
||||||
|
const languageList: {
|
||||||
|
code: string | null
|
||||||
|
nativeName: string
|
||||||
|
name?: string
|
||||||
|
}[] = [{
|
||||||
|
code: null,
|
||||||
|
nativeName: t('language.none'),
|
||||||
|
}, ...ISO6391.getAllCodes().map(code => ({
|
||||||
|
code,
|
||||||
|
nativeName: ISO6391.getNativeName(code),
|
||||||
|
name: ISO6391.getName(code),
|
||||||
|
}))]
|
||||||
|
|
||||||
|
const fuse = new Fuse(languageList, {
|
||||||
|
keys: ['code', 'nativeName', 'name'],
|
||||||
|
shouldSort: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const languages = $computed(() =>
|
||||||
|
languageKeyword.trim()
|
||||||
|
? fuse.search(languageKeyword).map(r => r.item)
|
||||||
|
: [...languageList].sort(({ code: a }, { code: b }) => {
|
||||||
|
return a === modelValue
|
||||||
|
? -1
|
||||||
|
: b === modelValue
|
||||||
|
? 1
|
||||||
|
: (a === null ? -1 : b === null ? 1 : a.localeCompare(b))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
function chooseLanguage(language: string | null) {
|
||||||
|
modelValue = language
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
v-model="languageKeyword"
|
||||||
|
:placeholder="t('language.search')"
|
||||||
|
p2 mb2 border-rounded w-full bg-transparent
|
||||||
|
outline-none border="~ base"
|
||||||
|
>
|
||||||
|
<div max-h-40vh overflow-auto>
|
||||||
|
<CommonDropdownItem
|
||||||
|
v-for="{ code, nativeName, name } in languages"
|
||||||
|
:key="code"
|
||||||
|
:checked="code === (modelValue || null)"
|
||||||
|
@click="chooseLanguage(code)"
|
||||||
|
>
|
||||||
|
{{ nativeName }}
|
||||||
|
<template #description>
|
||||||
|
<template v-if="name">
|
||||||
|
{{ name }}
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -3,8 +3,6 @@ import type { Attachment, CreateStatusParams, Status, StatusVisibility } from 'm
|
||||||
import { fileOpen } from 'browser-fs-access'
|
import { fileOpen } from 'browser-fs-access'
|
||||||
import { useDropZone } from '@vueuse/core'
|
import { useDropZone } from '@vueuse/core'
|
||||||
import { EditorContent } from '@tiptap/vue-3'
|
import { EditorContent } from '@tiptap/vue-3'
|
||||||
import ISO6391 from 'iso-639-1'
|
|
||||||
import Fuse from 'fuse.js'
|
|
||||||
import { statusVisibilities } from '~/composables/masto/icons'
|
import { statusVisibilities } from '~/composables/masto/icons'
|
||||||
import type { Draft } from '~/types'
|
import type { Draft } from '~/types'
|
||||||
|
|
||||||
|
@ -138,10 +136,6 @@ function chooseVisibility(visibility: StatusVisibility) {
|
||||||
draft.params.visibility = visibility
|
draft.params.visibility = visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseLanguage(language: string | null) {
|
|
||||||
draft.params.language = language
|
|
||||||
}
|
|
||||||
|
|
||||||
async function publish() {
|
async function publish() {
|
||||||
const payload = {
|
const payload = {
|
||||||
...draft.params,
|
...draft.params,
|
||||||
|
@ -188,29 +182,6 @@ async function onDrop(files: File[] | null) {
|
||||||
|
|
||||||
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
|
const { isOverDropZone } = useDropZone(dropZoneRef, onDrop)
|
||||||
|
|
||||||
const languageKeyword = $ref('')
|
|
||||||
const languageList: {
|
|
||||||
code: string | null
|
|
||||||
nativeName: string
|
|
||||||
name?: string
|
|
||||||
}[] = [{
|
|
||||||
code: null,
|
|
||||||
nativeName: t('language.none'),
|
|
||||||
}, ...ISO6391.getAllCodes().map(code => ({
|
|
||||||
code,
|
|
||||||
nativeName: ISO6391.getNativeName(code),
|
|
||||||
name: ISO6391.getName(code),
|
|
||||||
}))]
|
|
||||||
const fuse = new Fuse(languageList, {
|
|
||||||
keys: ['code', 'nativeName', 'name'],
|
|
||||||
shouldSort: true,
|
|
||||||
})
|
|
||||||
const languages = $computed(() =>
|
|
||||||
languageKeyword.trim()
|
|
||||||
? fuse.search(languageKeyword).map(r => r.item)
|
|
||||||
: languageList,
|
|
||||||
)
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
focusEditor: () => {
|
focusEditor: () => {
|
||||||
editor.value?.commands?.focus?.()
|
editor.value?.commands?.focus?.()
|
||||||
|
@ -363,27 +334,7 @@ defineExpose({
|
||||||
|
|
||||||
<template #popper>
|
<template #popper>
|
||||||
<div min-w-80 p3>
|
<div min-w-80 p3>
|
||||||
<input
|
<PublishLanguagePicker v-model="draft.params.language" />
|
||||||
v-model="languageKeyword"
|
|
||||||
:placeholder="t('language.search')"
|
|
||||||
p2 mb2 border-rounded w-full bg-transparent
|
|
||||||
outline-none border="~ base"
|
|
||||||
>
|
|
||||||
<div max-h-40vh overflow-auto>
|
|
||||||
<CommonDropdownItem
|
|
||||||
v-for="{ code, nativeName, name } in languages"
|
|
||||||
:key="code"
|
|
||||||
:checked="code === (draft.params.language || null)"
|
|
||||||
@click="chooseLanguage(code)"
|
|
||||||
>
|
|
||||||
{{ nativeName }}
|
|
||||||
<template #description>
|
|
||||||
<template v-if="name">
|
|
||||||
{{ name }}
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</CommonDropdownItem>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</CommonDropdown>
|
</CommonDropdown>
|
||||||
|
|
Loading…
Reference in a new issue