Browse Source

Merge branch 'iteration-20240801' into jenkins

lex 10 months ago
parent
commit
6574e65614

+ 17 - 3
src/views/content-information/content-instrument/detail.module.less

@@ -389,7 +389,9 @@
     }
 
     .musicTitleRight {
-      .textRead, .textClose {
+
+      .textRead,
+      .textClose {
         padding: 7px 8px;
         background: #E8F4FF;
         border-radius: 13px;
@@ -415,6 +417,7 @@
           background-size: contain;
         }
       }
+
       .textClose {
         .icon {
           background: url('../images/icon-speak-close.png');
@@ -432,6 +435,10 @@
     user-select: text;
     position: relative;
 
+    &::selection {
+      background-color: #dfdfdf;
+    }
+
     &>img {
       width: 100%;
     }
@@ -517,11 +524,14 @@
   display: flex;
   align-items: center;
   position: absolute;
+
   &.hide {
     opacity: 0;
     visibility: hidden;
   }
-  .textStart, .textReadOnly {
+
+  .textStart,
+  .textReadOnly {
     cursor: pointer;
     background: #1A8CFF;
     border-radius: 13px;
@@ -532,6 +542,8 @@
     display: inline-flex;
     align-items: center;
     padding: 3px 8px;
+    flex-shrink: 0;
+
     .icon {
       margin-left: 4px;
       display: inline-block;
@@ -546,8 +558,10 @@
       background-size: contain;
     }
   }
+
   .textReadOnly {
     margin-left: 10px;
+
     .icon {
 
       width: 9px;
@@ -556,4 +570,4 @@
       background-size: contain;
     }
   }
-}
+}

+ 27 - 4
src/views/content-information/content-instrument/detail.tsx

@@ -12,7 +12,8 @@ import {
   defineComponent,
   onMounted,
   onUnmounted,
-  reactive
+  reactive,
+  watch
 } from 'vue';
 import styles from './detail.module.less';
 import icon_back from '../../xiaoku-music/images/icon_back.png';
@@ -61,6 +62,15 @@ export default defineComponent({
       fontSize: 18 // 默认18
     });
 
+    watch(
+      () => data.playState,
+      () => {
+        if (data.playState === 'play') {
+          speak.onCloseSpeak();
+        }
+      }
+    );
+
     /** 选中的item */
     const activeItem = computed(() => {
       return data.list[data.listActive] || {};
@@ -297,7 +307,12 @@ export default defineComponent({
                         <i class={styles.icon}></i>关闭朗读
                       </span>
                     ) : (
-                      <span class={styles.textRead} onClick={speak.onAllSpeak}>
+                      <span
+                        class={styles.textRead}
+                        onClick={() => {
+                          speak.onAllSpeak();
+                          handleChangeAudio('pause');
+                        }}>
                         <i class={styles.icon}></i>全文朗读
                       </span>
                     )}
@@ -314,12 +329,20 @@ export default defineComponent({
                       styles.selectionCouser,
                       !speak.showDom.value && styles.hide
                     ]}>
-                    <span class={styles.textStart} onClick={speak.onTextStart}>
+                    <span
+                      class={styles.textStart}
+                      onClick={() => {
+                        speak.onTextStart();
+                        handleChangeAudio('pause');
+                      }}>
                       开始朗读<i class={styles.icon}></i>
                     </span>
                     <span
                       class={styles.textReadOnly}
-                      onClick={speak.onTextReadOnly}>
+                      onClick={() => {
+                        speak.onTextReadOnly();
+                        handleChangeAudio('pause');
+                      }}>
                       只读这段<i class={styles.icon}></i>
                     </span>
                   </div>

+ 4 - 2
src/views/content-information/content-knowledge/index.module.less

@@ -269,7 +269,7 @@
     // padding: 27px;
     padding-right: 27px;
     user-select: text;
-      position: relative;
+    position: relative;
 
     &>img {
       width: 100%;
@@ -287,6 +287,7 @@
     top: 15px;
     right: 15px;
     z-index: 9;
+
     .textRead,
     .textClose {
       padding: 7px 8px;
@@ -390,6 +391,7 @@
     display: inline-flex;
     align-items: center;
     padding: 3px 8px;
+    flex-shrink: 0;
 
     .icon {
       margin-left: 4px;
@@ -417,4 +419,4 @@
       background-size: contain;
     }
   }
-}
+}

+ 3 - 1
src/views/content-information/content-music/detail.module.less

@@ -375,6 +375,7 @@
     }
 
     .musicTitleRight {
+
       .textRead,
       .textClose {
         padding: 7px 8px;
@@ -641,6 +642,7 @@
     display: inline-flex;
     align-items: center;
     padding: 3px 8px;
+    flex-shrink: 0;
 
     .icon {
       margin-left: 4px;
@@ -668,4 +670,4 @@
       background-size: contain;
     }
   }
-}
+}

+ 64 - 31
src/views/content-information/useSpeak.ts

@@ -156,30 +156,39 @@ export const useSpeak = () => {
         const showDomRect = showDom.getBoundingClientRect();
 
         // 判断 上边超出边界
-        if (y - parentRect?.top > showDomRect.height + fHeight / 2) {
-          showDom.style.top =
-            (
-              y -
-              parentRect?.top -
-              (showDomRect.height + fHeight / 2) +
-              musicContent?.scrollTop
-            ).toFixed(2) + 'px';
-        } else {
-          console.log(
-            false,
-            parentRect?.bottom -
-            bottom +
+        // if (y - parentRect?.top > showDomRect.height + fHeight / 2) {
+        //   showDom.style.top =
+        //     (
+        //       y -
+        //       parentRect?.top -
+        //       (showDomRect.height + fHeight / 2) +
+        //       musicContent?.scrollTop
+        //     ).toFixed(2) + 'px';
+        // } else {
+        // console.log(
+        //   false,
+        //   parentRect?.bottom -
+        //   bottom +
+        //   (showDomRect.height + fHeight / 2) +
+        //   musicContent?.scrollTop
+        // );
+        showDom.style.top =
+          (
+            y -
+            parentRect?.top +
             (showDomRect.height + fHeight / 2) +
             musicContent?.scrollTop
-          );
-          showDom.style.top =
-            (
-              y -
-              parentRect?.top +
-              (showDomRect.height + fHeight / 2) +
-              musicContent?.scrollTop
-            ).toFixed(2) + 'px';
-        }
+          ).toFixed(2) + 'px';
+        // }
+        // console.log({
+        //   parentRectWidth: parentRect?.width,
+        //   firstRectLeft: x,
+        //   parentRectLeft: parentRect?.left,
+        //   parentRectStatus:
+        //     parentRect?.width - (x - parentRect?.left) > showDomRect.width,
+        //   diff: parentRect?.width - (x - parentRect?.left),
+        //   showDomRect: showDomRect.width
+        // });
         if (parentRect?.width - (x - parentRect?.left) > showDomRect.width) {
           // 判断是否选择到最右边 超出边界
           showDom.style.left = (x - parentRect?.left).toFixed(2) + 'px';
@@ -257,8 +266,11 @@ export const useSpeak = () => {
     const textContainer: any = document.querySelector('#musicContent');
     const sentences: any = textContainer?.querySelectorAll('label.speak-label');
 
+    // console.log(options, '--endIndex');
     let currentSentenceIndex = options.startIndex || 0;
-    const end = options.endIndex || sentences.length - 1;
+    const end =
+      options.endIndex === undefined ? sentences.length - 1 : options.endIndex;
+
     // 高亮显示
     const highlightSentence = (index: number) => {
       sentences.forEach((sentence: any, i: number) => {
@@ -277,6 +289,12 @@ export const useSpeak = () => {
     const speaker = () => {
       try {
         state.synth = window.speechSynthesis;
+
+        // 获取可用的 voice 列表
+        // const voices = speechSynthesis.getVoices();
+        // 选择一个特定的 voice
+        // const voice = voices.find(voice => voice.lang === 'zh-CN');
+        // console.log(voice, 'voice');
         // 如果当前正在播放,先暂停
         if (state.synth.speaking) {
           state.synth.cancel(); // 取消当前播放
@@ -288,29 +306,42 @@ export const useSpeak = () => {
           return;
         }
         // 判断是否为选中的内容播放
-        if (options.startIndex === options.endIndex) {
+        if (
+          options.startIndex === options.endIndex &&
+          options.endIndex !== undefined
+        ) {
           sentence = sentence.substr(
             options.anchorOffset,
             (options.focusOffset || 0) - (options.anchorOffset || 0)
           );
         } else {
           if (options.startIndex === currentSentenceIndex) {
-            sentence = sentence.substr(
-              options.anchorOffset,
-              sentence.length - 1
-            );
+            sentence = sentence.substr(options.anchorOffset, sentence.length);
           }
           if (options.endIndex === currentSentenceIndex) {
             sentence = sentence.substr(0, options.focusOffset);
           }
         }
 
-        const utterance = new SpeechSynthesisUtterance();
+        const replaceText = ['长笛', '曲'];
+        const afterReplaceText = ['尝笛', '取'];
+
+        if (sentence) {
+          replaceText.forEach((item: string, index: number) => {
+            if (sentence.includes(item)) {
+              const regex = new RegExp(item, 'g');
+              sentence = sentence.replace(regex, afterReplaceText[index]);
+            }
+          });
+        }
+
+        console.log(sentence, currentSentenceIndex, end, '---------');
+        const utterance = new SpeechSynthesisUtterance(sentence);
         utterance.lang = 'zh-CN';
         utterance.volume = 1;
         utterance.rate = 0.8; // 语速 0.1到10
         utterance.pitch = 1.5; // 范围从0(最小)到2(最大)
-        utterance.text = sentence;
+        // utterance.text = sentence;
 
         if (utterance) {
           utterance.onstart = null;
@@ -345,7 +376,7 @@ export const useSpeak = () => {
         };
         setTimeout(() => {
           state.synth.speak(utterance);
-        }, 100);
+        }, 80);
       } catch (e) {
         console.log(e, 'e');
       }
@@ -387,10 +418,12 @@ export const useSpeak = () => {
 
   onMounted(async () => {
     document.addEventListener('mouseup', getSelectText);
+    document.addEventListener('touchend', getSelectText);
   });
 
   onUnmounted(() => {
     document.removeEventListener('mouseup', getSelectText);
+    document.addEventListener('touchend', getSelectText);
     onCloseSpeak();
   });