移除播放器语言切换功能
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-09 20:00:57 +08:00
parent d65d02510f
commit 9bff839e54
3 changed files with 5 additions and 263 deletions

View File

@@ -20,28 +20,6 @@
<text class="expanded-subtitle" :class="{ error: displayPlaybackError }">{{ expandedSubtitle }}</text>
</view>
<view class="expanded-side">
<view
v-if="isLanguageSwitchable"
class="player-language-switch expanded-language"
@tap.stop
>
<view
v-for="option in audioLanguageOptions"
:key="option.value"
class="player-language-option"
:class="{
active: effectiveAudioLanguage === option.value,
pending: displayPendingLanguage === option.value,
disabled: isLanguagePending && displayPendingLanguage !== option.value
}"
@tap.stop="handleLanguageChange(option.value)"
>
<text class="player-language-text">{{ formatLanguageOptionText(option) }}</text>
</view>
</view>
<view v-else class="player-language-state expanded-language">
<text class="player-language-text">{{ displayAudioLanguageShort }}</text>
</view>
<view class="control-btn play-btn expanded-play" @tap.stop="togglePlay">
<svg v-if="displayPlaying" width="30" height="30" viewBox="0 0 24 24" fill="none">
<rect x="6" y="5" width="4" height="14" rx="1" fill="currentColor"/>
@@ -102,7 +80,6 @@
</svg>
</view>
<text class="floating-label">讲解</text>
<text class="floating-lang">{{ displayAudioLanguageShort }}</text>
</view>
</view>
@@ -128,25 +105,6 @@
</view>
</view>
<view v-if="isLanguageSwitchable" class="player-language-switch mini-language" @tap.stop>
<view
v-for="option in audioLanguageOptions"
:key="option.value"
class="player-language-option"
:class="{
active: effectiveAudioLanguage === option.value,
pending: displayPendingLanguage === option.value,
disabled: isLanguagePending && displayPendingLanguage !== option.value
}"
@tap.stop="handleLanguageChange(option.value)"
>
<text class="player-language-text">{{ formatLanguageOptionText(option) }}</text>
</view>
</view>
<view v-else class="player-language-state mini-language">
<text class="player-language-text">{{ displayAudioLanguageShort }}</text>
</view>
<view class="expand-action">
<text class="expand-text">展开</text>
<svg width="17" height="17" viewBox="0 0 24 24" fill="none">
@@ -188,7 +146,6 @@ const props = defineProps<{
playbackError?: string
currentTime?: number
durationValue?: number
pendingLanguage?: AudioLanguage | ''
closable?: boolean
}>()
@@ -205,7 +162,6 @@ const emit = defineEmits<{
stop: []
expand: []
seek: [percent: number]
'language-change': [language: AudioLanguage]
}>()
// 状态
@@ -245,31 +201,9 @@ const displayPlaybackError = computed(() => props.controlled ? props.playbackErr
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' }
]
const displayAudioLanguage = computed<AudioLanguage>(() => (
displayAudio.value?.language === 'en-US' ? 'en-US' : 'zh-CN'
))
const supportedAudioLanguages = computed(() => {
const languages = displayAudio.value?.supportedLanguages?.length
? displayAudio.value.supportedLanguages
: [displayAudioLanguage.value]
return Array.from(new Set(languages.filter((language): language is AudioLanguage => (
language === 'zh-CN' || language === 'en-US'
))))
})
const isLanguageSwitchable = computed(() => supportedAudioLanguages.value.length > 1)
const displayPendingLanguage = computed<AudioLanguage | ''>(() => props.pendingLanguage || '')
const effectiveAudioLanguage = computed<AudioLanguage>(() => (
displayPendingLanguage.value || displayAudioLanguage.value
))
const isLanguagePending = computed(() => Boolean(displayPendingLanguage.value))
const displayAudioLanguageShort = computed(() => (
displayAudioLanguage.value === 'en-US' ? 'EN' : '中文'
))
const formattedCurrentTime = computed(() => formatTime(displayCurrentTime.value))
const formattedDuration = computed(() => formatTime(resolvedDuration.value))
const expandedSubtitle = computed(() => {
@@ -286,10 +220,6 @@ const formatTime = (seconds: number): string => {
return `${mins}:${secs.toString().padStart(2, '0')}`
}
const formatLanguageOptionText = (option: { shortLabel: string; value: AudioLanguage }) => (
displayPendingLanguage.value === option.value ? `${option.shortLabel}...` : option.shortLabel
)
// 初始化音频上下文
const initAudio = () => {
if (h5AudioElement.value) return
@@ -610,12 +540,6 @@ const handleH5Play = () => {
}
}
const handleLanguageChange = (language: AudioLanguage) => {
if (isLanguagePending.value) return
if (!supportedAudioLanguages.value.includes(language) || language === displayAudioLanguage.value) return
emit('language-change', language)
}
const handleH5Pause = () => {
isPlaying.value = false
if (currentAudio.value) {
@@ -829,7 +753,6 @@ defineExpose({
.time-text,
.action-text,
.floating-label,
.floating-lang,
.expand-text {
display: block;
}
@@ -1003,7 +926,7 @@ defineExpose({
display: grid;
grid-template-columns: 56px minmax(0, 1fr) auto auto;
grid-template-areas:
"play spacer language expand"
"play spacer spacer expand"
"copy copy copy copy"
"progress progress progress progress";
column-gap: 10px;
@@ -1016,7 +939,7 @@ defineExpose({
.mini-player.with-close {
grid-template-columns: 56px minmax(0, 1fr) auto auto auto;
grid-template-areas:
"play spacer language expand close"
"play spacer spacer expand close"
"copy copy copy copy copy"
"progress progress progress progress progress";
}
@@ -1063,68 +986,6 @@ defineExpose({
height: 4px;
}
.player-language-state,
.player-language-switch {
flex-shrink: 0;
min-width: 56px;
height: 34px;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border-radius: 999px;
border: 1px solid rgba(224, 225, 0, 0.52);
background: rgba(255, 255, 255, 0.02);
color: var(--audio-accent);
}
.mini-language {
grid-area: language;
justify-self: end;
}
.player-language-switch {
min-width: 92px;
padding: 3px;
justify-content: flex-start;
gap: 2px;
}
.player-language-option {
min-width: 40px;
height: 26px;
padding: 0 8px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border-radius: 999px;
color: #ffffff;
}
.player-language-option.active {
background: var(--audio-accent);
color: #050505;
}
.player-language-option.pending {
background: rgba(224, 225, 0, 0.76);
color: #050505;
box-shadow: 0 0 0 1px rgba(224, 225, 0, 0.26);
}
.player-language-option.disabled {
opacity: 0.52;
}
.player-language-text {
font-size: 14px;
line-height: 18px;
font-weight: 900;
color: currentColor;
}
.expand-action {
grid-area: expand;
min-width: 70px;
@@ -1227,25 +1088,6 @@ defineExpose({
color: #ffffff;
}
.floating-lang {
position: relative;
z-index: 1;
min-width: 46px;
height: 23px;
margin-top: 2px;
padding: 0 8px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border: 1px solid rgba(224, 225, 0, 0.7);
border-radius: 999px;
font-size: 13px;
line-height: 18px;
font-weight: 900;
color: var(--audio-accent);
}
@media (min-width: 768px) {
.audio-player:not(.mode-floating) {
width: 402px;
@@ -1277,7 +1119,7 @@ defineExpose({
padding: 10px 12px 12px;
grid-template-columns: 50px minmax(0, 1fr) auto;
grid-template-areas:
"play language expand"
"play spacer expand"
"copy copy copy"
"progress progress progress";
column-gap: 8px;
@@ -1287,7 +1129,7 @@ defineExpose({
.mini-player.with-close {
grid-template-columns: 50px minmax(0, 1fr) auto auto;
grid-template-areas:
"play language expand close"
"play spacer expand close"
"copy copy copy copy"
"progress progress progress progress";
}

View File

@@ -9,7 +9,6 @@
:playback-error="error"
:current-time="currentTime"
:duration-value="duration"
:pending-language="pendingLanguage"
:closable="closable"
:avoid-bottom-nav="avoidBottomNav"
:mode="currentDisplayMode"
@@ -19,7 +18,6 @@
@close="player.close"
@seek="player.seekToPercent"
@expand="handleExpand"
@language-change="handleLanguageChange"
@update:visible="handleVisibleChange"
/>
</template>
@@ -28,8 +26,7 @@
import { computed, onMounted, onUnmounted, watch } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import AudioPlayer, {
type AudioDisplayMode,
type AudioLanguage
type AudioDisplayMode
} from '@/components/audio/AudioPlayer.vue'
import { useGlobalAudioPlayer } from '@/composables/useGlobalAudioPlayer'
@@ -54,7 +51,6 @@ const {
currentTime,
duration,
displayMode: currentDisplayMode,
pendingLanguage,
hasAudio
} = player
const hostId = player.registerHost()
@@ -96,10 +92,6 @@ const handleCollapse = () => {
player.collapse(props.displayMode === 'floating' ? 'floating' : 'mini')
}
const handleLanguageChange = (language: AudioLanguage) => {
void player.switchLanguage(language)
}
const handleVisibleChange = (visible: boolean) => {
if (!visible && hasAudio.value) {
player.collapse(props.displayMode === 'floating' ? 'floating' : 'mini')

View File

@@ -107,24 +107,6 @@
<view class="detail-audio-progress-fill"></view>
</view>
</view>
<view
v-if="isAudioLanguageSwitchVisible"
class="detail-audio-language-switch"
@tap.stop
>
<view
v-for="option in detailAudioLanguageOptions"
:key="option.value"
class="detail-audio-language-option"
:class="{ active: selectedAudioLanguage === option.value }"
@tap.stop="handleDetailAudioLanguageChange(option.value)"
>
<text class="detail-audio-lang-text">{{ option.shortLabel }}</text>
</view>
</view>
<view v-else class="detail-audio-lang">
<text class="detail-audio-lang-text">{{ audioLanguageShortText }}</text>
</view>
</view>
<view v-if="isLocationActionVisible" class="action-bar">
@@ -230,14 +212,6 @@ const contentLanguageOptions: Array<{
}
]
const audioLanguageOptions: Array<{
value: AudioLanguage
shortLabel: string
}> = [
{ value: 'zh-CN', shortLabel: '中文' },
{ value: 'en-US', shortLabel: 'EN' }
]
const isAudioLanguage = (value: unknown): value is AudioLanguage => (
value === 'zh-CN' || value === 'en-US'
)
@@ -284,21 +258,6 @@ const audioDockSubtitle = computed(() => [
exhibit.value.title,
exhibit.value.audio.durationLabel
].filter(Boolean).join(' · ') || '讲解音频')
const audioLanguageShortText = computed(() => (
selectedAudioLanguage.value === 'en-US' ? 'EN' : '中文'
))
const supportedDetailAudioLanguages = computed<AudioLanguage[]>(() => {
const languages = exhibit.value.audio.supportedLanguages?.length
? exhibit.value.audio.supportedLanguages
: [selectedAudioLanguage.value]
const normalized = Array.from(new Set(languages.filter(isAudioLanguage)))
return normalized.length ? normalized : [selectedAudioLanguage.value]
})
const detailAudioLanguageOptions = computed(() => (
audioLanguageOptions.filter((option) => supportedDetailAudioLanguages.value.includes(option.value))
))
const isAudioLanguageSwitchVisible = computed(() => detailAudioLanguageOptions.value.length > 1)
const isCurrentDetailAudioTarget = computed(() => {
const source = globalAudioPlayer.currentSource.value
const targetType = exhibit.value.audio.playTargetType || 'ITEM'
@@ -501,11 +460,6 @@ const handleLanguageChange = async (lang: AudioLanguage, options: { syncAudio?:
}
}
const handleDetailAudioLanguageChange = (lang: AudioLanguage) => {
if (!supportedDetailAudioLanguages.value.includes(lang)) return
void handleLanguageChange(lang)
}
watch(
() => globalAudioPlayer.currentSource.value,
(source) => {
@@ -1430,44 +1384,6 @@ const handleBack = () => {
border: 1px solid rgba(255, 255, 255, 0.46);
}
.detail-audio-language-switch {
flex-shrink: 0;
min-width: 74px;
height: 36px;
padding: 3px;
display: flex;
align-items: center;
gap: 3px;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 0.34);
border-radius: 13px;
background: rgba(255, 255, 255, 0.1);
}
.detail-audio-language-option {
min-width: 31px;
height: 28px;
padding: 0 6px;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
border-radius: 10px;
color: rgba(255, 255, 255, 0.7);
}
.detail-audio-language-option.active {
background: #e7e900;
color: #0b0f0a;
}
.detail-audio-lang-text {
font-size: 13px;
line-height: 18px;
font-weight: 900;
color: currentColor;
}
@media (max-width: 360px) {
.immersive-hero {
padding-left: 20px;
@@ -1489,13 +1405,5 @@ const handleBack = () => {
padding-left: 12px;
}
.detail-audio-language-switch {
min-width: 68px;
}
.detail-audio-language-option {
min-width: 28px;
padding: 0 5px;
}
}
</style>