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