diff --git a/assets/api.ts b/assets/api.ts index b139abf..be4941b 100644 --- a/assets/api.ts +++ b/assets/api.ts @@ -6,7 +6,7 @@ export interface IEntry { id: string entry: string[] reading: string[] - english: string[] + translation: string[] type: IType description: string tag: string[] @@ -148,7 +148,7 @@ class Api { } async extra_delete(params: { id: string }) { - return await this.axios.delete('/api/extra/delete', { + return await this.axios.delete('/api/extra', { params, }) } @@ -167,7 +167,9 @@ class Api { ) } - async character_getVocabulary(params: ILookup<{ entry: string }>) { + async character_getVocabulary( + params: ILookup<{ entry: string; distinct?: 'id' }> + ) { return await this.axios.get('/api/character/vocabulary', { params }).then( (r) => r.data as ILookupResult<{ @@ -176,7 +178,9 @@ class Api { ) } - async character_getSentence(params: ILookup<{ entry: string }>) { + async character_getSentence( + params: ILookup<{ entry: string; distinct?: 'id' }> + ) { return await this.axios.get('/api/character/sentence', { params }).then( (r) => r.data as ILookupResult<{ diff --git a/assets/util.ts b/assets/util.ts index bc6797a..b75e646 100644 --- a/assets/util.ts +++ b/assets/util.ts @@ -74,3 +74,7 @@ export function capitalize(s: string): string { if (!s) return s return s[0].toLocaleUpperCase() + s.substr(1) } + +export function jsonClone(o: T): T { + return JSON.parse(JSON.stringify(o)) +} diff --git a/components/ContextMenu.vue b/components/ContextMenu.vue index e4a08f6..a61ef87 100644 --- a/components/ContextMenu.vue +++ b/components/ContextMenu.vue @@ -40,42 +40,39 @@ Remove from quiz -
  • +
  • -
  • - +
  • + Show details
  • -
  • - +
  • + {{ type === 'character' ? 'Show details' : 'Search for Hanzi' }}
  • -
  • - +
  • + Search for vocabs
  • -
  • +
  • Open in Jisho.org
  • -
  • +
  • import { Vue, Component, Prop, Ref } from 'nuxt-property-decorator' -import { speak } from '@/assets/speak' -import { api } from '~/assets/api' +import { speak } from '~/assets/speak' +import { api, IType } from '~/assets/api' @Component export default class ContextMenu extends Vue { @Prop() id?: string - @Prop() entry?: string | string[] - @Prop() type?: string + @Prop() entry?: string + @Prop() list?: string[] + @Prop() type?: IType @Prop() source?: string @Prop() direction?: string @Prop() description?: string - @Prop({ default: () => ({}) }) pinyin!: Record - @Prop({ default: () => ({}) }) english!: Record @Prop({ default: () => [] }) additional!: { name: string @@ -134,15 +130,11 @@ export default class ContextMenu extends Vue { } get entries() { - return Array.isArray(this.entry) - ? this.entry - : this.entry - ? [this.entry] - : [] + return this.list || (this.entry ? [this.entry] : []) } async setQuiz() { - if (this.entry && this.type) { + if (this.entries.length && this.type) { const { result } = await api.quiz_getMany({ entries: this.entries, select: ['id', 'entry'], @@ -168,21 +160,8 @@ export default class ContextMenu extends Vue { } open(evt: MouseEvent) { - this.$nextTick(async () => { - if (this.entry && this.type) { - if ( - !( - this.quiz.of && - this.quiz.of.type !== this.type && - this.quiz.of.entries.length === this.entries.length && - this.quiz.of.entries.every((el, i) => this.entries[i] === el) - ) - ) { - await this.setQuiz() - } - - this.contextmenu.open(evt) - } + this.$nextTick(() => { + this.contextmenu.open(evt) }) } @@ -197,8 +176,8 @@ export default class ContextMenu extends Vue { } async doSpeak() { - if (this.entries.length === 1) { - await speak(this.entries[0]) + if (this.entry) { + await speak(this.entry) } } diff --git a/components/tabs/BrowseTab.vue b/components/tabs/BrowseTab.vue index 787df5e..78a1e09 100644 --- a/components/tabs/BrowseTab.vue +++ b/components/tabs/BrowseTab.vue @@ -67,8 +67,8 @@ @@ -77,7 +77,7 @@ @click="(ev) => onTableContextmenu(props.row, ev)" @contextmenu.prevent="(ev) => onTableContextmenu(props.row, ev)" > -
    +
    {{ it }}
    @@ -122,16 +122,16 @@ placeholder="Must not be empty" > - + @@ -179,7 +179,8 @@ ({ components: { @@ -220,11 +222,15 @@ export default class BrowseTab extends Vue { type: 'desc', } - selected: IEntry = { + selected: Omit & { + entry: string + list: string[] + } = { id: '', - entry: [], + entry: '', + list: [], reading: [], - english: [], + translation: [], type: 'vocabulary', description: '', tag: [], @@ -257,8 +263,8 @@ export default class BrowseTab extends Vue { ] } - if (!this.selected.english.length) { - this.selected.english = await api + if (!this.selected.translation.length) { + this.selected.translation = await api .all_getMeaning({ entry: this.selected.entry[0], }) @@ -292,9 +298,8 @@ export default class BrowseTab extends Vue { async doCreate() { const { id } = await api.extra_create({ ...this.selected, - description: this.selected.description || '', + entry: this.selected.list, }) - this.selected.id = id await this.context.addToQuiz() @@ -309,7 +314,7 @@ export default class BrowseTab extends Vue { if (id) { await api.extra_update({ ...this.selected, - description: this.selected.description || '', + entry: this.selected.list, id, }) @@ -337,9 +342,10 @@ export default class BrowseTab extends Vue { onNewItem() { this.selected = { id: '', - entry: [], + entry: '', + list: [], reading: [], - english: [], + translation: [], type: 'vocabulary', description: '', tag: [], @@ -351,7 +357,12 @@ export default class BrowseTab extends Vue { async onTableContextmenu(row: IEntry, evt: MouseEvent) { evt.preventDefault() - this.selected = JSON.parse(JSON.stringify(row)) + const o = jsonClone(row) + this.selected = { + ...o, + entry: o.entry[0], + list: o.entry, + } this.context.open(evt) } diff --git a/components/tabs/CharacterTab.vue b/components/tabs/CharacterTab.vue index 62faab2..02f539b 100644 --- a/components/tabs/CharacterTab.vue +++ b/components/tabs/CharacterTab.vue @@ -95,21 +95,25 @@
    - +
    - {{ english.join(' / ') }} + {{ translation.join(' / ') }}
    @@ -222,7 +226,7 @@ [{{ v.reading.join(' / ') }}] - {{ v.english.join(' / ') }} + {{ v.translation.join(' / ') }} @@ -244,15 +248,15 @@
    - {{ s.entry }} + {{ s.entry[0] }} - {{ s.english }} + {{ s.translation[0] }}
    @@ -304,7 +308,7 @@ export default class CharacterTab extends Vue { visual: string[] = [] reading: string[] = [] - english: string[] = [] + translation: string[] = [] tag: string[] = [] level = 0 @@ -387,7 +391,7 @@ export default class CharacterTab extends Vue { this.visual = [] this.reading = [] - this.english = [] + this.translation = [] this.tag = [] this.level = 0 this.vocabulary_lookup = [] @@ -402,7 +406,7 @@ export default class CharacterTab extends Vue { this.variant = [] this.visual = [] - this.english = [] + this.translation = [] this.tag = [] this.level = 0 return @@ -428,7 +432,7 @@ export default class CharacterTab extends Vue { }) this.reading = r?.reading || [] - this.english = r?.english || [] + this.translation = r?.translation || [] this.tag = r?.tag || [] this.level = r?.level || 0 })(), @@ -443,6 +447,7 @@ export default class CharacterTab extends Vue { const { result } = await api.character_getVocabulary({ entry: this.current, + distinct: 'id', }) this.vocabulary_lookup = await Promise.all( @@ -465,6 +470,7 @@ export default class CharacterTab extends Vue { const { result } = await api.character_getSentence({ entry: this.current, + distinct: 'id', }) this.vocabulary_lookup = await Promise.all(