import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref } from "vue"; import styles from "./index.module.less"; import iconBack from "./image/icon-back.svg"; import Title from "./title"; import { headImg } from "./image"; import { Badge, Circle, Popover, Popup, showConfirmDialog } from "vant"; import Speed from "./speed"; import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating"; import Settting from "./settting"; import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay } from "/src/state"; import { getAudioCurrentTime } from "/src/view/audio-list"; import { followData, toggleFollow } from "/src/view/follow-practice"; import { api_back } from "/src/helpers/communication"; import MusicType from "./music-type"; import ModeTypeMode from "../component/mode-type-mode"; import { getQuery } from "/src/utils/queryString"; /** 头部数据和方法 */ export const headTopData = reactive({ /** 模式 */ modeType: "" as "init" | "show", /** 显示返回按钮 */ showBack: true, /** 设置弹窗 */ settingMode: false, /** 切换模式 */ handleChangeModeType(value: "practise" | "follow" | "evaluating") { if (value === "evaluating") { console.log(state.platform) if (state.platform === IPlatform.PC){ showConfirmDialog({ title: '温馨提示', message: '该功能暂未开发,敬请期待', showCancelButton: false, }) return } handleStartEvaluat(); } else if (value === "follow") { toggleFollow(); } headTopData.modeType = "show"; }, }); export const headData = reactive({ speedShow: false, musicTypeShow: false, }); export default defineComponent({ name: "header-top", setup() { /** 设置按钮 */ const settingBtn = computed(() => { // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; // 评测开始 禁用, 跟练开始 禁用 if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true }; return { display: true, disabled: false, }; }); /** 转谱按钮 */ const converBtn = computed(() => { // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; // 评测开始 禁用 if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 速度按钮 */ const speedBtn = computed(() => { // 选择模式, 跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: true }; // 评测模式, 音频播放中 禁用 if (state.modeType === "evaluating" || state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 指法按钮 */ const fingeringBtn = computed(() => { // 没有指法 选择模式 评测模式 跟练模式 不显示 if ( headTopData.modeType !== "show" || !state.fingeringInfo.name || ["evaluating", "follow"].includes(state.modeType) ) return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 摄像头按钮 */ const cameraBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show" || state.modeType !== "evaluating") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 选段按钮 */ const selectBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show" || ["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 原声按钮 */ const originBtn = computed(() => { // 选择模式,跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false }; // 评测开始 禁用 if (state.modeType === "evaluating") return { display: false, disabled: true }; // 原声, 伴奏 少一个,就不能切换 if (!state.music || !state.accompany) return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 模式切换按钮 */ const toggleBtn = computed(() => { // 选择模式, url设置模式 不显示 if (headTopData.modeType !== "show" || !headTopData.showBack) return { display: false, disabled: false }; // 跟练开始, 评测开始 禁用 if (followData.start || evaluatingData.startBegin) return { display: true, disabled: true }; return { display: true, disabled: false, }; }); /** 播放按钮 */ const playBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: false }; // 评测模式 不显示,跟练模式 不显示 if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; return { display: true, disabled: false, }; }); /** 重播按钮 */ const resetBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: false }; // 评测模式 不显示,跟练模式 不显示 if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; // 播放状态 不显示 if (state.playState === "play") return { display: false, disabled: true }; // 播放进度为0 不显示 const currentTime = getAudioCurrentTime(); if (!currentTime) return { display: false, disabled: true }; return { display: true, disabled: false, }; }); /** 返回 */ const handleBack = () => { api_back(); }; /** 根据参数设置模式 */ const getQueryModelSetModelType = () => { const query: any = getQuery(); if (query.modelType) { if (query.modelType === "practise") { headTopData.handleChangeModeType("practise"); } else if (query.modelType === "evaluating") { headTopData.handleChangeModeType("evaluating"); } headTopData.showBack = false; } else { setTimeout(() => { headTopData.modeType = "init"; }, 500); } }; /** 课件播放 */ const changePlay = (res: any) => { if (res?.data?.api === "setPlayState") { togglePlay("paused"); } }; onMounted(() => { getQueryModelSetModelType(); window.addEventListener("message", changePlay); }); onUnmounted(() => { window.removeEventListener("message", changePlay); }); return () => ( <>
{headTopData.showBack && (
)} <div class={styles.headRight} > <div style={{ display: toggleBtn.value.display ? "" : "none" }} class={[styles.btn, toggleBtn.value.disabled && styles.disabled]} onClick={() => { handleRessetState(); headTopData.modeType = "init"; }} > <img class={styles.iconBtn} src={headImg(`modeType.svg`)} /> <span>模式</span> </div> <div style={{ display: originBtn.value.display ? "" : "none" }} class={[styles.btn, originBtn.value.disabled && styles.disabled]} id="tips-step-6" onClick={() => { state.playSource = state.playSource === "music" ? "background" : "music"; }} > <img style={{ display: state.playSource === "music" ? "" : "none" }} class={styles.iconBtn} src={headImg(`music.svg`)} /> <img style={{ display: state.playSource === "music" ? "none" : "" }} class={styles.iconBtn} src={headImg(`background.svg`)} /> <span>{state.playSource === "music" ? "原声" : "伴奏"}</span> </div> <div style={{ display: selectBtn.value.display ? "" : "none" }} class={[styles.btn, selectBtn.value.disabled && styles.disabled]} id="tips-step-4" onClick={() => handleChangeSection()} > <img style={{ display: state.section.length === 0 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section0.svg`)} /> <img style={{ display: state.section.length === 1 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section1.svg`)} /> <img style={{ display: state.section.length === 2 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section2.svg`)} /> <span>选段</span> </div> <div style={{ display: fingeringBtn.value.display ? "" : "none" }} class={[styles.btn, fingeringBtn.value.disabled && styles.disabled]} onClick={() => { state.setting.displayFingering = !state.setting.displayFingering; }} > <img style={{ display: state.setting.displayFingering ? "" : "none" }} class={styles.iconBtn} src={headImg(`icon_evaluatingOn.svg`)} /> <img style={{ display: state.setting.displayFingering ? "none" : "" }} class={styles.iconBtn} src={headImg(`icon_evaluatingOff.svg`)} /> <span>指法</span> </div> <Popover trigger="manual" v-model:show={headData.speedShow} placement="bottom" overlay={false} > {{ reference: () => ( <div id="tips-step-8" style={{ display: speedBtn.value.display ? "" : "none" }} class={[styles.btn, speedBtn.value.disabled && styles.disabled]} onClick={(e: Event) => { e.stopPropagation(); headData.speedShow = !headData.speedShow; }} > <Badge class={styles.badge} content={state.speed}> <img class={styles.iconBtn} src={headImg("icon_speed.svg")} /> </Badge> <span>速度</span> </div> ), default: () => <Speed />, }} </Popover> <Popover trigger="manual" v-model:show={headData.musicTypeShow} placement="bottom-end" overlay={false} > {{ reference: () => ( <div style={{ display: converBtn.value.display ? "" : "none" }} class={[styles.btn, converBtn.value.disabled && styles.disabled]} onClick={(e: Event) => { e.stopPropagation(); headData.musicTypeShow = !headData.musicTypeShow; }} > <img class={styles.iconBtn} src={headImg("icon_zhuanpu.svg")} /> <span>{state.musicRenderType === "staff" ? "转简谱" : "转五线谱"}</span> </div> ), default: () => <MusicType />, }} </Popover> <div style={{ display: settingBtn.value.display ? "" : "none" }} class={[styles.btn, settingBtn.value.disabled && styles.disabled]} onClick={() => (headTopData.settingMode = true)} > <img class={styles.iconBtn} src={headImg("icon_menu.svg")} /> <span>设置</span> </div> </div> </div> {/* 播放按钮 */} <div style={{ display: playBtn.value.display ? "" : "none" }} class={[styles.btn, styles.playBtn, playBtn.value.disabled && styles.disabled]} id="tips-step-5" onClick={() => togglePlay()} > <div class={styles.btnWrap}> <img style={{ display: state.playState === "play" ? "none" : "" }} class={styles.iconBtn} src={headImg("icon_play.svg")} /> <img style={{ display: state.playState === "play" ? "" : "none" }} class={styles.iconBtn} src={headImg("icon_pause.svg")} /> <Circle style={{ opacity: state.playState === "play" ? 1 : 0 }} class={styles.progress} stroke-width={80} currentRate={state.playProgress} rate={100} color="#FFC830" /> </div> </div> {/* 重播按钮 */} <div style={{ display: resetBtn.value.display ? "" : "none" }} class={[styles.btn, styles.resetBtn, resetBtn.value.disabled && styles.disabled]} id="tips-step-7" onClick={() => handleResetPlay()} > <img class={styles.iconBtn} src={headImg("icon_resetbtn.svg")} /> </div> <Popup v-model:show={headTopData.settingMode} class="popup-custom van-scale center-closeBtn" transition="van-scale" teleport="body" closeable > <Settting /> </Popup> {/* 模式切换 */} <ModeTypeMode /> </> ); }, });