添加时钟信号源

This commit is contained in:
fangxiang 2022-01-24 16:06:16 +08:00
parent 80422c14b5
commit cabf9ba04d
11 changed files with 681 additions and 385 deletions

View File

@ -15,14 +15,14 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"element-resize-detector": "^1.2.3", "element-resize-detector": "^1.2.3",
"quasar": "^2.4.10", "quasar": "^2.4.12",
"reconnecting-websocket": "^4.4.0", "reconnecting-websocket": "^4.4.0",
"v-viewer": "^3.0.9", "v-viewer": "^3.0.9",
"vue-i18n": "^9.0.0-beta.0", "vue-i18n": "^9.0.0-beta.0",
"vuex": "^4.0.1" "vuex": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"@quasar/app": "^3.2.7", "@quasar/app": "^3.2.9",
"@types/node": "^10.17.15", "@types/node": "^10.17.15",
"workbox-webpack-plugin": "^6.0.0" "workbox-webpack-plugin": "^6.0.0"
}, },

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

View File

@ -17,6 +17,7 @@ export namespace Common {
["EwindowType::Ppt", "img:source_icon/ppt.png"], ["EwindowType::Ppt", "img:source_icon/ppt.png"],
["EwindowType::Rtsp", "img:source_icon/rtsp.png"], ["EwindowType::Rtsp", "img:source_icon/rtsp.png"],
["EwindowType::Subtitles", "img:source_icon/subtitles.png"], ["EwindowType::Subtitles", "img:source_icon/subtitles.png"],
["EwindowType::Clock", "img:source_icon/clock.png"],
["EwindowType::Weather", "img:source_icon/weather.png"], ["EwindowType::Weather", "img:source_icon/weather.png"],
["EwindowType::HdmiIn", "img:source_icon/hdmi.png"], ["EwindowType::HdmiIn", "img:source_icon/hdmi.png"],
]); ]);

View File

