Skip to content

Commit

Permalink
fix: resolve repeated initialization of SakuraTypewriter
Browse files Browse the repository at this point in the history
  • Loading branch information
WRXinYue committed Jul 24, 2024
1 parent 5753f3c commit db1769d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 34 deletions.
54 changes: 21 additions & 33 deletions theme/components/plugins/SakuraTypewriter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { onMounted, onUnmounted, ref, watch } from 'vue'
import type { Options } from 'typeit'
import TypeIt from 'typeit'
import { watchOnce } from '@vueuse/core'
const props = withDefaults(defineProps<{
[key: string]: any
Expand All @@ -10,7 +11,7 @@ const props = withDefaults(defineProps<{
typeString: '',
})
const emit = defineEmits(['typingFinished', 'deletionFinished'])
const emit = defineEmits(['typingFinished', 'deletionFinished', 'allTypingFinished'])
export interface TypewriterProps {
/**
Expand Down Expand Up @@ -50,24 +51,15 @@ export interface TypewriterProps {
const typewriterElement = ref<HTMLElement | null>(null)
let refreshNeeded = false
let instance: TypeIt | null = null
let hasInitialized = false
onMounted(() => {
createTypewriter(Array.isArray(props.typeString) ? props.typeString : [props.typeString])
})
function createTypewriter(typeStrings: string[]) {
const options = {
deleteSpeed: props.deleteSpeed,
loop: props.loop,
} as Options
if (instance !== null)
destroyTypewriter()
instance = new TypeIt(typewriterElement.value!, options)
// const typeStrings = Array.isArray(props.typeString) ? props.typeString : [props.typeString]
if (instance === null)
instance = new TypeIt(typewriterElement.value!, options)
typeStrings.forEach((str, index) => {
// TODO: Add typing speed config
Expand All @@ -78,9 +70,10 @@ function createTypewriter(typeStrings: string[]) {
else if (Array.isArray(props.pauseFor))
instance!.pause(props.pauseFor[index])
instance!.exec(() => {
emit('typingFinished', str)
})
instance!.exec(() => emit('typingFinished'))
if (index === typeStrings.length - 1)
instance!.exec(() => emit('allTypingFinished'))
if (props.deleteAll === true) {
instance!.delete()
Expand All @@ -96,38 +89,33 @@ function createTypewriter(typeStrings: string[]) {
}
}
})
instance.go()
// Calling `.flush()` eliminates the need to call `.go()`
instance.flush(() => {
emit('deletionFinished')
// If typeString changes, refresh in the next step
if (refreshNeeded) {
refreshNeeded = false
destroyTypewriter()
// @ts-expect-error missing types
instance = instance!.reset()
createTypewriter(Array.isArray(props.typeString) ? props.typeString : [props.typeString])
refreshNeeded = false
}
})
}
function destroyTypewriter() {
if (instance) {
instance.destroy()
instance = null
}
}
watch(() => props.typeString, () => {
refreshNeeded = true
if (!hasInitialized) {
watch(() => props.typeString, () => refreshNeeded = true)
onMounted(() => {
if (props.typeString) {
createTypewriter(Array.isArray(props.typeString) ? props.typeString : [props.typeString])
hasInitialized = true
}
else { // If the data is empty, it is likely reactive, enable a one-time watch to ensure reactive data is displayed immediately
watchOnce(() => props.typeString, () => {
createTypewriter(Array.isArray(props.typeString) ? props.typeString : [props.typeString])
})
}
})
onUnmounted(() => {
destroyTypewriter()
})
onUnmounted(() => instance?.destroy())
</script>

<template>
Expand Down
2 changes: 1 addition & 1 deletion theme/components/themes/InfoOverlayThemeSakura.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function nextMedia() {
<span class="px-2 text-lg">
<template v-if="themeConfig.banner.typewriter">
<SakuraTypewriter v-if="!banner.enableHitokoto" :type-string="banner.motto" loop :delay="100" :pause-for="10000" :delete-all="100" />
<SakuraTypewriter v-else :type-string="hitokoto.hitokoto" loop :delay="100" :pause-for="10000" :delete-all="100" @typing-finished="fetchHitokoto()" />
<SakuraTypewriter v-else :type-string="hitokoto.hitokoto" loop :delay="100" :pause-for="10000" :delete-all="100" @all-typing-finished="fetchHitokoto()" />
</template>
<template v-else>
{{ banner.enableHitokoto ? hitokoto.hitokoto : banner.motto }}
Expand Down

0 comments on commit db1769d

Please sign in to comment.