From 0da2e1993f69afc2b82d0bd92cb3b18f7f51b051 Mon Sep 17 00:00:00 2001 From: fangxiang Date: Wed, 19 Jan 2022 19:28:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=9A=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E7=BB=84=E4=BB=B6=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=BD=AE=E8=AF=A2=E8=AE=BE=E7=BD=AE=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/ClientConnection.ts | 24 ++ src/common/RemoteDataExangeProcesser.ts | 45 ++- src/components/PlaylistDialog.vue | 1 - src/components/PollingSettingDialog.vue | 304 ++++++++++++++++++ src/components/Window.vue | 86 ++++- src/entities/MultimediaWindowEntity.ts | 8 + src/entities/WSProtocol.ts | 84 ++++- .../WindowOtherStateChangeNotifyEntity.ts | 3 + src/i18n/zh-CN/index.ts | 18 +- src/layouts/MainLayout.vue | 6 +- src/pages/MediaControlPage.vue | 105 +++++- src/pages/RightToolBar.vue | 2 +- src/pages/WallPage.vue | 95 +++++- 13 files changed, 738 insertions(+), 43 deletions(-) create mode 100644 src/components/PollingSettingDialog.vue diff --git a/src/common/ClientConnection.ts b/src/common/ClientConnection.ts index e5cdee9..a354ef7 100644 --- a/src/common/ClientConnection.ts +++ b/src/common/ClientConnection.ts @@ -2,6 +2,7 @@ import ReconnectingWebSocket from "reconnecting-websocket"; import NormalWindowRequestEntity from "src/entities/NormalWindowRequestEntity"; import { PlanEntity } from "src/entities/PlanEntity"; import { SignalSourceEntity } from "src/entities/SignalSourceEntity"; +import { StringKeyValueEntity } from "src/entities/StringKeyValueEntity"; import SubtitleEntity from "src/entities/SubtitleEntity"; import { Protocol } from "src/entities/WSProtocol"; import EventBus, { EventNamesDefine } from "./EventBus"; @@ -605,6 +606,7 @@ export default class ClientConnection { console.error(e); } } + public async setOutputBoardSetting( request: Protocol.SetOutputBoardSettingRequestEntity ) { @@ -616,6 +618,7 @@ export default class ClientConnection { console.error(e); } } + public async restoreOutputBoard() { try { return await this.doRpc( @@ -669,6 +672,27 @@ export default class ClientConnection { ); } + public async startPolling(window_id: number) { + this.ws?.send( + JSON.stringify(new Protocol.StartPollingRequestEntity(window_id)) + ); + } + + public async stopPolling(window_id: number) { + this.ws?.send( + JSON.stringify(new Protocol.StopPollingRequestEntity(window_id)) + ); + } + + public async setPollingData( + window_id: number, + datas?: StringKeyValueEntity[] + ) { + return await this.doRpc( + new Protocol.SetPollingDataRequestEntity(window_id, datas) + ); + } + public async getBuildInfo() { return await this.doRpc( new Protocol.GetBuildInfoRequestEntity(0) diff --git a/src/common/RemoteDataExangeProcesser.ts b/src/common/RemoteDataExangeProcesser.ts index d5a8dd4..67ea912 100644 --- a/src/common/RemoteDataExangeProcesser.ts +++ b/src/common/RemoteDataExangeProcesser.ts @@ -8,8 +8,17 @@ export default class RemoteDataExangeProcesser { private flag = false; private options: OptionsType; + private plan_notify: any = null; + constructor(options: OptionsType) { this.options = options; + + EventBus.getInstance().on(EventNamesDefine.WebSocketClose, () => { + if (this.plan_notify) { + this.plan_notify(void 0); + this.plan_notify = null; + } + }); } enable() { @@ -71,18 +80,30 @@ export default class RemoteDataExangeProcesser { notify.data ) as Protocol.PlanRunningStateChangeNotifyEntity; if (temp && temp.plan) { - $q.notify({ - color: "positive", - icon: "done", - message: - $t.t("plan") + - " '" + - temp.plan.name + - " '" + - (temp.running ? $t.t("is running") : $t.t("is stopping")), - position: "top", - timeout: 2000, - }); + if (temp.running) { + if (this.plan_notify) { + this.plan_notify(void 0); + this.plan_notify = null; + } + this.plan_notify = $q.notify({ + position: "center", + color: "positive", + timeout: 0, // we want to be in control when it gets dismissed + spinner: true, + message: + $t.t("plan") + + ": " + + temp.plan.name + + " " + + $t.t("running now") + + "!", + }); + } else { + if (this.plan_notify) { + this.plan_notify(void 0); + this.plan_notify = null; + } + } } } break; diff --git a/src/components/PlaylistDialog.vue b/src/components/PlaylistDialog.vue index 75fd1ca..b6bd827 100644 --- a/src/components/PlaylistDialog.vue +++ b/src/components/PlaylistDialog.vue @@ -171,7 +171,6 @@ export default defineComponent({ } } catch {}*/ - console.log(prefix); let temp_str = decodeURI(new URL(item).pathname).replace( /\\/g, "/" diff --git a/src/components/PollingSettingDialog.vue b/src/components/PollingSettingDialog.vue new file mode 100644 index 0000000..d8faa9a --- /dev/null +++ b/src/components/PollingSettingDialog.vue @@ -0,0 +1,304 @@ + + + + + diff --git a/src/components/Window.vue b/src/components/Window.vue index 45c6cc2..cd32d21 100644 --- a/src/components/Window.vue +++ b/src/components/Window.vue @@ -60,16 +60,75 @@ > {{ $t("close all windwos") }} + + {{ $t("start polling") }} + + + + {{ $t("stop polling") }} + + + + {{ $t("polling setting") }} +
- - {{ signal_source.name }} - + {{ + $props.window.polling_title + }} + {{ signal_source.name }} + +
+ + {{ $t("polling now") }} +
+
+ + {{ + $t($props.window.muted ? "muted now" : "unmuted now") + }} +
- signal_source.value.window_type == "EwindowType::Multimedia" || - signal_source.value.window_type == "EwindowType::HdmiIn" + const calc_is_audio_player_window = (window_type: string) => { + return ( + window_type == "EwindowType::Multimedia" || + window_type == "EwindowType::Rtsp" || + window_type == "EwindowType::HdmiIn" + ); + }; + const is_audo_player_window = computed(() => + calc_is_audio_player_window(signal_source.value.window_type) ); reload_signal_source(); @@ -395,6 +462,7 @@ export default defineComponent({ flags, is_audo_player_window, + calc_is_audio_player_window, onClick(evt: PointerEvent) { if (selected.value != true) { EventBus.getInstance().emit(EventNamesDefine.UnSelectAllWindows); diff --git a/src/entities/MultimediaWindowEntity.ts b/src/entities/MultimediaWindowEntity.ts index c290308..7383d36 100644 --- a/src/entities/MultimediaWindowEntity.ts +++ b/src/entities/MultimediaWindowEntity.ts @@ -1,5 +1,6 @@ import BaseEntity from "./BaseEntity"; import { SignalSourceEntity } from "./SignalSourceEntity"; +import { StringKeyValueEntity } from "./StringKeyValueEntity"; import { Protocol } from "./WSProtocol"; export class MultimediaWindowEntity extends BaseEntity { @@ -13,6 +14,8 @@ export class MultimediaWindowEntity extends BaseEntity { muted: boolean = false; playing: boolean = false; play_speed: number = 1; + polling: boolean = false; + polling_signal_sources: StringKeyValueEntity[] = []; } export class WindowOpenNotifyEntity extends MultimediaWindowEntity { @@ -36,4 +39,9 @@ export class WindowOpenNotifyEntity extends MultimediaWindowEntity { command = Protocol.Commands.kUnKnowCommand; window_id: number = 0; + + /** 轮询时的属性,不轮询时无效 */ + polling_title: string = ""; + /** 轮询时的属性,不轮询时无效 */ + polling_window_type: string = "EWindowType::Normal"; } diff --git a/src/entities/WSProtocol.ts b/src/entities/WSProtocol.ts index cf5a1c4..8f55f0f 100644 --- a/src/entities/WSProtocol.ts +++ b/src/entities/WSProtocol.ts @@ -1,3 +1,4 @@ +import { StringKeyValueEntity } from "./StringKeyValueEntity"; import { SignalSourceEntity } from "./SignalSourceEntity"; import ApplicationConfigEntity from "./ApplicationConfigEntity"; import { ModeEntity } from "./ModeEntity"; @@ -256,6 +257,19 @@ export namespace Protocol { return Commands.PROTOCOL_PREFIX + "PlayPrev"; } + public static get kStartPolling() { + return Commands.PROTOCOL_PREFIX + "StartPolling"; + } + public static get kStopPolling() { + return Commands.PROTOCOL_PREFIX + "StopPolling"; + } + public static get kRpcSetPollingData() { + return Commands.PROTOCOL_PREFIX + "RpcSetPollingData"; + } + public static get kPollingStateChanged() { + return Commands.PROTOCOL_PREFIX + "PollingStateChanged"; + } + static _all_commands = new Set([ Commands.kUnKnowCommand, Commands.kSearchDevice, @@ -315,6 +329,11 @@ export namespace Protocol { Commands.kWindowPlayNext, Commands.kPauseWindow, Commands.kPlayWindow, + Commands.kPollingStateChanged, + Commands.kRpcSetPollingData, + Commands.kStopPolling, + Commands.kStartPolling, + Commands.kPollingStateChanged, ]); public static get AllCommands() { @@ -512,7 +531,7 @@ export namespace Protocol { width: number = 0; height: number = 0; volume: number = 80; - muted: boolean = false; + muted: boolean = true; paused: boolean = false; play_speed: number = 1; @@ -1490,4 +1509,67 @@ export namespace Protocol { this.command = Commands.kFanTemperature; } } + + export class SetPollingDataRequestEntity extends Protocol.PacketEntity { + datas: StringKeyValueEntity[] = []; + window_id: number = 0; + constructor( + window_id: number, + datas?: StringKeyValueEntity[], + rcp_id?: number + ) { + super(); + this.rpc_id = rcp_id ?? 0; + this.command = Protocol.Commands.kRpcSetPollingData; + if (Array.isArray(datas)) { + if (datas.length % 2) { + datas.splice(datas.length - 1, 1); + } + this.datas = datas; + } + this.window_id = window_id; + } + } + + export class SetPollingDataResponseEntity extends Protocol.PacketEntity { + success = false; + + constructor() { + super(); + this.command = Protocol.Commands.kRpcSetPollingData; + } + } + + export class StartPollingRequestEntity extends PacketEntity { + window_id: number; + + constructor(window_id: number) { + super(); + this.rpc_id = 0; + this.command = Commands.kStartPolling; + this.window_id = window_id; + } + } + + export class StopPollingRequestEntity extends PacketEntity { + window_id: number; + + constructor(window_id: number) { + super(); + this.rpc_id = 0; + this.command = Commands.kStopPolling; + this.window_id = window_id; + } + } + + export class PollingStateChangeNotifyEntity extends PacketEntity { + window_id: number = 0; + polling: boolean = false; + window_type: string = "EwindowType::Normal"; + title: string = ""; + constructor() { + super(); + this.command = Commands.kPollingStateChanged; + } + } } diff --git a/src/entities/WindowOtherStateChangeNotifyEntity.ts b/src/entities/WindowOtherStateChangeNotifyEntity.ts index 13e084f..6a05aad 100644 --- a/src/entities/WindowOtherStateChangeNotifyEntity.ts +++ b/src/entities/WindowOtherStateChangeNotifyEntity.ts @@ -6,4 +6,7 @@ export default class WindowOtherStateChangeNotifyEntity extends Protocol.PacketE focus = false; muted = false; volume = 80; + polling = false; + title = ""; + window_type = "EWindowType::Normal"; } diff --git a/src/i18n/zh-CN/index.ts b/src/i18n/zh-CN/index.ts index a84edb1..b0df841 100644 --- a/src/i18n/zh-CN/index.ts +++ b/src/i18n/zh-CN/index.ts @@ -135,7 +135,6 @@ export default { pwa: "PWA版", "add plan item": "添加预案", "run plan directives send": "执行预案发送", - "is running": "正在运行", "is stopping": "已经停止", "add plan": "添加预案", "edit plan": "修改预案", @@ -292,4 +291,21 @@ export default { "play list": "播放列表", "close and save": "保存修改并关闭", "close and reset": "放弃修改并关闭", + operator_signal_source: "信号源", + "play prev": "上一曲", + "play next": "上一曲", + play: "播放", + pause: "暂停", + "volume up": "音量加", + "volume down": "音量减", + "start polling": "开启轮询", + "stop polling": "停止轮询", + "polling setting": "轮询设置", + "polling data": "轮询数据", + "set polling data": "设置轮询数据", + "please stop polling first": "请先停止轮询", + "muted now": "现在静音", + "unmuted now": "现在没有静音", + "polling now": "正在轮询窗口", + "running now": "正在运行", }; diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 4f8156e..9afe7c7 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -47,12 +47,8 @@ } } " - @click="(evt) => evt.stopPropagation()" > - +
diff --git a/src/pages/MediaControlPage.vue b/src/pages/MediaControlPage.vue index 04b1f80..ab837db 100644 --- a/src/pages/MediaControlPage.vue +++ b/src/pages/MediaControlPage.vue @@ -13,7 +13,16 @@ >
- + + {{ $t("play prev") }} +
- + > + {{ $t("play") }} + + {{ $t("pause") }}
+ > + {{ $t("play next") }}
- + + {{ $t("volume down") }}
@@ -46,20 +79,33 @@ flag size="lg" v-if="selected_window?.muted" - icon="volume_off" + :disable="plan_running" + icon="volume_mute" @click="unmuteWindow" - > + > {{ $t("unmute") }} + > {{ $t("mute") }}
- + + {{ $t("volume up") }} +
@@ -96,6 +142,31 @@ export default defineComponent({ let selected_window: Ref = ref(null); let is_multimedia_window = ref(false); + let can_pause_window = ref(false); + let can_next_prev_window = ref(false); + + let plan_running = ref(false); + + EventBus.getInstance().on( + EventNamesDefine.NotifyMessage, + (notify: NotifyMessage) => { + if (notify) { + switch (notify.packet.command) { + case Protocol.Commands.kCurrentRunningPlanStateChanged: + { + const temp = JSON.parse( + notify.data + ) as Protocol.PlanRunningStateChangeNotifyEntity; + if (temp && temp.plan) { + plan_running.value = temp.running; + } + } + break; + } + } + } + ); + watch( () => $store.state.selected_window, (newValue, oldValue) => { @@ -109,9 +180,16 @@ export default defineComponent({ element && element.uuid == window.signal_source_table_uuid ); if (signal_source) { + const type = window.polling + ? window.polling_window_type + : signal_source.window_type; is_multimedia_window.value = - signal_source.window_type == "EwindowType::Multimedia" || - signal_source.window_type == "EwindowType::RTSP"; + type == "EwindowType::Multimedia" || type == "EwindowType::Rtsp"; + + can_pause_window.value = type == "EwindowType::Multimedia"; + console.log(type); + can_next_prev_window.value = type == "EwindowType::Multimedia"; + console.log(can_next_prev_window.value); } } else { selected_window.value = null; @@ -123,6 +201,9 @@ export default defineComponent({ return { selected_window, is_multimedia_window, + can_pause_window, + can_next_prev_window, + plan_running, volumeUp(evt: MouseEvent) { evt.stopPropagation(); diff --git a/src/pages/RightToolBar.vue b/src/pages/RightToolBar.vue index 825f935..6755403 100644 --- a/src/pages/RightToolBar.vue +++ b/src/pages/RightToolBar.vue @@ -1,5 +1,5 @@