@ -153,6 +153,17 @@ export default defineComponent({
file_count.value = 0; file_count.value = 0;
}, },
showBackgroundImage() { showBackgroundImage() {
const temp_port =
GlobalData.getInstance().applicationConfig?.httpserver_port ??
HttpProtocol.DefaultHttpPort.toString();
try {
const url = new URL(
GlobalData.getInstance().getCurrentClient()?.url ??
"http://127.0.0.1:" + temp_port
);
url.protocol = "http";
url.port = temp_port.toString();
url.pathname = "/static/background_image.png";
viewerApi({ viewerApi({
options: { options: {
toolbar: true, toolbar: true,
@ -161,12 +172,12 @@ export default defineComponent({
}, },
images: [ images: [
{ {
src: "http://127.0.0.1:61429/static/default_background.png", src: url.toString(),
"data-source": "data-source": url.toString(),
"http://127.0.0.1:61429/static/default_background.png",
}, },
], ],
}); });
} catch {}
}, },
async onSubmit() { async onSubmit() {
if (file_count.value <= 0) { if (file_count.value <= 0) {

View File

@ -0,0 +1,223 @@
<template>
<q-dialog persistent v-model="show_dialog" @before-hide="resetData">
<q-card class="overflow-hidden" style="overflow-y: scroll; max-width: 60vw">
<q-form @submit="onSubmit">
<q-card-section class="q-ma-none q-pa-sm">
<div class="row">
<div class="col-auto text-h6">
{{ $t("clock") }}
</div>
<q-space />
<div>
<q-btn
:loading="loading"
flat
round
icon="close"
color="red"
v-close-popup
>
<q-tooltip>
{{ $t("close") }}
</q-tooltip>
</q-btn>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-section
style="max-height: 50vh; width: 55vw; height: 50vh"
class="scroll"
>
<q-list>
<q-item v-if="false">
<q-item-section avatar class="head_1">
{{ $t("font name") }}
</q-item-section>
<q-item-section>
<q-input v-model="clock_entity.font_name" />
</q-item-section>
</q-item>
<q-item>
<q-item-section avatar class="head_1">
{{ $t("font size") }}
</q-item-section>
<q-item-section>
<q-input v-model="clock_entity.font_size" type="number" />
</q-item-section>
<q-item-section avatar>
<q-checkbox
v-model="clock_entity.bold"
left-label
:label="$t('font bold')"
/>
</q-item-section>
</q-item>
<q-item>
<q-item-section avatar class="head_1">
{{ $t("font color") }}
</q-item-section>
<q-item-section>
<q-input
v-model="clock_entity.font_color"
:rules="['anyColor']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-color v-model="clock_entity.font_color" />
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</q-item-section>
</q-item>
<q-item>
<q-item-section avatar class="head_1">
{{ $t("background color") }}
</q-item-section>
<q-item-section>
<q-input
v-model="clock_entity.background_color"
:rules="['anyColor']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-color v-model="clock_entity.background_color" />
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</q-item-section>
<q-item-section avatar>
<q-checkbox
v-model="clock_entity.background_transparent"
left-label
:label="$t('background transparent')"
/>
</q-item-section>
</q-item>
</q-list>
</q-card-section>
<q-separator />
<q-card-actions>
<q-space />
<q-btn
:loading="loading"
flat
:label="$t('close and reset')"
color="primary"
v-close-popup
/>
<q-btn
ref="accept"
flat
:label="$t('close and save')"
:loading="loading"
type="submit"
color="primary"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
<file-manage-dialog ref="file_manage_dialog" />
</template>
<style scoped>
.head_1 {
width: 15%;
}
</style>
<script lang="ts">
import { defineComponent, ref, Ref, watch, computed } from "vue";
import { useStore } from "src/store";
import GlobalData from "src/common/GlobalData";
import { useQuasar } from "quasar";
import { useI18n } from "vue-i18n";
import ClockWindowParamEntity from "src/entities/ClockWindowParamEntity";
export default defineComponent({
name: "ComponentClockSignalSourceDialog",
components: {},
setup() {
let $store = useStore();
let $q = useQuasar();
let $t = useI18n();
let show_dialog = ref(false);
let loading = ref(false);
let clock_entity: Ref<ClockWindowParamEntity> = ref(
new ClockWindowParamEntity()
);
let _resolove: any = null;
const initialize_properties = (json: string) => {
if (json) {
try {
const temp = JSON.parse(json);
clock_entity.value = temp;
} catch {}
}
};
return {
show_dialog,
loading,
clock_entity,
showDialogAsync(options: any) {
if (_resolove) {
_resolove();
_resolove = null;
}
show_dialog.value = true;
initialize_properties(options);
return new Promise((resolove) => {
_resolove = resolove;
});
},
resetData() {
loading.value = false;
if (_resolove) {
_resolove();
_resolove = null;
}
},
async onSubmit() {
loading.value = true;
try {
if (_resolove) {
try {
clock_entity.value.font_size = parseInt(
clock_entity.value.font_size.toString()
);
_resolove(JSON.stringify(clock_entity.value));
} catch {
_resolove();
}
}
show_dialog.value = false;
} catch {}
loading.value = false;
},
};
},
});
</script>

View File

@ -144,6 +144,8 @@
media_url_label.startsWith($t('file path')) && media_url_label.startsWith($t('file path')) &&
item_data.window_type == 'EwindowType::Image' item_data.window_type == 'EwindowType::Image'
? doSelectFile() ? doSelectFile()
: item_data.window_type == 'EwindowType::Clock'
? showClockDialog()
: showPlaylistDialog() : showPlaylistDialog()
" "
v-model="item_data.media_url" v-model="item_data.media_url"
@ -264,6 +266,7 @@
</q-card> </q-card>
<playlist-dialog ref="playlist_dialog" /> <playlist-dialog ref="playlist_dialog" />
<file-manage-dialog ref="file_manage_dialog" /> <file-manage-dialog ref="file_manage_dialog" />
<clock-signal-source-dialog ref="clock_dialog" />
</q-dialog> </q-dialog>
</template> </template>
@ -292,11 +295,12 @@ import { useI18n } from "vue-i18n";
import { SignalSourceEntity } from "src/entities/SignalSourceEntity"; import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
import FileManageDialog from "src/components/FileManageDialog.vue"; import FileManageDialog from "src/components/FileManageDialog.vue";
import PlaylistDialog from "src/components/PlaylistDialog.vue"; import PlaylistDialog from "src/components/PlaylistDialog.vue";
import ClockSignalSourceDialog from "src/components/ClockSignalSourceDialog.vue";
import FileEntity from "src/entities/FileEntity"; import FileEntity from "src/entities/FileEntity";
export default defineComponent({ export default defineComponent({
name: "ComponentSignalSourceDialog", name: "ComponentSignalSourceDialog",
components: { FileManageDialog, PlaylistDialog }, components: { FileManageDialog, PlaylistDialog, ClockSignalSourceDialog },
setup() { setup() {
let $store = useStore(); let $store = useStore();
@ -311,6 +315,7 @@ export default defineComponent({
const selected: any = ref(null); const selected: any = ref(null);
let loading = ref(false); let loading = ref(false);
let playlist_dialog: any = ref(null); let playlist_dialog: any = ref(null);
let clock_dialog: any = ref(null);
let file_manage_dialog: any = ref(null); let file_manage_dialog: any = ref(null);
let suppored_window_types = new Set<string>([ let suppored_window_types = new Set<string>([
@ -318,6 +323,7 @@ export default defineComponent({
"EwindowType::Web", "EwindowType::Web",
"EwindowType::Image", "EwindowType::Image",
"EwindowType::Rtsp", "EwindowType::Rtsp",
"EwindowType::Clock",
]); ]);
let signal_source_options = [ let signal_source_options = [
@ -337,6 +343,10 @@ export default defineComponent({
label: $t.t("rtsp"), label: $t.t("rtsp"),
value: "EwindowType::Rtsp", value: "EwindowType::Rtsp",
}, },
{
label: $t.t("clock"),
value: "EwindowType::Clock",
},
]; ];
const tree_nodes = computed({ const tree_nodes = computed({
@ -426,6 +436,7 @@ export default defineComponent({
loading, loading,
tree_nodes, tree_nodes,
playlist_dialog, playlist_dialog,
clock_dialog,
file_manage_dialog, file_manage_dialog,
showDialog(options: any) { showDialog(options: any) {
if (options) { if (options) {
@ -471,6 +482,15 @@ export default defineComponent({
} catch {} } catch {}
loading.value = false; loading.value = false;
}, },
async showClockDialog() {
if (item_data.window_type != "EwindowType::Clock") {
return;
}
const result = await clock_dialog.value.showDialogAsync(
item_data.media_url
);
item_data.media_url = decodeURI(result);
},
async showPlaylistDialog() { async showPlaylistDialog() {
if (item_data.window_type != "EwindowType::Multimedia") { if (item_data.window_type != "EwindowType::Multimedia") {
return; return;

View File

@ -60,6 +60,7 @@
> >
<q-item-section> {{ $t("close all windwos") }} </q-item-section> <q-item-section> {{ $t("close all windwos") }} </q-item-section>
</q-item> </q-item>
<div v-if="!is_clock_window">
<q-item <q-item
clickable clickable
v-close-popup v-close-popup
@ -88,6 +89,7 @@
> >
<q-item-section> {{ $t("polling setting") }} </q-item-section> <q-item-section> {{ $t("polling setting") }} </q-item-section>
</q-item> </q-item>
</div>
</q-list> </q-list>
</q-popup-proxy> </q-popup-proxy>
<div class="row title_bar full-width"> <div class="row title_bar full-width">
@ -385,10 +387,15 @@ export default defineComponent({
window_type == "EwindowType::HdmiIn" window_type == "EwindowType::HdmiIn"
); );
}; };
const is_audo_player_window = computed(() => const is_audo_player_window = computed(() =>
calc_is_audio_player_window(signal_source.value.window_type) calc_is_audio_player_window(signal_source.value.window_type)
); );
const is_clock_window = computed(() => {
return signal_source.value.window_type == "EwindowType::Clock";
});
reload_signal_source(); reload_signal_source();
watch(props, (a, b) => { watch(props, (a, b) => {
reload_signal_source(); reload_signal_source();
@ -461,6 +468,7 @@ export default defineComponent({
can_resize, can_resize,
flags, flags,
is_audo_player_window, is_audo_player_window,
is_clock_window,
calc_is_audio_player_window, calc_is_audio_player_window,
onClick(evt: PointerEvent) { onClick(evt: PointerEvent) {

View File

@ -0,0 +1,10 @@
export default class ClockWindowParamEntity {
font_name = "Arial";
font_size = 9;
bold = false;
strike_out = false;
underline = false;
font_color = "#000000";
background_color = "#000000";
background_transparent = true;
}

View File

@ -1,5 +1,5 @@
export namespace HttpProtocol { export namespace HttpProtocol {
export const DefaultHttpPort = 61429; export const DefaultHttpPort = 80;
export const RequestUploadFile = "/upload_file"; export const RequestUploadFile = "/upload_file";
export const RequestPathUpdateDBBackupFile = "/common/update_db_backup_file"; export const RequestPathUpdateDBBackupFile = "/common/update_db_backup_file";
export const RequestPathDBBackup = "/db_backup"; export const RequestPathDBBackup = "/db_backup";

View File

@ -60,12 +60,12 @@ export default {
"multimedia file": "多媒体文件", "multimedia file": "多媒体文件",
Web: "网页", Web: "网页",
image: "图片", image: "图片",
rtsp: "RTSP视频流", rtsp: "网络视频",
"media url": "媒体 RUL", "media url": "媒体 RUL",
"please input media url": "请输入媒体 RUL", "please input media url": "请输入媒体 RUL",
"please input": "请输入", "please input": "请输入",
"http url": "HTTP超链接", "http url": "HTTP超链接",
"RTSP url": "RTSP链接", "RTSP url": "网络地址",
"file path": "文件路径", "file path": "文件路径",
"wall row": "行", "wall row": "行",
@ -308,4 +308,10 @@ export default {
"unmuted now": "现在没有静音", "unmuted now": "现在没有静音",
"polling now": "正在轮询窗口", "polling now": "正在轮询窗口",
"running now": "正在运行", "running now": "正在运行",
clock: "时钟",
"font bold": "字体加粗",
"font size": "字体大小",
"font name": "字体",
"font color": "字体颜色",
"new signal source": "新建信号源",
}; };

693
yarn.lock

File diff suppressed because it is too large Load Diff