Skip to content

Commit

Permalink
feat: realtime typing (#42)
Browse files Browse the repository at this point in the history
* wip: add instant text transmission

not yet togglable or spam guarded

* add ability to toggle realtime text

* fix issues when deleting all textbox text manually for realtime text

* add option to adjust footer size
  • Loading branch information
naeruru authored Sep 6, 2024
1 parent 9eb8a74 commit b0d84f1
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 17 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 44 additions & 4 deletions src/components/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,42 @@
</v-btn>
</template>
</v-snackbar>
<v-footer app class="d-flex flex-column pl-2" height="55" permanent fixed>
<v-footer app class="d-flex flex-column pl-2" :height="$route.name === 'home' && appearanceStore.footer_size ? 200 : 55" permanent fixed>
<div class="d-flex w-100 align-center">
<v-form
class="d-flex w-100 align-center"
@submit.prevent="onSubmit()"
>
<div class="d-flex w-100 align-center">
<div class="d-flex w-100">

<v-textarea
v-if="$route.name === 'home' && appearanceStore.footer_size"
v-model="input_text"
variant="outlined"
:label="$t('general.type_message')"
append-inner-icon="mdi-chevron-right"
class="mr-6 mt-1 fill-height"
rows="6"
hide-details
flat
loading
@keyup.enter="onSubmit()"
>
<template #loader>
<v-progress-linear
:active="logsStore.loading_result || translationStore.download >= 0"
:color="translationStore.download !== -1 ? 'warning' : 'secondary'"
:indeterminate="translationStore.download === -1"
:model-value="translationStore.download"
:max="100"
height="5"
rounded
/>
</template>
</v-textarea>

<v-text-field
v-else
v-model="input_text"
density="compact"
variant="outlined"
Expand Down Expand Up @@ -73,7 +101,7 @@
@click="toggleBroadcast"
/>
</v-badge>
<v-divider class="mr-4" vertical />
<v-divider height="50" class="mr-4" vertical />
<v-btn
v-if="$route.name === 'home'" color="transparent"
size="small"
Expand Down Expand Up @@ -111,6 +139,8 @@ import { useLogsStore } from '@/stores/logs'
import { useTranslationStore } from '@/stores/translation'
import { useOSCStore } from '@/stores/osc'
import { useDefaultStore } from '@/stores/default'
import { useSettingsStore } from '@/stores/settings'
import { useAppearanceStore } from '@/stores/appearance'
declare const window: any
Expand All @@ -121,9 +151,12 @@ const logsStore = useLogsStore()
const translationStore = useTranslationStore()
const oscStore = useOSCStore()
const defaultStore = useDefaultStore()
const settingsStore = useSettingsStore()
const appearanceStore = useAppearanceStore()
const router = useRouter()
const input_text = ref('')
const input_index = ref<any>(null)
const windowSize = ref({
x: 0,
Expand All @@ -137,6 +170,12 @@ const last_setting = computed(() => {
watch(input_text, () => {
if (oscStore.osc_text && oscStore.text_typing && defaultStore.broadcasting)
typing_event(true)
if (input_index.value === null) {
input_index.value = logsStore.logs.length
}
if (settingsStore.realtime_text)
speechStore.submit_text(input_text.value, input_index.value, false)
})
const { stt } = storeToRefs(speechStore)
Expand Down Expand Up @@ -296,10 +335,11 @@ async function onSubmit(log: Log | null = null) {
}
if (log && log.isFinal)
paramTrigger(log.transcript)
speechStore.on_submit(log, Math.max(logsStore.logs.length - 1, 0))
speechStore.on_submit(log, input_index.value ?? Math.max(logsStore.logs.length - 1, 0))
// clear chatbox
input_text.value = ''
input_index.value = null
}
function toggleBroadcast() {
Expand Down
9 changes: 7 additions & 2 deletions src/pages/Home.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<v-card
id="log-list" v-resize="onResize" class="fill-height pa-4 overflow-auto log-list"
:color="appearanceStore.ui.color" :height="height - 55" tile
:color="appearanceStore.ui.color" :height="height - (appearanceStore.footer_size ? 200 : 55)" tile
>
<div>
<a
Expand Down Expand Up @@ -64,7 +64,12 @@ const windowSize = ref({
y: 0,
})
const outer_size = computed(() => is_electron() ? '90px' : '55px')
const outer_size = computed(() => {
let value = 55
if (is_electron()) value += 35
if (appearanceStore.footer_size) value += 145
return `${value}px`
})
onMounted(() => {
if (appearanceStore.current_theme in theme.themes.value)
Expand Down
19 changes: 18 additions & 1 deletion src/pages/settings/Appearance.vue
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,22 @@
</v-col>
<v-divider />
</v-row>
<v-row>
<v-col :cols="12">
<p class="text-h6">
{{ $t('settings.appearance.footer') }}
</p>
</v-col>
<v-col>
<v-select
v-model="footer_size"
:items="footer_size_options"
:label="$t('settings.appearance.footer_size.hint')"
variant="solo"
hide-details
/>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
Expand All @@ -187,6 +203,7 @@ const { tm } = useI18n()
const theme = useTheme()
const line_delay_options: any[] = JSON.parse(JSON.stringify(tm('settings.appearance.text.new_line_delay.options')))
const footer_size_options: any[] = JSON.parse(JSON.stringify(tm('settings.appearance.footer_size.options')))
const fonts = ref< Font[]>([])
Expand All @@ -195,7 +212,7 @@ onMounted(async () => {
.then(res => fonts.value = res)
})
const { text, ui, current_theme } = storeToRefs(useAppearanceStore())
const { text, ui, current_theme, footer_size } = storeToRefs(useAppearanceStore())
watch(
() => text.value.font,
(v) => {
Expand Down
66 changes: 57 additions & 9 deletions src/pages/settings/General.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,65 @@
<v-divider />
</v-row>
<v-row>
<v-col :cols="12" class="d-flex flex-no-wrap justify-space-between">
<v-card-text class="text-subtitle-1 font-weight-medium">
{{ $t('settings.general.transcript') }}
</v-card-text>
<v-btn color="primary" class="mt-2" @click="logsStore.exportLogs()">
<v-icon>mdi-download</v-icon>
</v-btn>
<v-col :cols="12" :md="12" class="pb-0">
<v-card>
<v-list-item :title="$t('settings.general.realtime_text')">
<template #append>
<v-switch
v-model="settingsStore.realtime_text"
color="primary"
hide-details
inset
/>
</template>
</v-list-item>
</v-card>
</v-col>
<v-divider />
</v-row>
<v-row class="mt-12">
</v-row>
<v-row>
<v-col :cols="12" class="pb-0">
<v-card>
<v-list-item :title="$t('settings.general.transcript')">
<template #append>
<v-btn color="primary" class="my-2" @click="logsStore.exportLogs()">
<v-icon>mdi-download</v-icon>
</v-btn>
</template>
</v-list-item>
</v-card>
</v-col>
</v-row>
<v-row>
<v-col :cols="12" class="pb-0">
<v-card>
<v-list-item :title="$t('settings.general.reset.button')">
<template #append>
<v-btn color="error" class="my-2">
<v-icon>mdi-restore</v-icon>
<v-dialog
v-model="reset_dialog"
activator="parent"
max-width="500"
>
<v-card>
<v-card-title>{{ $t('settings.general.reset.dialog.title') }}</v-card-title>
<v-card-text>
{{ $t('settings.general.reset.dialog.description') }}
</v-card-text>
<v-btn class="mt-2" color="error" @click="reset_settings()">
{{ $t('settings.general.reset.dialog.button') }}
</v-btn>
</v-card>
</v-dialog>
</v-btn>
</template>
</v-list-item>
</v-card>
</v-col>
</v-row>
<!-- <v-row>
<v-col :cols="12" :md="12" class="d-flex flex-no-wrap justify-space-between">
<v-card-text class="text-subtitle-1 font-weight-medium">
{{ $t('settings.general.reset.button') }}
Expand All @@ -68,7 +116,7 @@
</v-btn>
</v-col>
<v-divider />
</v-row>
</v-row> -->
</v-card-text>
</v-card>
</template>
Expand Down
15 changes: 15 additions & 0 deletions src/plugins/localization/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default {
description: 'General application settings',
language: 'Select a UI language',
transcript: 'Download session transcript',
realtime_text: 'Instant textbox updates',
reset: {
button: 'Reset all settings',
dialog: {
Expand Down Expand Up @@ -80,6 +81,20 @@ export default {
title: 'Appearance',
description: 'Change the appearance of the app',
theme: 'Theme',
footer: 'Footer Settings',
footer_size: {
hint: 'Footer size',
options: [
{
title: 'Small',
value: 0
},
{
title: 'Large',
value: 1
}
]
},
text: {
title: 'Text Settings',
font_family: 'Font family',
Expand Down
15 changes: 15 additions & 0 deletions src/plugins/localization/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default {
description: 'アプリ全般の設定',
language: 'UIの言語を選択',
transcript: 'セッショントランスクリプトをダウンロードする',
realtime_text: 'テキストボックスのテキストは継続的に送信する',
reset: {
button: 'アプリの設定をリセットする',
dialog: {
Expand Down Expand Up @@ -80,6 +81,20 @@ export default {
title: 'テーマ',
description: 'アプリのテーマを変更',
theme: 'テーマ',
footer: 'フッター設定',
footer_size: {
hint: 'フッターサイズ',
options: [
{
title: '小さい',
value: 0
},
{
title: '大きい',
value: 1
}
]
},
text: {
title: '文字設定',
font_family: 'フォント',
Expand Down
2 changes: 2 additions & 0 deletions src/stores/appearance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ref } from 'vue'

export const useAppearanceStore = defineStore('appearance', () => {
const current_theme = ref('midnight_purple')
const footer_size = ref(0)

const text = ref({
color: '#FFFFFF',
Expand Down Expand Up @@ -39,6 +40,7 @@ export const useAppearanceStore = defineStore('appearance', () => {

return {
current_theme,
footer_size,
text,
ui,
}
Expand Down
2 changes: 2 additions & 0 deletions src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ref } from 'vue'
export const useSettingsStore = defineStore('settings', () => {
const welcome = ref(true)
const drawer = ref(true)
const realtime_text = ref(false)

const stt_Settings = ref({
language: 'en-US',
Expand All @@ -30,6 +31,7 @@ export const useSettingsStore = defineStore('settings', () => {
return {
welcome,
drawer,
realtime_text,
stt_Settings,
languages,
language,
Expand Down
Loading

0 comments on commit b0d84f1

Please sign in to comment.