Update RemoteDesktopModal.vue
This commit is contained in:
@@ -15,23 +15,26 @@ const props = defineProps<{
|
|||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
const rdpDisplayRef = ref<HTMLDivElement | null>(null);
|
const rdpDisplayRef = ref<HTMLDivElement | null>(null);
|
||||||
|
const rdpContainerRef = ref<HTMLDivElement | null>(null); // Added ref for the container
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const guacClient = ref<any | null>(null);
|
const guacClient = ref<any | null>(null);
|
||||||
const connectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected');
|
const connectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected');
|
||||||
const statusMessage = ref('');
|
const statusMessage = ref('');
|
||||||
const keyboard = ref<any | null>(null);
|
const keyboard = ref<any | null>(null);
|
||||||
const mouse = ref<any | null>(null);
|
const mouse = ref<any | null>(null);
|
||||||
const inputWidth = ref(1024);
|
// const inputWidth = ref(1024); // Removed, size determined by container
|
||||||
const inputHeight = ref(768);
|
// const inputHeight = ref(768); // Removed, size determined by container
|
||||||
// const modalStyle = ref({}); // Replaced by computedModalStyle
|
// const modalStyle = ref({}); // Replaced by computedModalStyle
|
||||||
const rdpContainerStyle = ref<{ height?: string }>({}); // Only height is needed now
|
// const rdpContainerStyle = ref<{ height?: string }>({}); // Removed, size determined by flex-1
|
||||||
const modalWidth = ref(1064); // Initial default based on 1024 + padding
|
const desiredModalWidth = ref(1064); // User sets the desired TOTAL modal width (1024 + 40 padding)
|
||||||
const modalHeight = ref(858); // Initial default based on 768 + padding
|
const desiredModalHeight = ref(858); // User sets the desired TOTAL modal height (768 + chrome)
|
||||||
|
|
||||||
const RDP_BACKEND_API_BASE = 'http://localhost:9090';
|
const RDP_BACKEND_API_BASE = 'http://localhost:9090';
|
||||||
const RDP_BACKEND_WEBSOCKET_URL = 'ws://localhost:8081';
|
const RDP_BACKEND_WEBSOCKET_URL = 'ws://localhost:8081';
|
||||||
|
const LOCAL_STORAGE_MODAL_WIDTH_KEY = 'rdpModalWidth'; // Reverted key name
|
||||||
|
const LOCAL_STORAGE_MODAL_HEIGHT_KEY = 'rdpModalHeight'; // Reverted key name
|
||||||
|
|
||||||
const connectRdp = async (useInputValues = false) => {
|
const connectRdp = async () => { // Removed useInputValues parameter
|
||||||
if (!props.connection || !rdpDisplayRef.value) {
|
if (!props.connection || !rdpDisplayRef.value) {
|
||||||
statusMessage.value = t('remoteDesktopModal.errors.missingInfo');
|
statusMessage.value = t('remoteDesktopModal.errors.missingInfo');
|
||||||
connectionStatus.value = 'error';
|
connectionStatus.value = 'error';
|
||||||
@@ -57,39 +60,26 @@ const connectRdp = async (useInputValues = false) => {
|
|||||||
}
|
}
|
||||||
statusMessage.value = t('remoteDesktopModal.status.connectingWs');
|
statusMessage.value = t('remoteDesktopModal.status.connectingWs');
|
||||||
|
|
||||||
let widthToSend = 1024;
|
// Get RDP container dimensions after DOM update
|
||||||
let heightToSend = 768;
|
await nextTick();
|
||||||
|
|
||||||
|
let widthToSend = 800; // Default/fallback width
|
||||||
|
let heightToSend = 600; // Default/fallback height
|
||||||
const dpiToSend = 96;
|
const dpiToSend = 96;
|
||||||
|
|
||||||
if (useInputValues) {
|
if (rdpContainerRef.value) {
|
||||||
widthToSend = parseInt(String(inputWidth.value), 10) || widthToSend;
|
// Use clientWidth/clientHeight as they represent the inner dimensions available for content
|
||||||
heightToSend = parseInt(String(inputHeight.value), 10) || heightToSend;
|
widthToSend = rdpContainerRef.value.clientWidth;
|
||||||
|
heightToSend = rdpContainerRef.value.clientHeight + 1; // Subtract 1 based on feedback
|
||||||
|
// Ensure minimum dimensions, adjust if necessary based on backend requirements
|
||||||
|
widthToSend = Math.max(100, widthToSend);
|
||||||
|
heightToSend = Math.max(100, heightToSend);
|
||||||
|
console.log(`Calculated RDP dimensions: ${widthToSend}x${heightToSend}`);
|
||||||
} else {
|
} else {
|
||||||
if (rdpDisplayRef.value && rdpDisplayRef.value.clientWidth > 0 && rdpDisplayRef.value.clientHeight > 0) {
|
console.warn("RDP container ref not available to get dimensions. Using defaults.");
|
||||||
widthToSend = rdpDisplayRef.value.clientWidth;
|
// Consider setting an error state or notifying the user
|
||||||
heightToSend = rdpDisplayRef.value.clientHeight;
|
|
||||||
} else {
|
|
||||||
widthToSend = parseInt(String(inputWidth.value), 10) || widthToSend;
|
|
||||||
heightToSend = parseInt(String(inputHeight.value), 10) || heightToSend;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inputWidth.value = widthToSend;
|
|
||||||
inputHeight.value = heightToSend;
|
|
||||||
|
|
||||||
const extraWidth = 40;
|
|
||||||
const headerHeight = 45;
|
|
||||||
const footerHeight = 35;
|
|
||||||
|
|
||||||
// Update modal size refs based on RDP size + padding
|
|
||||||
modalWidth.value = widthToSend + extraWidth;
|
|
||||||
modalHeight.value = heightToSend + headerHeight + footerHeight + 10;
|
|
||||||
|
|
||||||
rdpContainerStyle.value = {
|
|
||||||
// width: `${widthToSend}px`, // Remove width setting
|
|
||||||
height: `${heightToSend}px`,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tunnelUrl = `${RDP_BACKEND_WEBSOCKET_URL}/?token=${encodeURIComponent(token)}&width=${widthToSend}&height=${heightToSend}&dpi=${dpiToSend}`;
|
const tunnelUrl = `${RDP_BACKEND_WEBSOCKET_URL}/?token=${encodeURIComponent(token)}&width=${widthToSend}&height=${heightToSend}&dpi=${dpiToSend}`;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const tunnel = new Guacamole.WebSocketTunnel(tunnelUrl);
|
const tunnel = new Guacamole.WebSocketTunnel(tunnelUrl);
|
||||||
@@ -214,7 +204,10 @@ const removeInputListeners = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Removed stopResizeObserver as ResizeObserver is no longer used
|
||||||
|
|
||||||
const disconnectRdp = () => {
|
const disconnectRdp = () => {
|
||||||
|
// stopResizeObserver(); // Removed
|
||||||
removeInputListeners();
|
removeInputListeners();
|
||||||
if (guacClient.value) {
|
if (guacClient.value) {
|
||||||
guacClient.value.disconnect();
|
guacClient.value.disconnect();
|
||||||
@@ -232,40 +225,44 @@ const disconnectRdp = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const reconnectWithNewSize = () => {
|
// Removed reconnectWithNewSize function
|
||||||
const width = parseInt(String(inputWidth.value), 10);
|
|
||||||
const height = parseInt(String(inputHeight.value), 10);
|
|
||||||
if (!width || width <= 0 || !height || height <= 0) {
|
|
||||||
statusMessage.value = t('remoteDesktopModal.errors.invalidSize');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
disconnectRdp();
|
|
||||||
nextTick(() => {
|
|
||||||
connectRdp(true);
|
|
||||||
|
|
||||||
const headerHeight = 45;
|
|
||||||
const footerHeight = 35;
|
|
||||||
const extraWidth = 40;
|
|
||||||
|
|
||||||
rdpContainerStyle.value = {
|
|
||||||
// width: `${width}px`, // Remove width setting
|
|
||||||
height: `${height}px`,
|
|
||||||
};
|
|
||||||
// Update modal size refs based on new RDP size + padding
|
|
||||||
modalWidth.value = width + extraWidth;
|
|
||||||
modalHeight.value = height + headerHeight + footerHeight + 10;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
disconnectRdp();
|
disconnectRdp();
|
||||||
emit('close');
|
emit('close');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Removed setupResizeObserver as ResizeObserver is no longer used
|
||||||
|
|
||||||
|
|
||||||
|
// Load desired MODAL size from localStorage on mount
|
||||||
|
const loadDesiredModalSize = () => {
|
||||||
|
const savedWidth = localStorage.getItem(LOCAL_STORAGE_MODAL_WIDTH_KEY);
|
||||||
|
const savedHeight = localStorage.getItem(LOCAL_STORAGE_MODAL_HEIGHT_KEY);
|
||||||
|
if (savedWidth) {
|
||||||
|
desiredModalWidth.value = parseInt(savedWidth, 10) || desiredModalWidth.value;
|
||||||
|
}
|
||||||
|
if (savedHeight) {
|
||||||
|
desiredModalHeight.value = parseInt(savedHeight, 10) || desiredModalHeight.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save desired MODAL size to localStorage when changed
|
||||||
|
watch(desiredModalWidth, (newWidth) => {
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_MODAL_WIDTH_KEY, String(newWidth));
|
||||||
|
});
|
||||||
|
watch(desiredModalHeight, (newHeight) => {
|
||||||
|
localStorage.setItem(LOCAL_STORAGE_MODAL_HEIGHT_KEY, String(newHeight));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
loadDesiredModalSize(); // Load saved size first
|
||||||
|
|
||||||
if (props.connection) {
|
if (props.connection) {
|
||||||
nextTick(() => {
|
nextTick(async () => {
|
||||||
connectRdp(false);
|
await connectRdp(); // Connect using initial size
|
||||||
|
// No need to setup observer anymore
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
statusMessage.value = t('remoteDesktopModal.errors.noConnection');
|
statusMessage.value = t('remoteDesktopModal.errors.noConnection');
|
||||||
@@ -274,13 +271,14 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
disconnectRdp();
|
disconnectRdp(); // This already calls stopResizeObserver
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.connection, (newConnection, oldConnection) => {
|
watch(() => props.connection, (newConnection, oldConnection) => {
|
||||||
if (newConnection && newConnection.id !== oldConnection?.id) {
|
if (newConnection && newConnection.id !== oldConnection?.id) {
|
||||||
nextTick(() => {
|
nextTick(async () => {
|
||||||
connectRdp(false);
|
await connectRdp(); // Connect using initial size
|
||||||
|
// No need to setup observer anymore
|
||||||
});
|
});
|
||||||
} else if (!newConnection) {
|
} else if (!newConnection) {
|
||||||
disconnectRdp();
|
disconnectRdp();
|
||||||
@@ -289,10 +287,18 @@ watch(() => props.connection, (newConnection, oldConnection) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const computedModalStyle = computed(() => ({
|
// Use the desired modal size directly for the style
|
||||||
width: `${modalWidth.value}px`,
|
const computedModalStyle = computed(() => {
|
||||||
height: `${modalHeight.value}px`,
|
// const extraWidth = 40; // Removed from here as well
|
||||||
}));
|
// const headerHeight = 45; // Defined in connectRdp
|
||||||
|
// const footerHeight = 35; // Defined in connectRdp
|
||||||
|
// const extraHeight = headerHeight + footerHeight + 10; // Defined in connectRdp
|
||||||
|
|
||||||
|
return {
|
||||||
|
width: `${desiredModalWidth.value}px`, // Width is direct
|
||||||
|
height: `${desiredModalHeight.value}px`, // Height is direct
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@@ -326,7 +332,7 @@ const computedModalStyle = computed(() => ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative bg-black overflow-hidden flex-1" :style="rdpContainerStyle">
|
<div ref="rdpContainerRef" class="relative bg-black overflow-hidden flex-1">
|
||||||
<div ref="rdpDisplayRef" class="rdp-display-container w-full h-full">
|
<div ref="rdpDisplayRef" class="rdp-display-container w-full h-full">
|
||||||
</div>
|
</div>
|
||||||
<div v-if="connectionStatus === 'connecting' || connectionStatus === 'error'"
|
<div v-if="connectionStatus === 'connecting' || connectionStatus === 'error'"
|
||||||
@@ -336,7 +342,7 @@ const computedModalStyle = computed(() => ({
|
|||||||
<i v-else class="fas fa-exclamation-triangle fa-2x mb-3 text-red-400"></i>
|
<i v-else class="fas fa-exclamation-triangle fa-2x mb-3 text-red-400"></i>
|
||||||
<p class="text-sm">{{ statusMessage }}</p>
|
<p class="text-sm">{{ statusMessage }}</p>
|
||||||
<button v-if="connectionStatus === 'error'"
|
<button v-if="connectionStatus === 'error'"
|
||||||
@click="() => connectRdp(false)"
|
@click="() => connectRdp()"
|
||||||
class="mt-4 px-3 py-1 bg-primary text-white rounded text-xs hover:bg-primary-dark">
|
class="mt-4 px-3 py-1 bg-primary text-white rounded text-xs hover:bg-primary-dark">
|
||||||
{{ t('common.retry') }}
|
{{ t('common.retry') }}
|
||||||
</button>
|
</button>
|
||||||
@@ -347,56 +353,26 @@ const computedModalStyle = computed(() => ({
|
|||||||
<div class="p-2 border-t border-border flex-shrink-0 text-xs text-text-secondary bg-header flex items-center justify-between">
|
<div class="p-2 border-t border-border flex-shrink-0 text-xs text-text-secondary bg-header flex items-center justify-between">
|
||||||
<span>{{ statusMessage }}</span>
|
<span>{{ statusMessage }}</span>
|
||||||
<div class="flex items-center space-x-2 flex-wrap gap-y-1">
|
<div class="flex items-center space-x-2 flex-wrap gap-y-1">
|
||||||
<label for="modal-width" class="text-xs ml-2">Modal W:</label>
|
<label for="modal-width" class="text-xs ml-2">Modal W:</label> <!-- Changed label back -->
|
||||||
<input
|
<input
|
||||||
id="modal-width"
|
id="modal-width"
|
||||||
type="number"
|
type="number"
|
||||||
v-model="modalWidth"
|
v-model="desiredModalWidth"
|
||||||
min="200"
|
min="200"
|
||||||
step="10"
|
step="10"
|
||||||
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
||||||
/>
|
/>
|
||||||
<label for="modal-height" class="text-xs">Modal H:</label>
|
<label for="modal-height" class="text-xs">Modal H:</label> <!-- Changed label back -->
|
||||||
<input
|
<input
|
||||||
id="modal-height"
|
id="modal-height"
|
||||||
type="number"
|
type="number"
|
||||||
v-model="modalHeight"
|
v-model="desiredModalHeight"
|
||||||
min="200"
|
min="200"
|
||||||
step="10"
|
step="10"
|
||||||
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span class="border-l border-border h-4 mx-2"></span>
|
<!-- RDP Width/Height inputs and Reconnect button removed -->
|
||||||
|
|
||||||
<label for="rdp-width" class="text-xs">RDP W:</label>
|
|
||||||
<input
|
|
||||||
id="rdp-width"
|
|
||||||
type="number"
|
|
||||||
v-model="inputWidth"
|
|
||||||
min="100"
|
|
||||||
step="10"
|
|
||||||
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
||||||
@keyup.enter="reconnectWithNewSize"
|
|
||||||
/>
|
|
||||||
<label for="rdp-height" class="text-xs">H:</label>
|
|
||||||
<input
|
|
||||||
id="rdp-height"
|
|
||||||
type="number"
|
|
||||||
v-model="inputHeight"
|
|
||||||
min="100"
|
|
||||||
step="10"
|
|
||||||
class="w-16 px-1 py-0.5 text-xs border border-border rounded bg-input text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
||||||
@keyup.enter="reconnectWithNewSize"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
@click="reconnectWithNewSize"
|
|
||||||
:disabled="connectionStatus === 'connecting'"
|
|
||||||
class="px-2 py-0.5 text-xs bg-primary text-white rounded hover:bg-primary-dark disabled:opacity-50 disabled:cursor-not-allowed"
|
|
||||||
:title="t('remoteDesktopModal.reconnectTooltip')"
|
|
||||||
>
|
|
||||||
<i class="fas fa-sync-alt mr-1"></i>
|
|
||||||
{{ t('remoteDesktopModal.reconnect') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user