|
|
@ -1,31 +1,6 @@ |
|
|
|
<template> |
|
|
|
<section> |
|
|
|
<div class="CharacterTab"> |
|
|
|
<form class="field" @submit.prevent="q = q0"> |
|
|
|
<label for="q" class="label"> |
|
|
|
Search |
|
|
|
<b-tooltip label="How to?" position="is-right"> |
|
|
|
<a |
|
|
|
href="https://github.com/zhquiz/zhquiz/wiki/How-to-search-or-filter" |
|
|
|
target="_blank" |
|
|
|
rel="noopener noreferrer" |
|
|
|
> |
|
|
|
<b-icon icon="info-circle"></b-icon> |
|
|
|
</a> |
|
|
|
</b-tooltip> |
|
|
|
</label> |
|
|
|
<div class="control"> |
|
|
|
<input |
|
|
|
v-model="q0" |
|
|
|
class="input" |
|
|
|
type="search" |
|
|
|
name="q" |
|
|
|
placeholder="Type here to search." |
|
|
|
aria-label="search" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</form> |
|
|
|
|
|
|
|
<div class="columns"> |
|
|
|
<div class="column is-6 entry-display"> |
|
|
|
<div |
|
|
@ -234,7 +209,7 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
|
import { Component, Prop, Ref, Vue, Watch } from 'nuxt-property-decorator' |
|
|
|
import { Component, Prop, Ref, Vue } from 'nuxt-property-decorator' |
|
|
|
import ContextMenu from '@/components/ContextMenu.vue' |
|
|
|
import { api, IDictionaryLookup, IEntryLookup, IType } from '~/assets/api' |
|
|
|
|
|
|
@ -262,33 +237,26 @@ const makeLookupEntry = ( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Component<LookupTab>({ |
|
|
|
@Component<DictionaryTab>({ |
|
|
|
components: { |
|
|
|
ContextMenu, |
|
|
|
}, |
|
|
|
async created() { |
|
|
|
this.$emit('title', this.title) |
|
|
|
|
|
|
|
this.q = this.query.q || '' |
|
|
|
|
|
|
|
if (this.additionalContext[0]) { |
|
|
|
await this.additionalContext[0].handler() |
|
|
|
} |
|
|
|
this.$emit('title', `${this.query.entry} - ${this.query.type}`) |
|
|
|
this.loadComponents() |
|
|
|
this.loadVocabularies() |
|
|
|
this.loadSentences() |
|
|
|
}, |
|
|
|
}) |
|
|
|
export default class LookupTab extends Vue { |
|
|
|
@Prop({ default: () => ({}) }) query!: { |
|
|
|
q?: string |
|
|
|
entry?: string |
|
|
|
type?: 'character' | 'vocabulary' |
|
|
|
export default class DictionaryTab extends Vue { |
|
|
|
@Prop() query!: { |
|
|
|
entry: string |
|
|
|
type: IType |
|
|
|
} |
|
|
|
|
|
|
|
@Ref() context!: ContextMenu |
|
|
|
|
|
|
|
title = 'Lookup' |
|
|
|
|
|
|
|
entries: ILookupEntry[] = [] |
|
|
|
i = 0 |
|
|
|
entry = makeLookupEntry(this.query.entry, this.query.type) |
|
|
|
|
|
|
|
lookup: Record<IType, IDictionaryLookup[]> = { |
|
|
|
character: [], |
|
|
@ -305,91 +273,30 @@ export default class LookupTab extends Vue { |
|
|
|
type: '', |
|
|
|
} |
|
|
|
|
|
|
|
q = '' |
|
|
|
q0 = '' |
|
|
|
|
|
|
|
get entry() { |
|
|
|
return this.entries[this.i] || makeLookupEntry() |
|
|
|
} |
|
|
|
|
|
|
|
get additionalContext() { |
|
|
|
if (!(this.q || '').trim()) { |
|
|
|
return [ |
|
|
|
{ |
|
|
|
name: 'Reload', |
|
|
|
handler: async () => { |
|
|
|
const { result } = await api.all_getRandom({ type: 'vocabulary' }) |
|
|
|
this.q0 = result |
|
|
|
}, |
|
|
|
}, |
|
|
|
] |
|
|
|
} |
|
|
|
|
|
|
|
return [] |
|
|
|
} |
|
|
|
|
|
|
|
openContext(evt: MouseEvent, entry = this.selected) { |
|
|
|
this.selected = entry |
|
|
|
this.context.open(evt) |
|
|
|
} |
|
|
|
|
|
|
|
@Watch('q') |
|
|
|
async onQChange(q: string) { |
|
|
|
this.$emit('title', (q ? q + ' - ' : '') + this.title) |
|
|
|
this.entries = [] |
|
|
|
|
|
|
|
if (q.trim()) { |
|
|
|
const r = await api.all_getQuery({ |
|
|
|
q, |
|
|
|
type: this.query.type, |
|
|
|
distinct: 'id', |
|
|
|
}) |
|
|
|
this.entries = r.result.map(({ entry, type }) => |
|
|
|
makeLookupEntry(entry, type) |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
this.i = 0 |
|
|
|
} |
|
|
|
|
|
|
|
@Watch('entry.entry') |
|
|
|
load() { |
|
|
|
if (this.entry.entry) { |
|
|
|
this.loadComponents() |
|
|
|
this.loadVocabularies() |
|
|
|
this.loadSentences() |
|
|
|
} else { |
|
|
|
this.lookup = { |
|
|
|
character: [], |
|
|
|
vocabulary: [], |
|
|
|
sentence: [], |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async loadComponents() { |
|
|
|
const entry = this.entries[this.i] |
|
|
|
if (!entry) return |
|
|
|
|
|
|
|
const [comp, dict] = await Promise.all([ |
|
|
|
api.all_getComponent({ |
|
|
|
entry: entry.entry, |
|
|
|
type: entry.type, |
|
|
|
entry: this.query.entry, |
|
|
|
type: this.query.type, |
|
|
|
}), |
|
|
|
api |
|
|
|
.all_getLookup({ |
|
|
|
entry: entry.entry, |
|
|
|
type: entry.type, |
|
|
|
entry: this.query.entry, |
|
|
|
type: this.query.type, |
|
|
|
limit: 1, |
|
|
|
}) |
|
|
|
.then(({ result: [r] }) => r), |
|
|
|
]) |
|
|
|
|
|
|
|
this.$set(this.entries, this.i, { |
|
|
|
this.entry = { |
|
|
|
...this.query, |
|
|
|
...(dict || { |
|
|
|
entry: entry.entry, |
|
|
|
list: [], |
|
|
|
type: entry.type, |
|
|
|
reading: [], |
|
|
|
translation: [], |
|
|
|
audio: [], |
|
|
@ -404,29 +311,26 @@ export default class LookupTab extends Vue { |
|
|
|
amalgamation: [], |
|
|
|
component: [], |
|
|
|
}), |
|
|
|
} as ILookupEntry) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
async loadVocabularies() { |
|
|
|
const entry = this.entries[this.i] |
|
|
|
if (!entry) return |
|
|
|
|
|
|
|
if (entry.type === 'character') { |
|
|
|
if (!/^\p{sc=Han}$/u.test(entry.entry)) { |
|
|
|
if (this.query.type === 'character') { |
|
|
|
if (!/^\p{sc=Han}$/u.test(this.query.entry)) { |
|
|
|
this.lookup.vocabulary = [] |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.lookup.vocabulary = await api |
|
|
|
.character_getVocabulary({ |
|
|
|
entry: entry.entry, |
|
|
|
entry: this.query.entry, |
|
|
|
distinct: 'id', |
|
|
|
}) |
|
|
|
.then((r) => r.result) |
|
|
|
} else { |
|
|
|
this.lookup.vocabulary = await api |
|
|
|
.vocabulary_getVocabulary({ |
|
|
|
entry: entry.entry, |
|
|
|
entry: this.query.entry, |
|
|
|
distinct: 'id', |
|
|
|
}) |
|
|
|
.then((r) => r.result) |
|
|
@ -434,25 +338,22 @@ export default class LookupTab extends Vue { |
|
|
|
} |
|
|
|
|
|
|
|
async loadSentences() { |
|
|
|
const entry = this.entries[this.i] |
|
|
|
if (!entry) return |
|
|
|
|
|
|
|
if (entry.type === 'character') { |
|
|
|
if (!/^\p{sc=Han}$/u.test(entry.entry)) { |
|
|
|
if (this.query.type === 'character') { |
|
|
|
if (!/^\p{sc=Han}$/u.test(this.query.entry)) { |
|
|
|
this.lookup.sentence = [] |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.lookup.sentence = await api |
|
|
|
.character_getSentence({ |
|
|
|
entry: entry.entry, |
|
|
|
entry: this.query.entry, |
|
|
|
distinct: 'id', |
|
|
|
}) |
|
|
|
.then((r) => r.result) |
|
|
|
} else { |
|
|
|
this.lookup.sentence = await api |
|
|
|
.vocabulary_getSentence({ |
|
|
|
entry: entry.entry, |
|
|
|
entry: this.query.entry, |
|
|
|
distinct: 'id', |
|
|
|
}) |
|
|
|
.then((r) => r.result) |
|
|
|