import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef, ComputedRef } from "vue"; import styles from "./index.module.less"; import iconBack from "./image/icon-back.png"; import listImg from "./image/list.png"; import iconMode from "./image/mode.png"; import { headImg } from "./image"; import { Badge, Circle, Popover, Popup, showConfirmDialog, showToast, NoticeBar } from "vant"; import Speed from "./speed"; import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating"; import Settting from "./settting"; import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay, IPlayState, refreshMusicSvg } 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"; import { storeData } from "/src/store"; import TeacherTop from "../custom-plugins/guide-page/teacher-top"; import StudentTop from "../custom-plugins/guide-page/student-top"; import { HANDLE_WORK_ADD } from "../custom-plugins/work-index"; import { browser } from "/src/utils"; import store from "store"; import "../component/the-modal-tip/index.module.less"; import { metronomeData } from "../../helpers/metronome"; import { toggleMusicSheet } from "/src/view/plugins/toggleMusicSheet"; import useDrag from "/src/view/plugins/useDrag/index"; import Dragbom from "/src/view/plugins/useDrag/dragbom"; import { getGuidance, setGuidance } from "../custom-plugins/guide-page/api"; import ModeView from "./modeView"; import { smoothAnimationState } from "../view-detail/smoothAnimation"; import { isMusicList, musicListShow } from "../component/the-music-list"; import { EvaluatingDriver, EvaluatingResultDriver, FollowDriver, PractiseDriver } from "../custom-plugins/guide-driver"; /** 头部数据和方法 */ export const headTopData = reactive({ /** 模式 */ modeType: "" as "init" | "show", /** 显示返回按钮 */ showBack: true, /** 设置弹窗 */ settingMode: false, /** 切换模式 */ handleChangeModeType(value: "practise" | "follow" | "evaluating") { // 后台设置为不能评测 if (value === "evaluating" && !state.enableEvaluation) return; // 打击乐&节奏练习不支持跟练模式 if (value === "follow" && state.isPercussion) return; // 跟练模式,光标只有音符模式,无节拍模式 if (value === "follow" && metronomeData.cursorMode === 2) { metronomeData.cursorMode = 1; } if (value === "practise") { // state.playIngSpeed = state.speed } if (value === "evaluating") { // 如果延迟检测资源还在加载中,给出提示 if (!evaluatingData.jsonLoadDone) { evaluatingData.jsonLoading = true; state.audioDone && showToast("资源加载中,请稍后"); //音频资源加载完之后才提示 return; } // 如果是pc端, 评测模式暂不可用 if (state.platform === IPlatform.PC) { showConfirmDialog({ className: "modalTip", title: "温馨提示", message: "该功能暂未开放,敬请期待!", showCancelButton: false, }); return; } // 评测模式,只有一行谱模式 if (!state.isSingleLine) { state.isSingleLine = true; refreshMusicSvg(); } smoothAnimationState.isShow.value = false; // 隐藏旋律线 state.playIngSpeed = state.originSpeed; handleStartEvaluat(); // 开发模式,把此处打开 // state.modeType = "evaluating" // evaluatingData.rendered = true; // evaluatingData.soundEffectMode = true; } else if (value === "follow") { // 跟练模式,只有一行谱模式 if (!state.isSingleLine) { state.isSingleLine = true; refreshMusicSvg(); } smoothAnimationState.isShow.value = false; toggleFollow(); } headTopData.modeType = "show"; }, }); export const headData = reactive({ speedShow: false, musicTypeShow: false, }); let resetBtn: ComputedRef<{ display: boolean; disabled: boolean; }>; /** * 处理模式切换 * @param oldPlayType 没改变之前的播放模式 * @param oldPlaySource 没改变之前的播放类型 * @param isforceReset 是否强制刷新播放状态 模式times时值改变时候也刷新 */ export function handlerModeChange(oldPlayType: "play" | "sing", oldPlaySource: IPlayState, isforceReset?: boolean) { const isModeChange = modeChangeHandleTimes(oldPlayType, oldPlaySource); // 没有切换的时候 不处理下面的 if (isModeChange) { try { metronomeData.metro.calculation(state.times); } catch (error) {} console.log("重新之后的times", state.times, state.fixtime); } if (isModeChange || isforceReset) { // 重置播放状态 handleRessetState(); // 隐藏重播按钮 resetBtn && (resetBtn.value.display = false); } } // 模式切换之后重新给times赋值 function modeChangeHandleTimes(oldPlayType: "play" | "sing", oldPlaySource: IPlayState) { const playType = state.playType; const playSource = state.playSource; const { notBeatFixtime, xmlMp3BeatFixTime, difftime } = state.times[0]; const { isOpenMetronome, isSingOpenMetronome } = state; // 演奏向演唱切 if (oldPlayType === "play" && playType === "sing") { if (playSource === "mingSong") { // 唱名文件也要加上弱起时间 他们制作曲子加了弱起时间 state.fixtime = difftime; state.times.map((item) => { item.time = item.xmlNoteTime + difftime; item.endtime = item.xmlNoteEndTime + difftime; item.fixtime = difftime; }); return true; } else { //演奏开了节拍器,演唱没开节拍器 if (isOpenMetronome && !isSingOpenMetronome) { state.fixtime = notBeatFixtime; state.times.map((item) => { item.time = item.notBeatTime; item.endtime = item.notBeatEndTime; item.fixtime = notBeatFixtime; }); return true; } else if (!isOpenMetronome && isSingOpenMetronome) { state.fixtime = notBeatFixtime + xmlMp3BeatFixTime; state.times.map((item) => { item.time = item.notBeatTime + xmlMp3BeatFixTime; item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime; item.fixtime = notBeatFixtime + xmlMp3BeatFixTime; }); return true; } } } else if (oldPlayType === "sing" && playType === "play") { // 演唱向演奏切 if (oldPlaySource === "mingSong") { // 有节拍器 if (isOpenMetronome) { state.fixtime = notBeatFixtime + xmlMp3BeatFixTime; state.times.map((item) => { item.time = item.notBeatTime + xmlMp3BeatFixTime; item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime; item.fixtime = notBeatFixtime + xmlMp3BeatFixTime; }); return true; } else { state.fixtime = notBeatFixtime; state.times.map((item) => { item.time = item.notBeatTime; item.endtime = item.notBeatEndTime; item.fixtime = notBeatFixtime; }); return true; } } // 演奏开了节拍器,演唱没开节拍器 if (isOpenMetronome && !isSingOpenMetronome) { state.fixtime = notBeatFixtime + xmlMp3BeatFixTime; state.times.map((item) => { item.time = item.notBeatTime + xmlMp3BeatFixTime; item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime; item.fixtime = notBeatFixtime + xmlMp3BeatFixTime; }); return true; } else if (!isOpenMetronome && isSingOpenMetronome) { state.fixtime = notBeatFixtime; state.times.map((item) => { item.time = item.notBeatTime; item.endtime = item.notBeatEndTime; item.fixtime = notBeatFixtime; }); return true; } } else if (oldPlayType === "sing" && playType === "sing") { // 演唱之间切换 // 切到唱名时候 if (playSource === "mingSong") { // 唱名文件也要加上弱起时间 他们制作曲子加了弱起时间 state.fixtime = difftime; state.times.map((item) => { item.time = item.xmlNoteTime + difftime; item.endtime = item.xmlNoteEndTime + difftime; item.fixtime = difftime; }); return true; } else if (oldPlaySource === "mingSong") { // 有节拍器 if (isSingOpenMetronome) { state.fixtime = notBeatFixtime + xmlMp3BeatFixTime; state.times.map((item) => { item.time = item.notBeatTime + xmlMp3BeatFixTime; item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime; item.fixtime = notBeatFixtime + xmlMp3BeatFixTime; }); return true; } else { state.fixtime = notBeatFixtime; state.times.map((item) => { item.time = item.notBeatTime; item.endtime = item.notBeatEndTime; item.fixtime = notBeatFixtime; }); return true; } } } return false; } export default defineComponent({ name: "header-top", emits: ["close"], setup(props, { emit }) { const query = getQuery(); // 是否显示引导 const showGuide = ref(false); const showStudentGuide = ref(false); /** 设置按钮 */ 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 metronomeBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 指法按钮 */ const fingeringBtn = computed(() => { // 后台设置不显示指法 if (!state.isShowFingering) return { display: true, disabled: true }; // 没有指法 选择模式 评测模式 跟练模式 不显示 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" || ["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.isAppPlay) { if (state.playType === "play") { // 原声, 伴奏 少一个,就不能切换 if (state.music && state.accompany) return { display: true, disabled: false }; } else { // 播放过程中不能切换 if (state.playState === "play") { return { display: true, disabled: true }; } // 范唱 let index = 0; state.fanSong && index++; state.banSong && index++; state.mingSong && index++; if (index > 1) { return { display: true, disabled: false }; } } } return { disabled: true, display: true, }; }); /** 播放类型按钮 */ const playTypeBtn = computed(() => { // 选择模式,跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false }; // 评测开始 禁用 if (state.modeType === "evaluating") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; if (!state.isAppPlay) { let index = 0; state.music && index++; state.accompany && index++; let songIndex = 0; state.fanSong && songIndex++; state.banSong && songIndex++; state.mingSong && songIndex++; // 演唱和演奏 都有数据的时间不禁用 if (songIndex > 0 && index > 0) { return { display: true, disabled: false }; } } return { disabled: true, display: true, }; }); /** 模式切换按钮 */ const toggleBtn = computed(() => { // 选择模式, url设置模式 不显示 if (headTopData.modeType !== "show" || !headTopData.showBack) return { display: false, disabled: false }; // 跟练开始, 评测开始 播放开始 隐藏 if (state.playState == "play" || followData.start || evaluatingData.startBegin) return { display: false, disabled: false }; 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 }; // midi音频未初始化完成不可点击 if (state.isAppPlay && state.midiPlayIniting) return { display: true, disabled: true }; return { display: true, disabled: false, }; }); /** 重播按钮 */ 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(); // midi音频未初始化完成不可点击 if (state.isAppPlay && state.midiPlayIniting) return { display: false, disabled: true }; if (!currentTime) return { display: false, disabled: true }; return { display: true, disabled: false, }; }); const isAllBtns = computed(() => { const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showGuide.value; return flag; }); const isAllBtnsStudent = computed(() => { const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showStudentGuide.value; return flag; }); const showGuideIndex = computed(() => { // 从课堂乐器学生端课件预览默认不显示会员 if (storeData.user.vipMember || state.paymentType === "FREE" || query.showCourseMember === "true") { // 学生端 return true; } else { // vip return false; } }); const browInfo = browser(); /** 返回 */ const handleBack = () => { HANDLE_WORK_ADD(); // 不在APP中, if (!storeData.isApp) { window.close(); return; } if ((browInfo.iPhone || browInfo.ios) && query.workRecord) { setTimeout(() => { api_back(); }, 550); return; } api_back(); }; /** 根据参数设置模式 */ const getQueryModelSetModelType = () => { /** 作业模式 start, 如果为作业模式不处理,让作业模块处理 */ if (query.workRecord) { return; } /** 作业模式 end */ if (state.defaultModeType == 1) { headTopData.handleChangeModeType("practise"); if (state.platform === IPlatform.PC || state.isPreView) { headTopData.showBack = false; } } else { 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) => { // console.log('监听上课页面message',res) if (res?.data?.api === "setPlayState") { togglePlay("paused", "courseware"); } // 上课页面,按钮方向 if (res?.data?.api === "imagePos") { if (res?.data.data) { state.playBtnDirection = res.data.data === "right" ? "right" : "left"; // if (state.fingeringInfo.direction === "vertical" && state.setting.displayFingering) { // state.musicScoreBtnDirection = state.playBtnDirection === 'right' ? 'left' : 'right'; // } else { // state.musicScoreBtnDirection = state.playBtnDirection; // } state.musicScoreBtnDirection = state.playBtnDirection; } } }; const parentClassName = "settingBoxClass_drag"; const userId = storeData.user?.id ? String(storeData.user?.id) : ""; const positionInfo = state.platform !== IPlatform.PC ? { styleDrag: { value: null }, } : useDrag([`${parentClassName} .top_drag`, `${parentClassName} .bom_drag`], parentClassName, toRef(headTopData, "settingMode"), userId); onMounted(() => { getQueryModelSetModelType(); window.addEventListener("message", changePlay); if (state.platform === IPlatform.PC) { showGuide.value = true; } else { showStudentGuide.value = true; } }); onUnmounted(() => { window.removeEventListener("message", changePlay); }); // 设置改变触发 watch(state.setting, () => { console.log(state.setting, "state.setting"); store.set("musicscoresetting", state.setting); }); // 获取引导页信息 const getAllGuidance = async () => { let guideInfo: any = null; try { const res = await getGuidance({ guideTag: "guideInfo" }); if (res.data) { guideInfo = JSON.parse(res.data?.guideValue) || null; } else { guideInfo = {}; } state.guideInfo = guideInfo; } catch (e) { console.log(e); } }; getAllGuidance(); // 完成拖动弹窗引导页 const handleGuide = async () => { state.guideInfo.teacherDrag = true; try { const res = await setGuidance({ guideTag: "guideInfo", guideValue: JSON.stringify(state.guideInfo) }); } catch (e) { console.log(e); } }; return () => ( <>