Files
frontend-miniapp/src/components/audio/GlobalAudioPlayerHost.vue
lyf 653ec67b14
Some checks failed
CI / verify (push) Has been cancelled
修复讲解详情播放器语言切换重复显示
2026-07-10 10:21:15 +08:00

155 lines
2.9 KiB
Vue

<template>
<AudioPlayer
v-if="isHostVisible"
controlled
:visible="visible"
:audio="currentAudio"
:playing="playing"
:loading="loading"
:playback-error="error"
:current-time="currentTime"
:duration-value="duration"
:closable="closable"
:expandable="expandable"
:avoid-bottom-nav="avoidBottomNav"
:mode="currentDisplayMode"
@toggle="handleToggle"
@collapse="handleCollapse"
@stop="handleStop"
@close="player.close"
@seek="player.seekToPercent"
@expand="handleExpand"
@update:visible="handleVisibleChange"
/>
</template>
<script setup lang="ts">
import { computed, onMounted, onUnmounted, watch } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AudioPlayer, {
type AudioDisplayMode
} from '@/components/audio/AudioPlayer.vue'
import { useGlobalAudioPlayer } from '@/composables/useGlobalAudioPlayer'
const props = withDefaults(defineProps<{
avoidBottomNav?: boolean
displayMode?: AudioDisplayMode
closable?: boolean
expandable?: boolean
}>(), {
avoidBottomNav: true,
displayMode: 'mini',
closable: true,
expandable: true
})
const player = useGlobalAudioPlayer()
const {
currentAudio,
currentSource,
visible,
playing,
loading,
error,
currentTime,
duration,
displayMode: currentDisplayMode,
activeHostId,
hasAudio
} = player
const hostId = player.registerHost()
const isHostVisible = computed(() => (
visible.value
&& hasAudio.value
&& activeHostId.value === hostId
))
const handleToggle = () => {
if (playing.value) {
player.pause()
return
}
void player.resume()
}
const applyHostDisplayMode = () => {
if (!hasAudio.value) {
return
}
if (currentDisplayMode.value !== props.displayMode) {
player.setDisplayMode(props.displayMode)
}
}
const isCurrentH5Route = (route: string) => {
if (typeof window === 'undefined') return false
return window.location.hash.replace(/^#/, '') === route
}
const handleStop = () => {
player.stop()
}
const handleCollapse = () => {
player.collapse(props.displayMode === 'floating' ? 'floating' : 'mini')
}
const handleVisibleChange = (visible: boolean) => {
if (!visible && hasAudio.value) {
player.collapse(props.displayMode === 'floating' ? 'floating' : 'mini')
}
}
const handleExpand = () => {
if (!props.expandable) return
if (currentDisplayMode.value === 'floating') {
player.setDisplayMode('mini')
return
}
player.setDisplayMode('expanded')
const route = currentSource.value?.detailRoute
if (!route) {
return
}
if (isCurrentH5Route(route)) {
return
}
uni.navigateTo({
url: route
})
}
onMounted(() => {
player.activateHost(hostId)
applyHostDisplayMode()
})
onShow(() => {
player.activateHost(hostId)
applyHostDisplayMode()
})
onUnmounted(() => {
player.unregisterHost(hostId)
})
watch(
() => props.displayMode,
() => {
applyHostDisplayMode()
}
)
watch(hasAudio, () => {
applyHostDisplayMode()
})
</script>