shuisheng преди 2 години
родител
ревизия
2630a23bc6
променени са 5 файла, в които са добавени 93 реда и са изтрити 9 реда
  1. 5 1
      src/components/Dropdown/index.vue
  2. 48 3
      src/hooks/use-srs-ws.ts
  3. 8 3
      src/interface-ws.ts
  4. 2 0
      src/store/app/index.ts
  5. 30 2
      src/views/pull/index.vue

+ 5 - 1
src/components/Dropdown/index.vue

@@ -4,7 +4,7 @@
     :class="{ hover: props.trigger === 'hover' }"
     @mouseenter="handleMouseEnter"
     @mouseleave="handleMouseLeave"
-    @click="handleClick"
+    @click="handleClickWrap"
   >
     <div class="btn">
       <slot name="btn"></slot>
@@ -15,6 +15,7 @@
       :style="{
         display: show ? 'block' : 'none',
       }"
+      @click.stop="handleClick"
     >
       <div class="wrap">
         <slot name="list"></slot>
@@ -40,6 +41,9 @@ const props = withDefaults(
 );
 
 function handleClick() {
+  show.value = false;
+}
+function handleClickWrap() {
   show.value = true;
 }
 function handleMouseEnter() {

+ 48 - 3
src/hooks/use-srs-ws.ts

@@ -33,7 +33,7 @@ import { WebSocketClass, prettierReceiveWsMsg } from '@/network/webSocket';
 import { useAppStore } from '@/store/app';
 import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
-import { createVideo } from '@/utils';
+import { createVideo, formatDownTime } from '@/utils';
 
 import { useRTCParams } from './use-rtcParams';
 
@@ -57,7 +57,7 @@ export const useSrsWs = () => {
   const currentMaxBitrate = ref(maxBitrate.value[3].value);
   const currentMaxFramerate = ref(maxFramerate.value[2].value);
   const currentResolutionRatio = ref(resolutionRatio.value[3].value);
-
+  const timerObj = ref({});
   const damuList = ref<IDanmu[]>([]);
 
   onUnmounted(() => {
@@ -351,12 +351,57 @@ export const useSrsWs = () => {
       WsMsgTypeEnum.disableSpeaking,
       (data: WsDisableSpeakingType['data']) => {
         prettierReceiveWsMsg(WsMsgTypeEnum.disableSpeaking, data);
-        if (data.disable_expired_at) {
+        if (
+          (data.user_id === userStore.userInfo?.id &&
+            data.disable_expired_at) ||
+          data.is_disable_speaking
+        ) {
           window.$message.error('你已被禁言!');
+          appStore.disableSpeaking.set(data.live_room_id, {
+            exp: data.disable_expired_at,
+            label: formatDownTime({
+              startTime: +new Date(),
+              endTime: data.disable_expired_at,
+            }),
+          });
+          clearTimeout(timerObj.value[data.live_room_id]);
+          timerObj.value[data.live_room_id] = setInterval(() => {
+            if (
+              data.disable_expired_at &&
+              +new Date() > data.disable_expired_at
+            ) {
+              clearTimeout(timerObj.value[data.live_room_id]);
+            }
+            appStore.disableSpeaking.set(data.live_room_id, {
+              exp: data.disable_expired_at!,
+              label: formatDownTime({
+                startTime: +new Date(),
+                endTime: data.disable_expired_at!,
+              }),
+            });
+          }, 1000);
           damuList.value = damuList.value.filter(
             (v) => v.request_id !== data.request_id
           );
         }
+        if (data.user_id !== userStore.userInfo?.id && data.disable_ok) {
+          console.log('disable_ok', data);
+          window.$message.success('禁言成功!');
+        }
+        if (
+          data.user_id !== userStore.userInfo?.id &&
+          data.restore_disable_ok
+        ) {
+          window.$message.success('解除禁言成功!');
+        }
+        if (
+          data.user_id === userStore.userInfo?.id &&
+          data.restore_disable_ok
+        ) {
+          window.$message.success('禁言接触了!');
+          clearTimeout(timerObj.value[data.live_room_id]);
+          appStore.disableSpeaking.delete(data.live_room_id);
+        }
       }
     );
 

+ 8 - 3
src/interface-ws.ts

@@ -111,8 +111,9 @@ export type WsMessageType = IWsFormat<{
 
 /** 禁言用户 */
 export type WsDisableSpeakingType = IWsFormat<{
+  request_id?: string;
   /** 被禁言用户socket_id */
-  socket_id: number;
+  socket_id: string;
   /** 被禁言用户id */
   user_id: number;
   /** 直播间id */
@@ -123,10 +124,14 @@ export type WsDisableSpeakingType = IWsFormat<{
   disable_created_at?: number;
   /** 禁言到期消息 */
   disable_expired_at?: number;
+  /** 禁言成功 */
+  disable_ok?: boolean;
+  /** 解除禁言成功 */
+  restore_disable_ok?: boolean;
+  /** 是否正在禁言 */
+  is_disable_speaking?: boolean;
   /** 是否解除禁言 */
   restore?: boolean;
-  /** 消息id */
-  request_id?: number;
 }>;
 
 /** 其他用户加入直播间 */

+ 2 - 0
src/store/app/index.ts

@@ -38,6 +38,7 @@ export type AppRootState = {
   liveLine: LiveLineEnum;
   liveRoomInfo?: ILiveRoom;
   showLoginModal: boolean;
+  disableSpeaking: Map<number, { exp: number; label: string }>;
 };
 
 export const useAppStore = defineStore('app', {
@@ -55,6 +56,7 @@ export const useAppStore = defineStore('app', {
       liveLine: LiveLineEnum.hls,
       liveRoomInfo: undefined,
       showLoginModal: false,
+      disableSpeaking: new Map(),
     };
   },
   actions: {

+ 30 - 2
src/views/pull/index.vue

@@ -270,6 +270,18 @@
         class="send-msg"
         v-loading="msgLoading"
       >
+        <div
+          class="disableSpeaking"
+          v-if="appStore.disableSpeaking.get(appStore.liveRoomInfo?.id || -1)"
+        >
+          <div class="bg"></div>
+          <span class="txt">
+            你被禁言了({{
+              appStore.disableSpeaking.get(appStore.liveRoomInfo?.id || -1)
+                ?.label
+            }})
+          </span>
+        </div>
         <div class="control">
           <div
             class="ico face"
@@ -282,7 +294,6 @@
             @click="mockClick"
           >
             <input
-              placeholder="发个弹幕吧~"
               ref="uploadRef"
               type="file"
               class="input-upload"
@@ -292,6 +303,7 @@
           </div>
         </div>
         <textarea
+          :placeholder="'发个弹幕吧~'"
           v-model="danmuStr"
           class="ipt"
           @keydown="keydownDanmu"
@@ -893,7 +905,6 @@ function handleScrollTop() {
 
         .name {
           color: #9499a0;
-          cursor: pointer;
           &.system {
             color: red;
           }
@@ -929,6 +940,23 @@ function handleScrollTop() {
       box-sizing: border-box;
       padding: 4px 10px;
       width: 100%;
+      .disableSpeaking {
+        cursor: no-drop;
+
+        .bg {
+          @extend %maskBg;
+          position: absolute !important;
+        }
+        .txt {
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%);
+          font-size: 14px;
+          width: 100%;
+          text-align: center;
+        }
+      }
       .control {
         display: flex;
         margin: 4px 0;