add contextmenu

This commit is contained in:
polv committed 2021-10-24 18:16:46 +07:00
1 parent 1c53acbe2c
commit f0bd330d04
18 files changed
+912 -131

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
const allVoices: Record<string, string> = {}
// eslint-disable-next-line array-callback-return
speechSynthesis.getVoices().map((v) => {
allVoices[v.lang] = v.lang
})
speechSynthesis.onvoiceschanged = () => {
// eslint-disable-next-line array-callback-return
speechSynthesis.getVoices().map((v) => {
allVoices[v.lang] = v.lang
})
}
export async function speak(
s: string,
opts: {
lang?: string
forceOffline?: boolean
} = {}
) {
if (!opts.forceOffline) {
const audio = new Audio(
`/api/tts?q=${encodeURIComponent(s)}&lang=${encodeURIComponent(
opts.lang || 'ja'
)}`
)
await audio.play().catch(() =>
speak(s, {
...opts,
forceOffline: true,
})
)
return
}
let lang = 'zh'
const voices = Object.keys(allVoices)
const stage1 = () => voices.filter((v) => v === lang)[0]
const stage2 = () => {
const m1 = lang.substr(0, 2)
const m2 = lang.substr(3, 2)
const r1 = new RegExp(`^${m1}[-_]${m2}`, 'i')
return voices.filter((v) => r1.test(v))[0]
}
const stage3 = () => {
const m1 = lang.substr(0, 2).toLocaleLowerCase()
return voices.filter((v) => v.toLocaleLowerCase().startsWith(m1))[0]
}
lang = stage1() || stage2() || stage3() || ''
if (lang) {
const utterance = new SpeechSynthesisUtterance(s)
utterance.lang = lang
speechSynthesis.speak(utterance)
return new Promise<void>((resolve) => {
utterance.onend = () => {
resolve()
}
})
}
}
window.addEventListener('keydown', (ev) => {
if (
ev.target instanceof HTMLElement &&
['INPUT', 'TEXTAREA'].includes(ev.target.tagName.toLocaleUpperCase())
) {
return
}
if (ev.key === 's') {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const s = window.getSelection()!.toString()
if (s) {
speak(s)
}
}
})