media_player_client/src/pages/TopToolBar.vue

847 lines
26 KiB
Vue

<template>
<div>
<q-toolbar style="background-color: #3e9acd" class="shadow-2 text-white">
<q-btn-dropdown
v-if="false"
v-touch-hold:10000.mouse="handleHold"
:disable-dropdown="!show_advanced_menu"
stretch
flat
icon="img:icons/favicon-32x32.png"
label="电视机拼接盒"
class="q-mr-sm"
>
<q-list>
<q-item
clickable
v-close-popup
@click="$refs.upgrade_dialog.showDialog()"
>
<q-item-section avatar>
<q-icon name="system_update" />
</q-item-section>
<q-item-section>
{{ $t("upgrade") }}
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn-dropdown
stretch
flat
icon="devices"
:label="$store.state.device_ip_address"
class="q-mr-sm"
>
<q-list>
<div v-if="false">
<div
v-for="(item, index) of $store.state.connect_list"
:key="index"
>
<q-item clickable v-close-popup @click="changeHost(item)">
<q-item-section avatar>
<q-icon
name="computer"
:color="
item.host == $store.state.device_ip_address ? 'green' : ''
"
/>
</q-item-section>
<q-item-section>
<q-item-label>
{{ item.name ? item.name : $t("client") + index }}
</q-item-label>
<q-item-label caption>
{{ item.host }}
</q-item-label>
</q-item-section>
</q-item>
</div>
</div>
<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
: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
: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.showDialog()"
/>
<q-btn
stretch
: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="$refs.grid_setting_dialog.showDialog()"
/>
<q-btn
stretch
: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
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
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
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
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
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
:disable="!$store.state.power_state"
flat
stack
icon="border_clear"
:label="$t('edge blending')"
class="q-mr-sm"
v-if="false"
@click="$refs.edge_blending_dialog.showDialog()"
/>
<q-btn
stretch
: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
stretch
flat
stack
icon="img:new_icon/power_off.png"
:label="$t('power off')"
class="q-mr-sm"
@click="powerOff"
/>
<q-btn
stretch
flat
stack
icon="img:new_icon/power_on.png"
:label="$t('power on')"
class="q-mr-sm"
@click="powerOn"
/>
<q-btn
v-if="function_center_control"
:disable="!$store.state.power_state"
stretch
flat
stack
icon="img:new_icon/center_control.png"
:label="$t('center contorl')"
class="q-mr-sm"
@click="$refs.center_control_dialog.showDialog()"
/>
<q-space />
<q-btn-dropdown
:disable="!$store.state.power_state"
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">
<q-item
clickable
v-close-popup
@click="$refs.background_image_dialog.showDialog()"
>
<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()"
>
<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">
<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()"
>
<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="switchLanguage">
<q-item-section avatar>
<!-- <q-icon name="info_outline" /> -->
<q-icon name="translate" />
</q-item-section>
<q-item-section>
{{ $t("CN/EN switch") }}
</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="showDeviceInfo">
<q-item-section avatar>
<!-- <q-icon name="devices" /> -->
<q-icon name="img:new_icon/device_info.png" />
</q-item-section>
<q-item-section>
{{ $t("device info") }}
</q-item-section>
</q-item>
<q-item
clickable
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
clickable
v-close-popup
@click="$refs.about_dialog.showDialog()"
>
<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
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 ref="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" />
</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 } from "vue";
import { useStore } from "src/store";
import GridSettingDialog from "src/components/GridSettingDialog.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 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,
date as $date,
} from "quasar";
import { useI18n } from "vue-i18n";
import { ConnectTableEntity } from "src/entities/ConnectTableEntity";
import ClientConnection from "src/common/ClientConnection";
export default defineComponent({
name: "PageTopToolBar",
components: {
GridSettingDialog,
BackgroundImageDialog,
RecoveryDatabaseDialog,
UpgradeDialog,
FileManageDialog,
SubtitleDialog,
SystemSettingDialog,
AboutDialog,
EdgeBlendingDialog,
RegisterDialog,
CenterControlDialog,
AdvancedDebugDialog,
WindowRectEditDialog,
},
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 function_center_control = ref(
($store.state.device_attribute &
Protocol.EDeviceAttribute.CenterControl) !=
0
);
let system_run_time = 0;
let system_idle_time = 0;
let current_system_time = 0;
let server_run_time = 0;
let server_all_run_time = 0;
const window_rect_edit_dialog: Ref<any> = ref(null);
const plan_running = computed(
() => $store.state.current_running_plan.trim() != ""
);
const get_time_text = (s: number, show_ss: boolean = true) => {
console.log(s);
var time = "";
var second = s % 60;
var minute = parseInt((parseInt(s.toString()) / 60).toString()) % 60;
if (show_ss) {
time = second + $t.t("SS");
}
if (minute >= 1) {
time = minute + $t.t("MM") + time;
}
var hour = parseInt((parseInt((s / 60).toString()) / 60).toString()) % 24;
if (hour >= 1) {
time = hour + $t.t("HH") + time;
}
var day = parseInt(
(
parseInt((parseInt((s / 60).toString()) / 60).toString()) / 24
).toString()
);
if (day >= 1) {
time = day + $t.t("DD") + time;
}
return time;
};
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 {}
}
);
watch(
() => $store.state.device_attribute,
(value) => {
function_center_control.value =
(value & Protocol.EDeviceAttribute.CenterControl) != 0;
}
);
return {
show_advanced_menu,
plan_running,
edge_blending_dialog,
register_dialog,
function_center_control,
window_rect_edit_dialog,
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);
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();
}
},
async showDeviceInfo() {
try {
const response = await GlobalData.getInstance()
.getCurrentClient()
?.getSystemTimes();
if (response) {
system_run_time = response.system_run_time;
system_idle_time = response.system_idle_time;
current_system_time = response.current_system_time;
server_run_time = response.server_run_time;
server_all_run_time = response.server_all_run_time;
}
} catch (e) {
console.log(e);
}
$q.dialog({
html: true,
title: "<div class='text-h4'>" + $t.t("device info") + "</div>",
message: `<div class="text-h6">
${$t.t("device resolution")} : ${$store.state.device_screen_width}X${
$store.state.device_screen_height
}@${$store.state.device_screen_refresh_rate}<br />
${$t.t("system run time")} : ${get_time_text(system_run_time)} <br />
${$t.t("system idle rate")} : ${(
(system_idle_time / (system_run_time * 4)) *
100
).toFixed(0)} % <br />
${$t.t("server run time")} : ${get_time_text(server_run_time)} <br />
${$t.t("server all run time")} : ${get_time_text(
server_all_run_time,
false
)} <br />
${$t.t("current server system time")} : ${$date.formatDate(
new Date(current_system_time),
"YYYY-MM-DD HH:mm:ss"
)}<br />
</div>`,
});
},
async powerOff() {
let success = false;
try {
const response = await GlobalData.getInstance()
.getCurrentClient()
?.deviceStandByMode();
if (response) {
success = response?.success ?? false;
}
} catch {}
$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 {}
$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) {
const result =
await window_rect_edit_dialog.value.showDialogAsync(
window.x * $store.state.device_screen_width,
window.y * $store.state.device_screen_height,
window.width * $store.state.device_screen_width,
window.height * $store.state.device_screen_height
);
if (result) {
let { x, y, width, height } = result;
x /= $store.state.device_screen_width;
y /= $store.state.device_screen_height;
width /= $store.state.device_screen_width;
height /= $store.state.device_screen_height;
GlobalData.getInstance()
.getCurrentClient()
?.setWindowGeometry(window.window_id, x, y, width, height);
}
}
} catch {}
}
},
};
},
});
</script>