|
@@ -1,25 +1,28 @@
|
|
|
-import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
|
|
+import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
|
|
|
import styles from "./index.module.less";
|
|
|
+import store from 'store'
|
|
|
|
|
|
import Title from "./title";
|
|
|
import icons from "./image/headerTop.json";
|
|
|
import { Badge, Circle, Popover, Popup } from "vant";
|
|
|
import { metronomeData } from "../../helpers/metronome";
|
|
|
import Speed from "./speed";
|
|
|
-import { handleEndBegin, handleStartEvaluat } from "/src/view/evaluating";
|
|
|
+import { evaluatingData, handleEndBegin, handleStartEvaluat } from "/src/view/evaluating";
|
|
|
import Settting from "./settting";
|
|
|
import ModeTypeMode from "./mode-type-mode";
|
|
|
import state, { handleChangeSection, handleResetPlay, handleRessetState, togglePlay } from "/src/state";
|
|
|
import { getAudioCurrentTime } from "/src/view/audio-list";
|
|
|
-import { toggleFollow } from "/src/view/follow-practice";
|
|
|
+import { followData, toggleFollow } from "/src/view/follow-practice";
|
|
|
import { api_back, api_suspendPlay } from "/src/helpers/communication";
|
|
|
import MusicType from "./music-type";
|
|
|
import { handleNoEndExit } from "../custom-plugins/recording-time";
|
|
|
+import { handle_stopFollow } from "../follow-model";
|
|
|
|
|
|
export const headData = reactive({
|
|
|
speedShow: false,
|
|
|
musicTypeShow: false,
|
|
|
modeMode: true, // 模式弹框
|
|
|
+ settingMode: false, // 设置弹框
|
|
|
});
|
|
|
|
|
|
/** 关闭模式选择 */
|
|
@@ -30,43 +33,147 @@ export const handleCloseModeMode = (type = false) => {
|
|
|
export default defineComponent({
|
|
|
name: "header-top",
|
|
|
setup() {
|
|
|
- const headerData = reactive({
|
|
|
- settingMode: false,
|
|
|
- });
|
|
|
- const headRef = ref();
|
|
|
-
|
|
|
- const toggleEvaluat = () => {
|
|
|
- handleStartEvaluat();
|
|
|
- };
|
|
|
|
|
|
/** 切换模式 */
|
|
|
const handleChangeModeType = (value: "practise" | "follow" | "evaluating") => {
|
|
|
if (value === "evaluating") {
|
|
|
- toggleEvaluat();
|
|
|
+ handleStartEvaluat();
|
|
|
} else if (value === "follow") {
|
|
|
toggleFollow();
|
|
|
}
|
|
|
headData.modeMode = false;
|
|
|
};
|
|
|
- const disabledList = ["evaluating"];
|
|
|
|
|
|
- /** 按钮禁用 */
|
|
|
+ /** 设置按钮 */
|
|
|
+ const settingBtn = computed(() => {
|
|
|
+ // 音频播放中 禁用
|
|
|
+ if (state.playState === "play") return { display: true, disabled: true };
|
|
|
+ // 评测开始 禁用, 跟练开始 禁用
|
|
|
+ if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true };
|
|
|
|
|
|
- /** 重播按钮显示条件 */
|
|
|
- const resetBtnDisplay = computed(() => {
|
|
|
- const currentTime = getAudioCurrentTime();
|
|
|
- const playState = state.playState;
|
|
|
- const modeType = state.modeType;
|
|
|
- return currentTime !== 0 && playState !== "play" && modeType === "practise";
|
|
|
+ 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 (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 音频播放中 禁用
|
|
|
+ if (state.playState === "play") return { display: true, disabled: true };
|
|
|
+ // 评测模式 禁用
|
|
|
+ if (state.modeType === "evaluating") return { display: true, disabled: true };
|
|
|
+ // 跟练模式 不显示
|
|
|
+ if (state.modeType === "follow") return { display: false, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ disabled: false,
|
|
|
+ display: true,
|
|
|
+ };
|
|
|
});
|
|
|
- /** 播放按钮显示条件 */
|
|
|
- const playBtnDisplay = computed(() => {
|
|
|
- const modeType = state.modeType;
|
|
|
- return modeType === "practise";
|
|
|
+
|
|
|
+ /** 指法按钮 */
|
|
|
+ const fingeringBtn = computed(() => {
|
|
|
+ // 没有指法 不显示
|
|
|
+ if (!state.fingeringInfo.name) return { display: false, disabled: true };
|
|
|
+ // 选择模式 不显示
|
|
|
+ if (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 音频播放中 禁用
|
|
|
+ if (state.playState === "play") return { display: true, disabled: true };
|
|
|
+ // 评测模式 不显示,跟练模式 不显示
|
|
|
+ if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ disabled: false,
|
|
|
+ display: true,
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 选段按钮 */
|
|
|
+ const selectBtn = computed(() => {
|
|
|
+ // 选择模式 不显示
|
|
|
+ if (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 音频播放中 禁用
|
|
|
+ if (state.playState === "play") return { display: true, disabled: true };
|
|
|
+ // 评测模式 不显示,跟练模式 不显示
|
|
|
+ if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ disabled: false,
|
|
|
+ display: true,
|
|
|
+ };
|
|
|
});
|
|
|
- /** 指法显示条件 */
|
|
|
- const fingeringDisplay = computed(() => {
|
|
|
- return state.fingeringInfo.name;
|
|
|
+
|
|
|
+ /** 原声按钮 */
|
|
|
+ const originBtn = computed(() => {
|
|
|
+ // 选择模式 不显示
|
|
|
+ if (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 跟练模式 不显示
|
|
|
+ if (state.modeType === "follow") return { display: false, disabled: true };
|
|
|
+ // 评测开始 禁用
|
|
|
+ if (state.modeType === "evaluating") return { display: true, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ disabled: false,
|
|
|
+ display: true,
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 模式切换按钮 */
|
|
|
+ const toggleBtn = computed(() => {
|
|
|
+ // 选择模式 不显示
|
|
|
+ if (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 跟练开始 禁用
|
|
|
+ if (followData.start) return { display: true, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ display: true,
|
|
|
+ disabled: false,
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 播放按钮 */
|
|
|
+ const playBtn = computed(() => {
|
|
|
+ // 选择模式 不显示
|
|
|
+ if (headData.modeMode) 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 (headData.modeMode) return { display: false, disabled: false };
|
|
|
+ // 评测模式 不显示,跟练模式 不显示
|
|
|
+ if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
|
|
|
+ // 播放进度为0 不显示, 不是暂停状态不显示
|
|
|
+ const currentTime = getAudioCurrentTime();
|
|
|
+ if (currentTime === 0 || state.playState !== "paused") return { display: false, disabled: true };
|
|
|
+
|
|
|
+ return {
|
|
|
+ display: true,
|
|
|
+ disabled: false,
|
|
|
+ };
|
|
|
});
|
|
|
|
|
|
/** 返回 */
|
|
@@ -77,25 +184,34 @@ export default defineComponent({
|
|
|
|
|
|
onMounted(() => {
|
|
|
api_suspendPlay(() => {
|
|
|
- if (state.modeType === 'practise') {
|
|
|
- togglePlay('paused')
|
|
|
- } else if (state.modeType === 'evaluating'){
|
|
|
- handleEndBegin()
|
|
|
+ if (state.modeType === "practise") {
|
|
|
+ togglePlay("paused");
|
|
|
+ } else if (state.modeType === "evaluating") {
|
|
|
+ handleEndBegin();
|
|
|
+ } else if (state.modeType === "follow") {
|
|
|
+ handle_stopFollow();
|
|
|
}
|
|
|
- })
|
|
|
- })
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 设置改变触发
|
|
|
+ watch(state.setting, () => {
|
|
|
+ store.set("musicscoresetting", state.setting);
|
|
|
+ });
|
|
|
|
|
|
return () => (
|
|
|
- <div ref={headRef} class={styles.headerTop}>
|
|
|
+ <div class={styles.headerTop}>
|
|
|
<div class={styles.back} onClick={handleBack}>
|
|
|
<img src={icons["icon-back"]} />
|
|
|
</div>
|
|
|
<Title text={state.examSongName} rightView={false} />
|
|
|
|
|
|
- <div class={styles.headRight} style={{ display: headData.modeMode ? "none" : "" }}>
|
|
|
+ <div class={styles.headRight}>
|
|
|
+ {/* 模式切换按钮 */}
|
|
|
<div
|
|
|
id="tips-step-0"
|
|
|
- class={styles.btn}
|
|
|
+ style={{ display: toggleBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, toggleBtn.value.disabled && styles.disabled]}
|
|
|
onClick={() => {
|
|
|
handleRessetState();
|
|
|
headData.modeMode = true;
|
|
@@ -105,9 +221,11 @@ export default defineComponent({
|
|
|
<span>模式</span>
|
|
|
</div>
|
|
|
|
|
|
+ {/* 原声按钮 */}
|
|
|
<div
|
|
|
id="tips-step-1"
|
|
|
- class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: originBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, originBtn.value.disabled && styles.disabled]}
|
|
|
onClick={() => {
|
|
|
state.playSource = state.playSource === "music" ? "background" : "music";
|
|
|
}}
|
|
@@ -115,14 +233,23 @@ export default defineComponent({
|
|
|
<img class={styles.iconBtn} src={state.playSource === "music" ? icons.music : icons.accompaniment} />
|
|
|
<span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
|
|
|
</div>
|
|
|
- <div id="tips-step-2" class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} onClick={() => handleChangeSection()}>
|
|
|
+
|
|
|
+ {/* 选段按钮 */}
|
|
|
+ <div
|
|
|
+ id="tips-step-2"
|
|
|
+ style={{ display: selectBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, selectBtn.value.disabled && styles.disabled]}
|
|
|
+ onClick={() => handleChangeSection()}
|
|
|
+ >
|
|
|
<img class={styles.iconBtn} src={state.section.length === 0 ? icons.section : state.section.length === 1 ? icons.section1 : icons.section2} />
|
|
|
<span>选段</span>
|
|
|
</div>
|
|
|
+
|
|
|
+ {/* 指法按钮 */}
|
|
|
<div
|
|
|
id="tips-step-3"
|
|
|
- style={{ display: fingeringDisplay.value ? "" : "none" }}
|
|
|
- class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: fingeringBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, fingeringBtn.value.disabled && styles.disabled]}
|
|
|
onClick={() => {
|
|
|
state.setting.displayFingering = !state.setting.displayFingering;
|
|
|
}}
|
|
@@ -152,12 +279,14 @@ export default defineComponent({
|
|
|
<span style={{ whiteSpace: "nowrap" }}>节拍器</span>
|
|
|
</div> */}
|
|
|
|
|
|
+ {/* 速度按钮 */}
|
|
|
<Popover trigger="manual" v-model:show={headData.speedShow} placement="bottom" overlay={false}>
|
|
|
{{
|
|
|
reference: () => (
|
|
|
<div
|
|
|
id="tips-step-4"
|
|
|
- class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: speedBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, speedBtn.value.disabled && styles.disabled]}
|
|
|
onClick={(e: Event) => {
|
|
|
e.stopPropagation();
|
|
|
headData.speedShow = !headData.speedShow;
|
|
@@ -172,11 +301,14 @@ export default defineComponent({
|
|
|
default: () => <Speed />,
|
|
|
}}
|
|
|
</Popover>
|
|
|
+
|
|
|
+ {/* 转简谱按钮 */}
|
|
|
<Popover trigger="manual" v-model:show={headData.musicTypeShow} placement="bottom-end" overlay={false}>
|
|
|
{{
|
|
|
reference: () => (
|
|
|
<div
|
|
|
- class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: converBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, converBtn.value.disabled && styles.disabled]}
|
|
|
onClick={(e: Event) => {
|
|
|
e.stopPropagation();
|
|
|
headData.musicTypeShow = !headData.musicTypeShow;
|
|
@@ -190,14 +322,20 @@ export default defineComponent({
|
|
|
}}
|
|
|
</Popover>
|
|
|
|
|
|
- <div class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} onClick={() => (headerData.settingMode = true)}>
|
|
|
+ {/* 设置按钮 */}
|
|
|
+ <div
|
|
|
+ style={{ display: settingBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, settingBtn.value.disabled && styles.disabled]}
|
|
|
+ onClick={() => (headData.settingMode = true)}
|
|
|
+ >
|
|
|
<img class={styles.iconBtn} src={icons.setting} />
|
|
|
<span>设置</span>
|
|
|
</div>
|
|
|
|
|
|
+ {/* 播放按钮 */}
|
|
|
<div
|
|
|
- style={{ display: playBtnDisplay.value ? "" : "none" }}
|
|
|
- class={[styles.btn, styles.playBtn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: playBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, styles.playBtn, playBtn.value.disabled && styles.disabled]}
|
|
|
id="tips-step-5"
|
|
|
onClick={() => togglePlay()}
|
|
|
>
|
|
@@ -213,9 +351,11 @@ export default defineComponent({
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ {/* 重播按钮 */}
|
|
|
<div
|
|
|
- style={{ display: resetBtnDisplay.value ? "" : "none" }}
|
|
|
- class={[styles.btn, styles.resetBtn, disabledList.includes(state.modeType) && styles.disable]}
|
|
|
+ style={{ display: resetBtn.value.display ? "" : "none" }}
|
|
|
+ class={[styles.btn, styles.resetBtn, resetBtn.value.disabled && styles.disabled]}
|
|
|
id="tips-step-7"
|
|
|
onClick={() => handleResetPlay()}
|
|
|
>
|
|
@@ -223,10 +363,10 @@ export default defineComponent({
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <Popup v-model:show={headerData.settingMode} class="popup-custom van-scale" transition="van-scale" teleport="body">
|
|
|
- <Settting onClose={() => (headerData.settingMode = false)} />
|
|
|
+ <Popup v-model:show={headData.settingMode} class="popup-custom van-scale" transition="van-scale" teleport="body">
|
|
|
+ <Settting onClose={() => (headData.settingMode = false)} />
|
|
|
</Popup>
|
|
|
- <Popup v-model:show={headData.modeMode} teleport="body" class="popup-custom" position="bottom" closeOnClickOverlay={false} overlay={false}>
|
|
|
+ <Popup v-model:show={headData.modeMode} teleport="body" class="popup-custom" position="bottom" closeOnClickOverlay={false} overlay={false}>
|
|
|
<ModeTypeMode onClose={(value) => handleChangeModeType(value)} />
|
|
|
</Popup>
|
|
|
</div>
|