添加替换窗口
This commit is contained in:
parent
c2268af842
commit
8f0abc20e3
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "media_player_client",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"description": "A Quasar Framework app",
|
||||
"productName": "MediaPlayerClient",
|
||||
"author": "fangxiang <fangxiang@cloudview.work>",
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
>
|
||||
<q-card-section class="q-ma-none q-pa-sm">
|
||||
<div class="row">
|
||||
<div class="col-auto text-h6">
|
||||
<div v-if="status == 'select'" class="col-auto text-h6">
|
||||
{{ $t("select file") }}({{ filters.join(";") }})
|
||||
</div>
|
||||
<div v-else class="col-auto text-h6">
|
||||
{{ $t("file manage") }}
|
||||
</div>
|
||||
<q-space />
|
||||
|
@ -321,7 +324,7 @@ a:hover {
|
|||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, watch, computed } from "vue";
|
||||
import { defineComponent, ref, Ref, watch, computed } from "vue";
|
||||
import { useStore } from "src/store";
|
||||
import { useQuasar, date, copyToClipboard } from "quasar";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
@ -370,6 +373,7 @@ export default defineComponent({
|
|||
let uploader: any = ref(null);
|
||||
let resolve: any = null;
|
||||
let resolve_value: any = null;
|
||||
const filters: Ref<string[]> = ref([]);
|
||||
|
||||
const disk_options = ref([
|
||||
{
|
||||
|
@ -459,9 +463,27 @@ export default defineComponent({
|
|||
const _show_files = (response: any) => {
|
||||
if (response) {
|
||||
if (response.status == 200) {
|
||||
const file_entity = response.data as FileEntity[];
|
||||
if (file_entity) {
|
||||
files.value = file_entity;
|
||||
const file_entitys = response.data as FileEntity[];
|
||||
if (Array.isArray(file_entitys)) {
|
||||
if (filters.value.length == 0) {
|
||||
files.value = file_entitys;
|
||||
} else {
|
||||
files.value = [];
|
||||
for (const item of file_entitys) {
|
||||
if (item) {
|
||||
if (item.is_directory) {
|
||||
files.value.push(item);
|
||||
} else {
|
||||
for (const filter of filters.value) {
|
||||
if (item.name.endsWith(filter)) {
|
||||
files.value.push(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("data is not typeof FileEntity!", response);
|
||||
}
|
||||
|
@ -481,6 +503,18 @@ export default defineComponent({
|
|||
refresh_file_list_async();
|
||||
};
|
||||
|
||||
const parseFilter = (filter?: string) => {
|
||||
filters.value = [];
|
||||
|
||||
if (filter) {
|
||||
for (const item of filter.split(";")) {
|
||||
if (item && item.length > 0) {
|
||||
filters.value.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const selectFile = async (file: FileEntity) => {
|
||||
resolve_value = {
|
||||
file,
|
||||
|
@ -528,6 +562,10 @@ export default defineComponent({
|
|||
() => status.value,
|
||||
(newValue: string) => {
|
||||
switch (newValue) {
|
||||
case undefined:
|
||||
case null:
|
||||
status.value = "normal";
|
||||
break;
|
||||
case "normal":
|
||||
case "select":
|
||||
break;
|
||||
|
@ -594,16 +632,20 @@ export default defineComponent({
|
|||
refresh_file_list,
|
||||
refresh_file_list_async,
|
||||
status,
|
||||
async showDialog(in_status: string) {
|
||||
filters,
|
||||
async showDialog(in_status: string, filter?: string) {
|
||||
status.value = in_status;
|
||||
parseFilter(filter);
|
||||
refresh_usb_devices();
|
||||
refresh_file_list();
|
||||
|
||||
show_dialog.value = true;
|
||||
},
|
||||
showDialogAsync(in_status: string) {
|
||||
showDialogAsync(in_status: string, filter?: string) {
|
||||
console.log(filter);
|
||||
return new Promise((_resolve, _reject) => {
|
||||
status.value = in_status;
|
||||
parseFilter(filter);
|
||||
refresh_usb_devices();
|
||||
refresh_file_list();
|
||||
show_dialog.value = true;
|
||||
|
|
|
@ -188,7 +188,10 @@ export default defineComponent({
|
|||
|
||||
const doSelectFile = async () => {
|
||||
let result = "";
|
||||
const obj = await file_manage_dialog.value.showDialogAsync("select");
|
||||
const obj = await file_manage_dialog.value.showDialogAsync(
|
||||
"select",
|
||||
filter
|
||||
);
|
||||
if (obj) {
|
||||
interface __I {
|
||||
path: string;
|
||||
|
@ -210,6 +213,8 @@ export default defineComponent({
|
|||
}
|
||||
};
|
||||
|
||||
let filter: string | undefined = "";
|
||||
|
||||
return {
|
||||
show_dialog,
|
||||
loading,
|
||||
|
@ -218,16 +223,17 @@ export default defineComponent({
|
|||
|
||||
addRow,
|
||||
|
||||
showDialogAsync(options: any) {
|
||||
showDialogAsync(options: any, _filter?: string) {
|
||||
if (_resolove) {
|
||||
_resolove();
|
||||
_resolove = null;
|
||||
}
|
||||
show_dialog.value = true;
|
||||
filter = _filter;
|
||||
initialize_properties(options);
|
||||
if (play_list.value.length == 0) {
|
||||
addRow();
|
||||
}
|
||||
show_dialog.value = true;
|
||||
return new Promise((resolove) => {
|
||||
_resolove = resolove;
|
||||
});
|
||||
|
|
|
@ -154,10 +154,10 @@
|
|||
@dblclick="
|
||||
media_url_label.startsWith($t('file path')) &&
|
||||
item_data.window_type == 'EwindowType::Image'
|
||||
? doSelectFile()
|
||||
? doSelectFile('.jpg;.png')
|
||||
: item_data.window_type == 'EwindowType::Clock'
|
||||
? showClockDialog()
|
||||
: showPlaylistDialog()
|
||||
: showPlaylistDialog('.mp4;.avi;.ts;')
|
||||
"
|
||||
v-model="item_data.media_url"
|
||||
:readonly="media_url_label.startsWith($t('file path'))"
|
||||
|
@ -502,12 +502,13 @@ export default defineComponent({
|
|||
);
|
||||
item_data.media_url = decodeURI(result);
|
||||
},
|
||||
async showPlaylistDialog() {
|
||||
async showPlaylistDialog(filter: string) {
|
||||
if (item_data.window_type != "EwindowType::Multimedia") {
|
||||
return;
|
||||
}
|
||||
const result = await playlist_dialog.value.showDialogAsync(
|
||||
item_data.media_url
|
||||
item_data.media_url,
|
||||
filter
|
||||
);
|
||||
if (Array.isArray(result)) {
|
||||
if (result.length) {
|
||||
|
@ -535,11 +536,14 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
},
|
||||
async doSelectFile() {
|
||||
async doSelectFile(filter: string) {
|
||||
if (!media_url_label.value.startsWith($t.t("file path"))) {
|
||||
return;
|
||||
}
|
||||
const obj = await file_manage_dialog.value.showDialogAsync("select");
|
||||
const obj = await file_manage_dialog.value.showDialogAsync(
|
||||
"select",
|
||||
filter
|
||||
);
|
||||
if (obj) {
|
||||
interface __I {
|
||||
path: string;
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
{{ $props.window.muted ? $t("unmute") : $t("mute") }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
:disable="$props.disable"
|
||||
@click="$emit('replace_this_window', $props.window.window_id)"
|
||||
>
|
||||
<q-item-section> {{ $t("replace window") }} </q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
v-close-popup
|
||||
|
@ -254,6 +262,7 @@ export default defineComponent({
|
|||
"close_this_window",
|
||||
"close_other_windows",
|
||||
"close_all_windows",
|
||||
"replace_this_window",
|
||||
"top_window",
|
||||
"lower_window",
|
||||
"edit_volume",
|
||||
|
|
|
@ -801,6 +801,7 @@ export namespace Protocol {
|
|||
|
||||
export class AddSignalSourceResponseEntity extends Protocol.PacketEntity {
|
||||
success = false;
|
||||
uuid: string = "";
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
|
|
@ -348,4 +348,6 @@ export default {
|
|||
HH: "时",
|
||||
MM: "分",
|
||||
SS: "秒",
|
||||
"open window": "开窗",
|
||||
"replace window": "替换窗口",
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
@close_this_window="closeWindow"
|
||||
@close_other_windows="closeOtherWindows"
|
||||
@close_all_windows="closeAllWindows"
|
||||
@replace_this_window="repliceWindow"
|
||||
@top_window="topWindow"
|
||||
@lower_window="lowerWindow"
|
||||
@dblclick="(evt) => windowDBClick(item.window_id)"
|
||||
|
@ -78,9 +79,27 @@
|
|||
height: item_height + 'px',
|
||||
}"
|
||||
>
|
||||
<q-popup-proxy context-menu>
|
||||
<q-popup-proxy context-menu />
|
||||
<q-popup-proxy
|
||||
context-menu
|
||||
@show="
|
||||
{
|
||||
last_context_menu_pos_x = $event.layerX;
|
||||
last_context_menu_pos_y = $event.layerY;
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-list>
|
||||
<q-item
|
||||
:disable="plan_running"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="openWindowByLocalFile($event)"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon name="open_in_browser" />
|
||||
</q-item-section>
|
||||
<q-item-section> {{ $t("open window") }} </q-item-section>
|
||||
</q-item>
|
||||
<q-item
|
||||
:disable="plan_running"
|
||||
clickable
|
||||
|
@ -119,6 +138,7 @@
|
|||
></div>
|
||||
<edit-volume-dialog ref="edit_volume_dialog" />
|
||||
<polling-setting-dialog ref="polling_setting_dialog" />
|
||||
<file-manage-dialog ref="file_manage_dialog" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -163,6 +183,10 @@ import PollingSettingDialog from "src/components/PollingSettingDialog.vue";
|
|||
|
||||
import vue3ResizeDrag from "../third_lib/vue3-resize-drag/components/vue3-resize-drag/index.vue";
|
||||
|
||||
import FileManageDialog from "src/components/FileManageDialog.vue";
|
||||
import FileEntity from "src/entities/FileEntity";
|
||||
import { SignalSourceEntity } from "src/entities/SignalSourceEntity";
|
||||
|
||||
class Rect {
|
||||
start_x = 0;
|
||||
start_y = 0;
|
||||
|
@ -185,6 +209,7 @@ export default defineComponent({
|
|||
Window,
|
||||
EditVolumeDialog,
|
||||
PollingSettingDialog,
|
||||
FileManageDialog,
|
||||
},
|
||||
setup() {
|
||||
const $q = useQuasar();
|
||||
|
@ -193,6 +218,10 @@ export default defineComponent({
|
|||
|
||||
const edit_volume_dialog: Ref<any> = ref(null);
|
||||
const polling_setting_dialog: Ref<any> = ref(null);
|
||||
const file_manage_dialog: Ref<any> = ref(null);
|
||||
|
||||
const last_context_menu_pos_x = ref(0);
|
||||
const last_context_menu_pos_y = ref(0);
|
||||
|
||||
const plan_running = computed(
|
||||
() => $store.state.current_running_plan.trim() != ""
|
||||
|
@ -647,8 +676,14 @@ export default defineComponent({
|
|||
plan_running,
|
||||
edit_volume_dialog,
|
||||
polling_setting_dialog,
|
||||
file_manage_dialog,
|
||||
area_open_window_rect,
|
||||
area_open_window_flag,
|
||||
last_context_menu_pos_x,
|
||||
last_context_menu_pos_y,
|
||||
loga(a: any) {
|
||||
console.log(a);
|
||||
},
|
||||
onDrop(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
let target = e.target as any;
|
||||
|
@ -927,6 +962,175 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
},
|
||||
async openWindowByLocalFile(event: MouseEvent) {
|
||||
if (!wall.value) {
|
||||
return;
|
||||
}
|
||||
const obj = await file_manage_dialog.value.showDialogAsync(
|
||||
"select",
|
||||
".mp4;.avi;.ts;.jpg;.png;"
|
||||
);
|
||||
if (obj) {
|
||||
interface __I {
|
||||
path: string;
|
||||
file: FileEntity;
|
||||
}
|
||||
let { path, file }: __I = obj;
|
||||
if (path && file) {
|
||||
const full_path = (path + "/" + file.name).replace(/\\/g, "/");
|
||||
const entity: SignalSourceEntity = new SignalSourceEntity();
|
||||
if (
|
||||
file.name.endsWith("mp4") ||
|
||||
file.name.endsWith("avi") ||
|
||||
file.name.endsWith("ts")
|
||||
) {
|
||||
entity.window_type = "EwindowType::Multimedia";
|
||||
entity.media_url = JSON.stringify([full_path]);
|
||||
} else {
|
||||
entity.window_type = "EwindowType::Image";
|
||||
entity.media_url = full_path;
|
||||
}
|
||||
entity.name = file.name;
|
||||
entity.local_file_flag = true;
|
||||
entity.group_uuid = "";
|
||||
try {
|
||||
const response = await GlobalData.getInstance()
|
||||
.getCurrentClient()
|
||||
?.addSignalSource(entity);
|
||||
if (response && response.success) {
|
||||
const cell_width = 1.0 / $store.state.wall_col;
|
||||
const cell_height = 1.0 / $store.state.wall_row;
|
||||
|
||||
const x =
|
||||
parseInt(
|
||||
(
|
||||
last_context_menu_pos_x.value /
|
||||
wall.value.offsetWidth /
|
||||
cell_width
|
||||
).toFixed(0)
|
||||
) * cell_width;
|
||||
const y =
|
||||
parseInt(
|
||||
(
|
||||
last_context_menu_pos_y.value /
|
||||
wall.value.offsetHeight /
|
||||
cell_height
|
||||
).toFixed(0)
|
||||
) * cell_height;
|
||||
|
||||
if (!isNaN(x) && !isNaN(y)) {
|
||||
const open_window_request =
|
||||
new Protocol.OpenWindowRequestEntity(
|
||||
response.uuid,
|
||||
x,
|
||||
y,
|
||||
cell_width,
|
||||
cell_height
|
||||
);
|
||||
|
||||
GlobalData.getInstance()
|
||||
.getCurrentClient()
|
||||
?.openWindow(open_window_request);
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
},
|
||||
async repliceWindow(window_id: number) {
|
||||
if (!wall.value) {
|
||||
return;
|
||||
}
|
||||
const old_window = $store.state.windows.find(
|
||||
(element) => element && element.window_id == window_id
|
||||
);
|
||||
if (old_window) {
|
||||
const old_signal_source = GlobalData.getInstance().signal_source.find(
|
||||
(element) =>
|
||||
element && element.uuid == old_window.signal_source_table_uuid
|
||||
);
|
||||
if (old_signal_source) {
|
||||
const obj = await file_manage_dialog.value.showDialogAsync(
|
||||
"select",
|
||||
".mp4;.avi;.ts;.jpg;.png;"
|
||||
);
|
||||
if (obj) {
|
||||
interface __I {
|
||||
path: string;
|
||||
file: FileEntity;
|
||||
}
|
||||
let { path, file }: __I = obj;
|
||||
if (path && file) {
|
||||
const full_path = (path + "/" + file.name).replace(/\\/g, "/");
|
||||
const entity: SignalSourceEntity = new SignalSourceEntity();
|
||||
if (
|
||||
file.name.endsWith("mp4") ||
|
||||
file.name.endsWith("avi") ||
|
||||
file.name.endsWith("ts")
|
||||
) {
|
||||
entity.window_type = "EwindowType::Multimedia";
|
||||
entity.media_url = JSON.stringify([full_path]);
|
||||
} else {
|
||||
entity.window_type = "EwindowType::Image";
|
||||
entity.media_url = full_path;
|
||||
}
|
||||
entity.name = file.name;
|
||||
entity.local_file_flag = true;
|
||||
entity.group_uuid = "";
|
||||
try {
|
||||
const response = await GlobalData.getInstance()
|
||||
.getCurrentClient()
|
||||
?.addSignalSource(entity);
|
||||
if (response && response.success) {
|
||||
const cell_width = 1.0 / $store.state.wall_col;
|
||||
const cell_height = 1.0 / $store.state.wall_row;
|
||||
|
||||
const x =
|
||||
parseInt(
|
||||
(
|
||||
last_context_menu_pos_x.value /
|
||||
wall.value.offsetWidth /
|
||||
cell_width
|
||||
).toFixed(0)
|
||||
) * cell_width;
|
||||
const y =
|
||||
parseInt(
|
||||
(
|
||||
last_context_menu_pos_y.value /
|
||||
wall.value.offsetHeight /
|
||||
cell_height
|
||||
).toFixed(0)
|
||||
) * cell_height;
|
||||
|
||||
if (!isNaN(x) && !isNaN(y)) {
|
||||
const open_window_request =
|
||||
new Protocol.OpenWindowRequestEntity(
|
||||
response.uuid,
|
||||
old_window.x,
|
||||
old_window.y,
|
||||
old_window.width,
|
||||
old_window.height
|
||||
);
|
||||
open_window_request.muted = old_window.muted;
|
||||
open_window_request.volume = old_window.volume;
|
||||
open_window_request.paused = !old_window.playing;
|
||||
open_window_request.play_speed = old_window.play_speed;
|
||||
|
||||
GlobalData.getInstance()
|
||||
.getCurrentClient()
|
||||
?.closeWindow(old_window.window_id);
|
||||
|
||||
GlobalData.getInstance()
|
||||
.getCurrentClient()
|
||||
?.openWindow(open_window_request);
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue