media_player_client/src/pages/custom/ISVTopToolBar.vue

851 lines
25 KiB
Vue

<template>
<div>
<q-toolbar
style="background-color: #3e9acd"
class="shadow-2 text-white"
@dragstart.prevent
>
<q-btn-dropdown
stretch
no-caps
flat
icon="devices"
:label="$store.state.device_ip_address"
class="q-mr-sm"
>
<q-list>
<q-item clickable v-close-popup @click="logout">
<q-item-section avatar> <q-icon name="logout" /> </q-item-section>
<q-item-section>
{{ $t("logout") }}
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-separator vertical inset />
<q-btn
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*settings*/ 'img:new_icon/system_setting.png'"
:label="$t('system setting')"
class="q-mr-sm"
@click="$refs.system_setting_dialog.showDialog()"
/>
<q-btn
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*description*/ 'img:new_icon/file_manager.png'"
:label="$t('file manage')"
class="q-mr-sm"
@click="$refs.file_manage_dialog.showDialogAsync()"
/>
<q-btn
v-if="$store.state.custom_defines.function_output_board"
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*settings*/ 'img:new_icon/system_setting.png'"
:label="$t('video wall')"
class="q-mr-sm"
@click="$refs.isv_video_wall_dialog.showDialog()"
/>
<q-btn
stretch
no-caps
v-else
:disable="!$store.state.power_state"
flat
stack
icon="img:new_icon/full_screen_icon.png"
class="q-mr-sm"
:label="$t('full screen window')"
@click="fullscreenWindow"
/>
<q-btn
v-if="$store.state.custom_defines.function_output_board"
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*settings*/ 'img:new_icon/system_setting.png'"
:label="$t('splice') + $t(' ') + $t(splicing_state ? 'off' : 'on')"
class="q-mr-sm"
@click="switchOutputBoardState"
/>
<q-btn
stretch
no-caps
v-else
:disable="!$store.state.power_state"
flat
stack
icon="img:new_icon/exit_full_screen_icon.png"
class="q-mr-sm"
:label="$t('restore window size')"
@click="exitFullscreenWindow"
/>
<q-btn
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*grid_on*/ 'img:new_icon/grid_setting.png'"
:label="$t('grid setting')"
class="q-mr-sm"
@click="
($store.state.isSpecialVideo()
? $refs.special_video_grid_setting_dialog
: $refs.grid_setting_dialog
)?.showDialog()
"
/>
<q-btn
v-if="$store.state.isLedPlayer()"
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
:icon="/*art_track*/ 'img:new_icon/subtitle.png'"
:label="$t('subtitle')"
class="q-mr-sm"
@click="$refs.subtitle_dialog.showDialog()"
/>
<q-btn
stretch
no-caps
flat
stack
:disable="plan_running || !$store.state.power_state"
:icon="/*vertical_align_bottom*/ 'img:new_icon/edit_window_rect.png'"
:label="$t('toolbar edit window rect')"
class="q-mr-sm"
@click="editRect"
/>
<q-btn
stretch
no-caps
flat
stack
:disable="plan_running || !$store.state.power_state"
:icon="/*vertical_align_top*/ 'img:new_icon/top_window.png'"
:label="$t('win top')"
class="q-mr-sm"
@click="topWindow"
/>
<q-btn
stretch
no-caps
flat
stack
:disable="plan_running || !$store.state.power_state"
:icon="/*vertical_align_bottom*/ 'img:new_icon/lower_window.png'"
:label="$t('win lower')"
class="q-mr-sm"
@click="lowerWindow"
/>
<q-btn
stretch
no-caps
flat
stack
:disable="plan_running || !$store.state.power_state"
:icon="/*close*/ 'img:new_icon/close_window.png'"
:label="$t('close')"
class="q-mr-sm"
@click="closeCurrentWindow"
/>
<q-btn
stretch
flat
no-caps
stack
:disable="plan_running || !$store.state.power_state"
:icon="/*clear_all*/ 'img:new_icon/clean_windows.png'"
:label="$t('clean screen')"
class="q-mr-sm"
@click="closeAllWindows"
/>
<q-btn
stretch
no-caps
:disable="!$store.state.power_state"
flat
stack
icon="stop"
:label="$t('stop plan')"
class="q-mr-sm"
v-if="plan_running"
@click="stopPlan"
/>
<q-btn
v-if="$store.state.custom_defines.function_center_control"
:disable="!$store.state.power_state"
no-caps
stretch
flat
stack
icon="img:new_icon/center_control.png"
:label="$t('center control')"
class="q-mr-sm"
@click="$refs.center_control_dialog.showDialog()"
/>
<q-space />
<q-btn-dropdown
no-caps
stretch
flat
:icon="/*build*/ 'img:new_icon/other_setting.png'"
:label="$t('other setting')"
class="q-mr-sm"
>
<q-list
style="background-color: #3e9acd"
class="shadow-2 text-white"
@dragstart.prevent
>
<q-item
clickable
v-close-popup
:disable="power_flag"
@click="powerOff"
>
<q-item-section avatar>
<!-- <q-icon name="image" /> -->
<q-icon name="img:new_icon/power_off.png" />
</q-item-section>
<q-item-section>
{{ $t("power off") }}
</q-item-section>
</q-item>
<q-item
clickable
:disable="power_flag"
v-close-popup
@click="powerOn"
>
<q-item-section avatar>
<!-- <q-icon name="image" /> -->
<q-icon name="img:new_icon/power_on.png" />
</q-item-section>
<q-item-section>
{{ $t("power on") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$refs.background_image_dialog.showDialog()"
:disable="!$store.state.power_state"
>
<q-item-section avatar>
<!-- <q-icon name="image" /> -->
<q-icon name="img:new_icon/background_image.png" />
</q-item-section>
<q-item-section>
{{ $t("background image setting") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$refs.recovery_database_dialog.showDialog()"
:disable="!$store.state.power_state"
>
<q-item-section avatar>
<!-- <q-icon name="backup" /> -->
<q-icon name="img:new_icon/database_backup.png" />
</q-item-section>
<q-item-section>
{{ $t("database import") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="backupDB"
:disable="!$store.state.power_state"
>
<q-item-section avatar>
<!-- <q-icon name="cloud_download" /> -->
<q-icon name="img:new_icon/database_recovery.png" />
</q-item-section>
<q-item-section>
{{ $t("database export") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$refs.upgrade_dialog.showDialog()"
:disable="!$store.state.power_state"
>
<q-item-section avatar>
<!-- <q-icon name="system_update" /> -->
<q-icon name="img:new_icon/upgrade.png" />
</q-item-section>
<q-item-section>
{{ $t("upgrade") }}
</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
@click="$refs.about_dialog.showDialog()"
v-if="false"
>
<q-item-section avatar>
<!-- <q-icon name="info_outline" /> -->
<q-icon name="img:new_icon/about.png" />
</q-item-section>
<q-item-section>
{{ $t("about") }}
</q-item-section>
</q-item>
<q-item
clickable
v-if="$store.state.factory_mode"
v-close-popup
@click="$refs.register_dialog.showDialog()"
>
<q-item-section avatar>
<!-- <q-icon name="devices" /> -->
<q-icon name="lock_open" />
</q-item-section>
<q-item-section>
{{ $t("register device") }}
</q-item-section>
</q-item>
<q-item
v-if="$store.state.advanced_debug"
clickable
v-close-popup
@click="$refs.advanced_debug_dialog.showDialog()"
>
<q-item-section avatar>
<q-icon name="bug_report" />
</q-item-section>
<q-item-section> AdvancedDebug </q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-separator vertical inset />
<q-item>
<q-item-section avatar style="margin-right: 0px; padding-right: 0px">
<!-- <q-icon class="text-white rotate" name="img:svgs/fan.svg" /> -->
<q-icon class="text-white rotate" name="img:new_icon/fan.png" />
</q-item-section>
<q-item-section style="margin-left: -25px">
{{ $store.state.fan_temp.toFixed(1) }} ℃
</q-item-section>
</q-item>
</q-toolbar>
</div>
<grid-setting-dialog
v-if="$store.state.isLedPlayer()"
ref="grid_setting_dialog"
/>
<special-video-grid-setting-dialog
v-if="$store.state.isSpecialVideo()"
ref="special_video_grid_setting_dialog"
/>
<background-image-dialog ref="background_image_dialog" />
<subtitle-dialog ref="subtitle_dialog" />
<recovery-database-dialog ref="recovery_database_dialog" />
<upgrade-dialog ref="upgrade_dialog" />
<file-manage-dialog ref="file_manage_dialog" />
<system-setting-dialog ref="system_setting_dialog" />
<about-dialog ref="about_dialog" />
<edge-blending-dialog ref="edge_blending_dialog" />
<register-dialog ref="register_dialog" />
<center-control-dialog ref="center_control_dialog" />
<advanced-debug-dialog ref="advanced_debug_dialog" />
<window-rect-edit-dialog ref="window_rect_edit_dialog" />
<i-s-v-video-wall-dialog ref="isv_video_wall_dialog" />
</template>
<style scoped>
@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
.rotate {
animation: rotate 1.5s linear infinite;
}
</style>
<script lang="ts">
import { defineComponent, ref, Ref, computed, watch, onMounted } from "vue";
import { useStore } from "src/store";
import GridSettingDialog from "src/components/GridSettingDialog.vue";
import SpecialVideoGridSettingDialog from "src/components/SpecialVideoGridSettingDialog.vue";
import BackgroundImageDialog from "src/components/BackgroundImageDialog.vue";
import RecoveryDatabaseDialog from "src/components/RecoveryDatabaseDialog.vue";
import UpgradeDialog from "src/components/UpgradeDialog.vue";
import FileManageDialog from "src/components/FileManageDialog.vue";
import SubtitleDialog from "src/components/SubtitleDialog.vue";
import SystemSettingDialog from "src/components/SystemSettingDialog.vue";
import AboutDialog from "src/components/AboutDialog.vue";
import EdgeBlendingDialog from "src/components/EdgeBlendingDialog.vue";
import RegisterDialog from "src/components/RegisterDialog.vue";
import CenterControlDialog from "src/components/CenterControlDialog.vue";
import AdvancedDebugDialog from "src/components/AdvancedDebugDialog.vue";
import WindowRectEditDialog from "src/components/WindowRectEditDialog.vue";
import ISVVideoWallDialog from "src/components/custom/ISVVideoWallDialog.vue";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
import { Protocol } from "src/entities/WSProtocol";
import GlobalData from "src/common/GlobalData";
import { api } from "boot/axios";
import { HttpProtocol } from "src/entities/HttpProtocol";
import { SessionStorage, Cookies, openURL, useQuasar } from "quasar";
import { useI18n } from "vue-i18n";
import { ConnectTableEntity } from "src/entities/ConnectTableEntity";
import ClientConnection from "src/common/ClientConnection";
export default defineComponent({
name: "PageCustomISVTopToolBar",
components: {
GridSettingDialog,
SpecialVideoGridSettingDialog,
BackgroundImageDialog,
RecoveryDatabaseDialog,
UpgradeDialog,
FileManageDialog,
SubtitleDialog,
SystemSettingDialog,
AboutDialog,
EdgeBlendingDialog,
RegisterDialog,
CenterControlDialog,
AdvancedDebugDialog,
WindowRectEditDialog,
ISVVideoWallDialog,
},
setup() {
let $store = useStore();
let $q = useQuasar();
let $t = useI18n();
let show_advanced_menu = ref(true);
const edge_blending_dialog: Ref<any> = ref(null);
const register_dialog: Ref<any> = ref(null);
const window_rect_edit_dialog: Ref<any> = ref(null);
const splicing_state = ref(false);
const power_flag = ref(false);
watch(
() => power_flag.value,
(newV) => {
if (newV) {
setTimeout(() => {
power_flag.value = false;
}, 1100 * 5);
}
}
);
const plan_running = computed(
() => $store.state.current_running_plan.trim() != ""
);
const checkRegistered = () => {
if (
GlobalData.getInstance().getCurrentClient()?.is_connected &&
GlobalData.getInstance().getCurrentClient()?.is_login
) {
let register: any =
GlobalData.getInstance().applicationConfig?.registered;
try {
register = JSON.parse(register);
} catch {
register = false;
}
if (
!register &&
(!register_dialog.value || !register_dialog.value.isShow())
) {
$q.notify({
color: "negative",
icon: "report_problem",
message:
"<span class='text-h4'>" +
$t.t("not registered") +
"!!!" +
"</span>",
position: "center",
actions: [
{
label: $t.t("register"),
color: "blue",
handler: () => {
if (register_dialog.value) {
register_dialog.value.showDialog();
}
},
},
],
html: true,
timeout: 2500,
});
}
}
};
setInterval(checkRegistered, 5000);
EventBus.getInstance().on(
EventNamesDefine.CurrentConnectConnected,
async () => {
try {
const client = GlobalData.getInstance().getCurrentClient();
if (client) {
const response = await client.getConnectList();
if (response) {
$store.commit("setConnects", response.connects);
}
}
} catch {}
}
);
EventBus.getInstance().on(EventNamesDefine.NotifyMessage, (notify) => {
try {
switch (notify.packet.command) {
case Protocol.Commands.kOutputBoardSettingNotify: {
let temp = JSON.parse(
notify.data
) as Protocol.OutputBoardSettingNotify;
splicing_state.value = temp?.splicing ?? false;
}
}
} catch (e) {
console.error(e);
}
});
GlobalData.getInstance()
.getCurrentClient()
?.getOutputBoardSetting()
?.then((response) => {
splicing_state.value = response?.splicing ?? false;
});
return {
show_advanced_menu,
plan_running,
edge_blending_dialog,
register_dialog,
window_rect_edit_dialog,
power_flag,
splicing_state,
async backupDB() {
let client = GlobalData.getInstance().getCurrentClient();
if (client) {
let url = new URL(client.url);
url.port =
GlobalData.getInstance().applicationConfig?.httpserver_port ??
HttpProtocol.DefaultHttpPort.toString();
url.pathname = HttpProtocol.RequestPathUpdateDBBackupFile;
url.protocol = "http:";
console.log(url.toString());
let response = await api.get(url.toString());
if (response.status == 200 && response && response.data) {
url.pathname =
HttpProtocol.RequestPathDBBackup + "/" + response.data;
openURL(url.toString());
} else {
$q.notify({
type: "warning",
message: $t.t("data export ") + $t.t("fail") + "!",
position: "top",
timeout: 1500,
});
}
}
},
handleHold() {
show_advanced_menu.value = true;
},
stopPlan() {
GlobalData.getInstance().getCurrentClient()?.stopCurrentRunningPlan();
},
topWindow() {
const window = $store.state.windows.find(
(element) => element && element.uuid == $store.state.selected_window
);
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.focusIn(window.window_id);
}
},
lowerWindow() {
const window = $store.state.windows.find(
(element) => element && element.uuid == $store.state.selected_window
);
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.lowerWindow(window.window_id);
}
},
closeCurrentWindow() {
const window = $store.state.windows.find(
(element) => element && element.uuid == $store.state.selected_window
);
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.closeWindow(window.window_id);
}
},
closeAllWindows() {
// for (const window of $store.state.windows) {
// if (window) {
// GlobalData.getInstance()
// .getCurrentClient()
// ?.closeWindow(window.window_id);
// }
// }
GlobalData.getInstance().getCurrentClient()?.closeWindow(-1);
},
switchLanguage() {
let language = Cookies.get("language");
if (!language) {
language = "zh-CN";
}
if (language != "zh-CN" && language != "en-US") {
language = "zh-CN";
} else {
language = language == "zh-CN" ? "en-US" : "zh-CN";
}
Cookies.set("language", language, {
expires: 365,
});
window.location.reload();
},
logout() {
const w = window as any;
if (w.controlLogout && typeof w.controlLogout == "function") {
w.controlLogout();
} else {
Cookies.remove("auto_login");
SessionStorage.clear();
try {
$q.fullscreen.exit();
} catch {}
window.location.reload();
}
},
powerOff() {
$q.dialog({
title: $t.t("power off"),
message: $t.t("are you sure power off device") + "?",
ok: {
label: $t.t("ok"),
noCaps: true,
flat: true,
},
cancel: {
label: $t.t("cancel"),
noCaps: true,
flat: true,
},
persistent: true,
}).onOk(async () => {
let success = false;
try {
const response = await GlobalData.getInstance()
.getCurrentClient()
?.deviceStandByMode();
if (response) {
success = response?.success ?? false;
}
} catch {}
if (success) {
power_flag.value = true;
}
$q.notify({
color: success ? "positive" : "negative",
icon: success ? "done" : "warning",
message:
$t.t("send power off command") +
(success ? $t.t("success") : $t.t("fail")) +
"!",
position: "top",
timeout: 1500,
});
});
},
async powerOn() {
let success = false;
try {
const response = await GlobalData.getInstance()
.getCurrentClient()
?.wakeUpDevice();
if (response) {
success = response?.success ?? false;
}
} catch {}
if (success) {
power_flag.value = true;
}
$q.notify({
color: success ? "positive" : "negative",
icon: success ? "done" : "warning",
message:
$t.t("send power on command") +
(success ? $t.t("success") : $t.t("fail")) +
"!",
position: "top",
timeout: 1500,
});
},
async changeHost(item: ConnectTableEntity) {
if (item) {
const url =
"ws://" +
item.host +
":" +
GlobalData.kDefaultWebsocektPort.toString() +
GlobalData.kWebsocketResource;
const web_socket = new ClientConnection(
url,
item.user,
item.password
);
$q.loading.hide();
$q.loading.show({
message: $t.t("connection") + "...",
});
const wait_for = (ms: number) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(true);
}, ms);
});
};
let login_success = false;
for (let i = 0; i < 20; ++i) {
await wait_for(500);
if (web_socket._is_login) {
login_success = true;
break;
}
}
$q.loading.hide();
{
$q.notify({
color: login_success ? "positive" : "negative",
icon: login_success ? "done" : "warning",
message:
$t.t("login") +
(login_success
? $t.t("success")
: $t.t("fail") +
$t.t("please check ipaddress or username or password")) +
"!",
position: "top",
timeout: 1500,
});
if (login_success) {
GlobalData.getInstance().addClient(item.host, web_socket);
GlobalData.getInstance().setCurrentClientName(item.host);
$store.commit("setDeviceIpAddress", item.host);
EventBus.getInstance().emit(
EventNamesDefine.CurrentClientChanged
);
} else {
web_socket.destory();
GlobalData.getInstance().removeClient(item.host);
}
}
}
},
async editRect() {
if (window_rect_edit_dialog.value) {
try {
const window = $store.state.windows.find(
(element) =>
element && element.uuid == $store.state.selected_window
);
if (window) {
window_rect_edit_dialog.value.showDialog(window.window_id);
}
} catch {}
}
},
fullscreenWindow() {
const window = $store.state.windows.find(
(element) => element && element.uuid == $store.state.selected_window
);
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.windowFullScreen(window.window_id, true);
}
},
exitFullscreenWindow() {
const window = $store.state.windows.find(
(element) => element && element.uuid == $store.state.selected_window
);
if (window) {
GlobalData.getInstance()
.getCurrentClient()
?.windowFullScreen(window.window_id, false);
}
},
switchOutputBoardState() {
GlobalData.getInstance()
.getCurrentClient()
?.switchOutputBoardSplitState();
},
};
},
});
</script>