This commit is contained in:
polv committed 2021-10-24 22:44:24 +07:00
1 parent d3fdba1139
commit 70066f3086
5 files changed
+82 -78

No files matched your search

+22 -43
View File
@@ -40,42 +40,39 @@
Remove from quiz
</a>
</li>
<li v-if="entries.length === 1" class="separator">
<li v-if="entry" class="separator">
<a></a>
</li>
<li v-if="entries.length === 1 && type === 'vocabulary'">
<a
role="button"
@click="openInNewTab('Vocabulary', { entry: entries[0] })"
>
<li v-if="entry && type === 'vocabulary'">
<a role="button" @click="openInNewTab('Vocabulary', { entry })">
Show details
</a>
</li>
<li v-if="entries.length === 1">
<a role="button" @click="openInNewTab('Character', { q: entries[0] })">
<li v-if="entry">
<a role="button" @click="openInNewTab('Character', { q: entry })">
{{ type === 'character' ? 'Show details' : 'Search for Hanzi' }}
</a>
</li>
<li v-if="entries.length === 1 && type !== 'character'">
<a role="button" @click="openInNewTab('Vocabulary', { q: entries[0] })">
<li v-if="entry && type !== 'character'">
<a role="button" @click="openInNewTab('Vocabulary', { q: entry })">
Search for vocabs
</a>
</li>
<li v-if="entries.length === 1">
<li v-if="entry">
<a
role="button"
:href="`https://jisho.org/word/${encodeURIComponent(entries[0])}`"
:href="`https://jisho.org/word/${encodeURIComponent(entry)}`"
target="_blank"
rel="noopener noreferrer"
>
Open in Jisho.org
</a>
</li>
<li v-if="entries.length === 1 && type !== 'sentence'">
<li v-if="entry && type !== 'sentence'">
<a
role="button"
:href="`https://dictionary.goo.ne.jp/srch/all/${encodeURIComponent(
entries[0]
entry
)}/m0u`"
target="_blank"
rel="noopener noreferrer"
@@ -98,19 +95,18 @@
<script lang="ts">
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<string, string>
@Prop({ default: () => ({}) }) english!: Record<string, string>
@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)
}
}
+30 -19
View File
@@ -67,8 +67,8 @@
</span>
</b-table-column>
<b-table-column
field="english"
label="English"
field="translation"
label="Translation"
v-slot="props"
width="40vw"
>
@@ -77,7 +77,7 @@
@click="(ev) => onTableContextmenu(props.row, ev)"
@contextmenu.prevent="(ev) => onTableContextmenu(props.row, ev)"
>
<div v-for="it in props.row.english" :key="it">
<div v-for="it in props.row.translation" :key="it">
{{ it }}
</div>
</span>
@@ -122,16 +122,16 @@
placeholder="Must not be empty"
></b-input>
</b-field>
<b-field label="English">
<b-field label="Translation">
<template slot="label">
English
Translation
<b-tooltip type="is-dark" label="New-line separated">
<b-icon size="is-small" icon="info-circle"></b-icon>
</b-tooltip>
</template>
<b-input
:value="selected.english.join('\n')"
@input="(ev) => (selected.english = ev.trim().split('\n'))"
:value="selected.translation.join('\n')"
@input="(ev) => (selected.translation = ev.trim().split('\n'))"
type="textarea"
placeholder="Must not be empty"
></b-input>
@@ -179,7 +179,8 @@
<ContextMenu
:id="selected.id"
ref="context"
:entry="selected.entry[0]"
:entry="selected.entry"
:list="selected.list"
:type="selected.type || 'vocabulary'"
:description="selected.description"
source="extra"
@@ -193,6 +194,7 @@
import { Component, Ref, Vue, Watch } from 'nuxt-property-decorator'
import ContextMenu from '@/components/ContextMenu.vue'
import { api, IEntry } from '~/assets/api'
import { jsonClone } from '~/assets/util'
@Component<BrowseTab>({
components: {
@@ -220,11 +222,15 @@ export default class BrowseTab extends Vue {
type: 'desc',
}
selected: IEntry = {
selected: Omit<IEntry, 'entry'> & {
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)
}
+18 -12
View File
@@ -95,21 +95,25 @@
</div>
</b-collapse>
<b-collapse class="card" animation="slide" :open="!!english.length">
<b-collapse
class="card"
animation="slide"
:open="!!translation.length"
>
<div
slot="trigger"
slot-scope="props"
class="card-header"
role="button"
>
<h2 class="card-header-title">English</h2>
<h2 class="card-header-title">Translation</h2>
<a role="button" class="card-header-icon">
<fontawesome :icon="props.open ? 'caret-down' : 'caret-up'" />
</a>
</div>
<div class="card-content">
{{ english.join(' / ') }}
{{ translation.join(' / ') }}
</div>
</b-collapse>
@@ -222,7 +226,7 @@
<span class="pinyin">[{{ v.reading.join(' / ') }}]</span>
<span>{{ v.english.join(' / ') }}</span>
<span>{{ v.translation.join(' / ') }}</span>
</div>
</div>
</b-collapse>
@@ -244,15 +248,15 @@
<div v-for="(s, i) in sentences" :key="i" class="long-item">
<span
class="clickable"
@click="(evt) => openContext(evt, s.entry, 'sentence')"
@click="(evt) => openContext(evt, s.entry[0], 'sentence')"
@contextmenu.prevent="
(evt) => openContext(evt, s.entry, 'sentence')
(evt) => openContext(evt, s.entry[0], 'sentence')
"
>
{{ s.entry }}
{{ s.entry[0] }}
</span>
<span>{{ s.english }}</span>
<span>{{ s.translation[0] }}</span>
</div>
</div>
</b-collapse>
@@ -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(