@@ -63,7 +63,7 @@
|
||||
<text class="time-text">{{ formattedDuration }}</text>
|
||||
</view>
|
||||
|
||||
<view class="expanded-actions">
|
||||
<view class="expanded-actions" :class="{ 'with-close': closable }">
|
||||
<view class="action-btn collapse-action" @tap.stop="handleCollapse">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M6 15L12 9L18 15" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
@@ -77,11 +77,21 @@
|
||||
</svg>
|
||||
<text class="action-text">停止播放</text>
|
||||
</view>
|
||||
<view v-if="closable" class="action-divider"></view>
|
||||
<view v-if="closable" class="action-btn close-action" @tap.stop="handleClose">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M7 7L17 17M17 7L7 17" stroke="currentColor" stroke-width="2.1" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<text class="action-text">关闭播放器</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="displayMode === 'floating'" class="floating-player" @tap="handleExpand">
|
||||
<view class="floating-ring" :style="{ '--progress': progressPercent + '%' }">
|
||||
<view v-if="closable" class="floating-close" @tap.stop="handleClose">
|
||||
<text class="floating-close-text">×</text>
|
||||
</view>
|
||||
<view class="control-btn floating-play" @tap.stop="togglePlay">
|
||||
<svg v-if="displayPlaying" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="6" y="5" width="4" height="14" rx="1" fill="currentColor"/>
|
||||
@@ -96,7 +106,7 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="mini-player" @tap="handleExpand">
|
||||
<view v-else class="mini-player" :class="{ 'with-close': closable }" @tap="handleExpand">
|
||||
<view class="control-btn play-btn mini-play" @tap.stop="togglePlay">
|
||||
<svg v-if="displayPlaying" width="26" height="26" viewBox="0 0 24 24" fill="none">
|
||||
<rect x="6" y="5" width="4" height="14" rx="1" fill="currentColor"/>
|
||||
@@ -143,6 +153,9 @@
|
||||
<path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</view>
|
||||
<view v-if="closable" class="mini-close" @tap.stop="handleClose">
|
||||
<text class="mini-close-text">×</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -176,6 +189,7 @@ const props = defineProps<{
|
||||
currentTime?: number
|
||||
durationValue?: number
|
||||
pendingLanguage?: AudioLanguage | ''
|
||||
closable?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -230,6 +244,7 @@ const displayLoading = computed(() => props.controlled ? props.loading === true
|
||||
const displayPlaybackError = computed(() => props.controlled ? props.playbackError || '' : localPlaybackError.value)
|
||||
const displayCurrentTime = computed(() => props.controlled ? props.currentTime || 0 : localCurrentTime.value)
|
||||
const displayMode = computed<AudioDisplayMode>(() => props.mode || 'mini')
|
||||
const closable = computed(() => props.closable !== false)
|
||||
const audioLanguageOptions: Array<{ value: AudioLanguage; label: string; shortLabel: string }> = [
|
||||
{ value: 'zh-CN', label: '中文', shortLabel: '中文' },
|
||||
{ value: 'en-US', label: 'English', shortLabel: 'EN' }
|
||||
@@ -569,6 +584,17 @@ const handleStop = () => {
|
||||
emit('stop')
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
if (props.controlled) {
|
||||
emit('close')
|
||||
return
|
||||
}
|
||||
|
||||
stopAudio()
|
||||
emit('update:visible', false)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const handleH5LoadedMetadata = () => {
|
||||
const audio = h5AudioElement.value
|
||||
if (!audio) return
|
||||
@@ -936,6 +962,10 @@ defineExpose({
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
|
||||
.expanded-actions.with-close {
|
||||
grid-template-columns: 1fr 1px 1fr 1px 1fr;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
min-width: 0;
|
||||
height: 42px;
|
||||
@@ -950,6 +980,10 @@ defineExpose({
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
}
|
||||
|
||||
.close-action {
|
||||
color: rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.action-divider {
|
||||
width: 1px;
|
||||
height: 26px;
|
||||
@@ -979,6 +1013,14 @@ defineExpose({
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.mini-player.with-close {
|
||||
grid-template-columns: 56px minmax(0, 1fr) auto auto auto;
|
||||
grid-template-areas:
|
||||
"play spacer language expand close"
|
||||
"copy copy copy copy copy"
|
||||
"progress progress progress progress progress";
|
||||
}
|
||||
|
||||
.mini-play {
|
||||
grid-area: play;
|
||||
width: 56px;
|
||||
@@ -1097,6 +1139,23 @@ defineExpose({
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.mini-close {
|
||||
grid-area: close;
|
||||
width: 34px;
|
||||
height: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.82);
|
||||
}
|
||||
|
||||
.mini-close-text {
|
||||
display: block;
|
||||
font-size: 28px;
|
||||
line-height: 28px;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.expand-text {
|
||||
font-size: 18px;
|
||||
line-height: 22px;
|
||||
@@ -1120,6 +1179,26 @@ defineExpose({
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.floating-close {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 5px;
|
||||
right: 7px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: rgba(255, 255, 255, 0.82);
|
||||
}
|
||||
|
||||
.floating-close-text {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.floating-ring::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
@@ -1205,6 +1284,14 @@ defineExpose({
|
||||
row-gap: 6px;
|
||||
}
|
||||
|
||||
.mini-player.with-close {
|
||||
grid-template-columns: 50px minmax(0, 1fr) auto auto;
|
||||
grid-template-areas:
|
||||
"play language expand close"
|
||||
"copy copy copy copy"
|
||||
"progress progress progress progress";
|
||||
}
|
||||
|
||||
.mini-play {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
:current-time="currentTime"
|
||||
:duration-value="duration"
|
||||
:pending-language="pendingLanguage"
|
||||
:closable="closable"
|
||||
:avoid-bottom-nav="avoidBottomNav"
|
||||
:mode="currentDisplayMode"
|
||||
@toggle="handleToggle"
|
||||
@collapse="handleCollapse"
|
||||
@stop="handleStop"
|
||||
@close="player.close"
|
||||
@seek="player.seekToPercent"
|
||||
@expand="handleExpand"
|
||||
@language-change="handleLanguageChange"
|
||||
@@ -34,9 +36,11 @@ import { useGlobalAudioPlayer } from '@/composables/useGlobalAudioPlayer'
|
||||
const props = withDefaults(defineProps<{
|
||||
avoidBottomNav?: boolean
|
||||
displayMode?: AudioDisplayMode
|
||||
closable?: boolean
|
||||
}>(), {
|
||||
avoidBottomNav: true,
|
||||
displayMode: 'mini'
|
||||
displayMode: 'mini',
|
||||
closable: true
|
||||
})
|
||||
|
||||
const player = useGlobalAudioPlayer()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<GlobalAudioPlayerHost
|
||||
:avoid-bottom-nav="audioPlayerAvoidBottomNav"
|
||||
:display-mode="audioPlayerMode"
|
||||
:closable="audioPlayerClosable"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
@@ -57,6 +58,7 @@ withDefaults(defineProps<{
|
||||
cancelLabel?: string
|
||||
audioPlayerAvoidBottomNav?: boolean
|
||||
audioPlayerMode?: AudioDisplayMode
|
||||
audioPlayerClosable?: boolean
|
||||
}>(), {
|
||||
activeTab: 'guide',
|
||||
variant: 'overlay',
|
||||
@@ -68,7 +70,8 @@ withDefaults(defineProps<{
|
||||
backLabel: '返回',
|
||||
cancelLabel: '取消',
|
||||
audioPlayerAvoidBottomNav: true,
|
||||
audioPlayerMode: 'mini'
|
||||
audioPlayerMode: 'mini',
|
||||
audioPlayerClosable: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
variant="static"
|
||||
:show-top-tabs="false"
|
||||
:audio-player-avoid-bottom-nav="false"
|
||||
:audio-player-closable="false"
|
||||
audio-player-mode="expanded"
|
||||
@back="handleBack"
|
||||
>
|
||||
@@ -505,7 +506,8 @@ watch(
|
||||
&& closedSource.targetId === currentAudioTarget.value.targetId
|
||||
&& (!closedSource.lang || closedSource.lang === selectedAudioLanguage.value)
|
||||
) {
|
||||
detailAudioDockDismissed.value = true
|
||||
// 关闭全局播放器后,详情页需要恢复本地播放入口,避免用户无法重新播放。
|
||||
detailAudioDockDismissed.value = false
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user