Files
Starlight_Lancher/apps/app-frontend/src/composables/useTranslationToggle.ts
T

90 lines
2.1 KiB
TypeScript

import { ref } from 'vue'
/**
* Manages translation toggle state (active/loading) with version-based
* cancellation to handle async race conditions.
*
* Usage:
* ```
* const ctrl = useTranslationToggle()
*
* async function doTranslate() {
* const version = ctrl.start()
* try {
* const result = await api()
* if (ctrl.isStale(version)) return // superseded, discard
* // apply result
* ctrl.translationActive.value = true
* } finally {
* ctrl.done(version)
* }
* }
*
* function toggleTranslation() {
* ctrl.toggle(
* () => { restoreOriginal() },
* () => void doTranslate(),
* )
* }
*
* // When new data arrives (e.g. new search results):
* ctrl.cancel()
* ```
*/
export function useTranslationToggle() {
const translationActive = ref(false)
const translationLoading = ref(false)
let _version = 0
/** Bump version, set loading, and return the new version number for staleness checks. */
function start(): number {
translationLoading.value = true
return ++_version
}
/** Returns true if `version` is no longer the current request. */
function isStale(version: number): boolean {
return version !== _version
}
/** Stop loading only if `version` is still current. */
function done(version: number): void {
if (version === _version) translationLoading.value = false
}
/**
* Toggle between original and translated content.
*
* @param showOriginal - callback that restores the original untranslated data
* @param doTranslate - callback that kicks off a new translation
*/
function toggle(showOriginal: () => void, doTranslate: () => void): void {
if (translationActive.value) {
_version++ // cancel any in-flight translation
showOriginal()
translationActive.value = false
translationLoading.value = false
return
}
doTranslate()
}
/** Cancel any in-flight translation and reset to inactive state. Returns the current version. */
function cancel(): number {
_version++
translationActive.value = false
translationLoading.value = false
return _version
}
return {
translationActive,
translationLoading,
start,
isStale,
done,
toggle,
cancel,
}
}