Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 20 additions & 24 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,13 @@ const showTabSwitchDialog = ref(false)
const pendingTabSwitch = ref(null)

// Add this watch effect after the state declarations
watch(text, (newValue) => {
// If text is edited and differs from original file content, clear the file association
if (currentFileId.value && newValue !== originalFileContent.value) {
currentFileId.value = null
}
}, { deep: true })
watch(
text,
(newValue) => {
fileUploadStore.clearCurrentFileIfTextEdited(newValue)
},
{ deep: true }
)

// --- PROFILE MANAGEMENT FUNCTIONS ---
async function onProfileSelect(profileId) {
Expand All @@ -169,7 +170,9 @@ async function onProfileSelect(profileId) {
voice.value = val
// Pipeline will be automatically updated via the watch in SpeakerSelection
},
setVolume: (val) => { volume.value = val },
setVolume: (val) => {
ttsStore.setVolumeAndApply(val, setVolume)
},
setFiles: (files) => { setFiles(files) }
})
} catch (error) {
Expand All @@ -184,7 +187,9 @@ async function onProfileCreate(data) {
data.volume / 100,
{
setVoice: (val) => { voice.value = val },
setVolume: (val) => { volume.value = val },
setVolume: (val) => {
ttsStore.setVolumeAndApply(val, setVolume)
},
setFiles: (files) => { setFiles(files) }
}
)
Expand Down Expand Up @@ -248,15 +253,6 @@ function handleSeek(event) {
if (!isNaN(pos)) { seekToPosition(pos) }
}

watch(volume, (newVal) => {
setVolume(newVal / 100)
})
watch(unifiedBuffer, (newBuffer) => {
if (newBuffer) {
setTotalDuration(newBuffer.duration)
ttsStore.setUnifiedBuffer(newBuffer)
}
})

onMounted(() => {
const slider = mainContent.value?.audioControls?.volumeSlider
Expand All @@ -272,13 +268,13 @@ onMounted(async () => {
})

const keydownHandler = event => {
globalHandleKeydown(event, {
currentSource,
togglePlayback,
volume,
setVolume,
isDownloadComplete,
seekRelative
globalHandleKeydown(event, {
currentSource,
togglePlayback,
volume,
applyVolume: (val) => ttsStore.setVolumeAndApply(val, setVolume),
isDownloadComplete,
seekRelative
});
}
onMounted(() => {
Expand Down
7 changes: 3 additions & 4 deletions frontend/src/composables/usePlayback.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function usePlayback(audioContext, gainNode) {
const ttsStore = useTTSStore()
const {
volume,
setVolume: updateVolume,
setVolumeAndApply,
isPlaying,
currentSource,
playbackProgress,
Expand Down Expand Up @@ -115,9 +115,8 @@ export function usePlayback(audioContext, gainNode) {
}

function handleVolumeChange(event, setVolume) {
const newVol = parseFloat(event.target.value) / 100
updateVolume(parseInt(event.target.value))
setVolume(newVol)
const newVol = parseInt(event.target.value)
setVolumeAndApply(newVol, setVolume)
event.target.style.setProperty('--volume-percentage', `${volume.value}%`)
}

Expand Down
18 changes: 9 additions & 9 deletions frontend/src/composables/useTTS.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function useTTS() {
currentTime,
isDownloadComplete,
downloadProgress,
setUnifiedBuffer,
updateUnifiedBuffer,
setIsPlaying,
setCurrentSource,
setPlaybackProgress,
Expand Down Expand Up @@ -84,7 +84,7 @@ export function useTTS() {
setIsDownloadComplete(false)
setDownloadProgress(0)
audioQueue.length = 0
setUnifiedBuffer(null)
updateUnifiedBuffer(null, setTotalDuration)
// make sure we start in streaming mode for new generations:
streamingMode = true

Expand Down Expand Up @@ -114,8 +114,7 @@ export function useTTS() {
}

if (totalChunks === 1) {
setUnifiedBuffer(firstChunk.buffer)
setTotalDuration(unifiedBuffer.value.duration)
updateUnifiedBuffer(firstChunk.buffer, setTotalDuration)
setIsDownloadComplete(true)
} else {
fetchNextChunks(text, voice, isGenerating, unifiedBuffer, audioQueue, isDownloadComplete)
Expand Down Expand Up @@ -240,7 +239,7 @@ export function useTTS() {
setDownloadProgress(0)
audioQueue.length = 0
chunkCache.clear()
setUnifiedBuffer(null)
updateUnifiedBuffer(null, setTotalDuration)
// For multi-speaker we immediately get a full WAV; so switch to unifiedBuffer mode:
streamingMode = false

Expand All @@ -265,9 +264,10 @@ export function useTTS() {

const sessionId = multiResponse.sessionId
const arrayBuffer = multiResponse.arrayBuffer
setUnifiedBuffer(await audioContext.value.decodeAudioData(arrayBuffer))

setTotalDuration(unifiedBuffer.value.duration)
updateUnifiedBuffer(
await audioContext.value.decodeAudioData(arrayBuffer),
setTotalDuration
)
setIsDownloadComplete(true)

currentSource.value = audioContext.value.createBufferSource()
Expand Down Expand Up @@ -347,7 +347,7 @@ export function useTTS() {
resetChunks()
audioQueue.length = 0
currentChunkIndex.value = 0
setUnifiedBuffer(null)
updateUnifiedBuffer(null, setTotalDuration)
setDownloadProgress(0)
setPlaybackProgress(0)
setIsDownloadComplete(false)
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/stores/fileUploadStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ export const useFileUploadStore = defineStore('fileUpload', () => {
}
}

function clearCurrentFileIfTextEdited(newText) {
if (currentFileId.value && newText !== originalFileContent.value) {
currentFileId.value = null
}
}

return {
uploadedFiles,
progressMessage,
Expand All @@ -204,6 +210,7 @@ export const useFileUploadStore = defineStore('fileUpload', () => {
processFile,
handleFileSelect,
handleFileDrop,
handleFileClick
handleFileClick,
clearCurrentFileIfTextEdited
}
})
19 changes: 18 additions & 1 deletion frontend/src/stores/ttsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ export const useTTSStore = defineStore('tts', () => {
downloadProgress.value = val
}

function setVolumeAndApply(val, applyFn) {
volume.value = val
if (typeof applyFn === 'function') {
applyFn(val / 100)
}
}

function updateUnifiedBuffer(buffer, setDuration) {
setUnifiedBuffer(buffer)
if (typeof setDuration === 'function') {
const duration = buffer ? buffer.duration : 0
setDuration(duration)
}
}

return {
volume,
isGenerating,
Expand All @@ -76,6 +91,8 @@ export const useTTSStore = defineStore('tts', () => {
setPlaybackProgress,
setCurrentTime,
setIsDownloadComplete,
setDownloadProgress
setDownloadProgress,
setVolumeAndApply,
updateUnifiedBuffer
}
})
16 changes: 11 additions & 5 deletions frontend/src/utils/generalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function cancelTabSwitch({ pendingTabSwitch, showTabSwitchDialog }) {

// --- New keydown handler helper function ---

export function handleKeydown(event, { currentSource, togglePlayback, volume, setVolume, seekRelative }) {
export function handleKeydown(event, { currentSource, togglePlayback, volume, applyVolume, seekRelative }) {
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') return;

switch (event.code) {
Expand All @@ -65,14 +65,20 @@ export function handleKeydown(event, { currentSource, togglePlayback, volume, se
case 'ArrowUp':
event.preventDefault();
const newVolUp = Math.min(100, volume.value + 5);
volume.value = newVolUp;
setVolume(newVolUp / 100);
if (applyVolume) {
applyVolume(newVolUp);
} else {
volume.value = newVolUp;
}
break;
case 'ArrowDown':
event.preventDefault();
const newVolDown = Math.max(0, volume.value - 5);
volume.value = newVolDown;
setVolume(newVolDown / 100);
if (applyVolume) {
applyVolume(newVolDown);
} else {
volume.value = newVolDown;
}
break;
case 'ArrowLeft':
event.preventDefault();
Expand Down