More fixes
All checks were successful
Deploy SingleChat / deploy (push) Successful in 23s

This commit is contained in:
Torsten Schulz (local)
2026-06-17 15:44:22 +02:00
parent 5d4129b5b3
commit c46e64367d
3 changed files with 73 additions and 4 deletions

View File

@@ -39,6 +39,13 @@
</button>
</div>
</footer>
<button
type="button"
class="floating-video-resize-handle"
title="Fenstergröße ändern"
@mousedown.stop.prevent="startResize"
></button>
</div>
</template>
@@ -53,7 +60,8 @@ const selfVideoRef = ref(null);
const windowStyle = computed(() => ({
left: `${chatStore.floatingVideoPosition.x}px`,
top: `${chatStore.floatingVideoPosition.y}px`
top: `${chatStore.floatingVideoPosition.y}px`,
width: `${chatStore.floatingVideoSize.width}px`
}));
watch(
@@ -100,6 +108,29 @@ function startDrag(event) {
window.addEventListener('mouseup', handleUp);
}
function startResize(event) {
const startX = event.clientX;
const startY = event.clientY;
const startWidth = chatStore.floatingVideoSize.width;
const measuredHeight = event.currentTarget?.closest('.floating-video-window')?.offsetHeight || 0;
const startHeight = chatStore.floatingVideoSize.height || measuredHeight;
const handleMove = (moveEvent) => {
chatStore.updateFloatingVideoSize({
width: startWidth + (moveEvent.clientX - startX),
height: startHeight + (moveEvent.clientY - startY)
});
};
const handleUp = () => {
window.removeEventListener('mousemove', handleMove);
window.removeEventListener('mouseup', handleUp);
};
window.addEventListener('mousemove', handleMove);
window.addEventListener('mouseup', handleUp);
}
onBeforeUnmount(() => {
if (selfVideoRef.value) {
selfVideoRef.value.srcObject = null;
@@ -111,7 +142,6 @@ onBeforeUnmount(() => {
.floating-video-window {
position: fixed;
z-index: 1300;
width: min(46vw, 720px);
min-width: 340px;
border-radius: 16px;
border: 1px solid #cad5ce;
@@ -224,9 +254,22 @@ onBeforeUnmount(() => {
color: #ffffff;
}
.floating-video-resize-handle {
position: absolute;
right: 6px;
bottom: 6px;
width: 18px;
height: 18px;
border: 0;
padding: 0;
cursor: nwse-resize;
background:
linear-gradient(135deg, transparent 0 42%, rgba(29, 106, 66, 0.2) 42% 52%, transparent 52% 62%, rgba(29, 106, 66, 0.45) 62% 72%, transparent 72% 82%, rgba(29, 106, 66, 0.75) 82% 92%, transparent 92% 100%);
}
@media (max-width: 860px) {
.floating-video-window {
width: calc(100vw - 24px);
width: calc(100vw - 24px) !important;
min-width: 0;
left: 12px !important;
top: 12px !important;

View File

@@ -19,7 +19,15 @@
:key="session.callId"
class="video-dock-card"
>
<div class="video-card-frame">
<div
class="video-card-frame video-card-frame-clickable"
role="button"
tabindex="0"
:title="`${session.withUserName} in den Vordergrund holen`"
@click="chatStore.bringVideoSessionToFront(session.callId)"
@keyup.enter="chatStore.bringVideoSessionToFront(session.callId)"
@keyup.space.prevent="chatStore.bringVideoSessionToFront(session.callId)"
>
<VideoSessionSurface :session="session" :muted="true" />
</div>
<div class="video-card-meta">
@@ -133,6 +141,10 @@ function statusLabel(status) {
position: relative;
}
.video-card-frame-clickable {
cursor: pointer;
}
.video-card-frame video {
width: 100%;
height: 100%;

View File

@@ -42,6 +42,10 @@ function createDefaultFloatingPosition() {
return { x: 24, y: 24 };
}
function createDefaultFloatingSize() {
return { width: 720, height: 0 };
}
export const useChatStore = defineStore('chat', () => {
const isLoggedIn = ref(false);
const userName = ref('');
@@ -73,6 +77,7 @@ export const useChatStore = defineStore('chat', () => {
const maxVideoConnectionsReached = ref(false);
const foregroundVideoSessionId = ref(null);
const floatingVideoPosition = ref(createDefaultFloatingPosition());
const floatingVideoSize = ref(createDefaultFloatingSize());
const selfPreviewStream = shallowRef(null);
const remoteStreams = ref({});
const selfMuted = ref(false);
@@ -287,6 +292,7 @@ export const useChatStore = defineStore('chat', () => {
selfMuted.value = false;
selfCameraEnabled.value = true;
floatingVideoPosition.value = createDefaultFloatingPosition();
floatingVideoSize.value = createDefaultFloatingSize();
}
async function ensureLocalPreviewStream() {
@@ -1030,6 +1036,12 @@ export const useChatStore = defineStore('chat', () => {
};
}
function updateFloatingVideoSize(size) {
const width = Math.max(340, Math.round(size.width || createDefaultFloatingSize().width));
const height = Math.max(0, Math.round(size.height || 0));
floatingVideoSize.value = { width, height };
}
function toggleSelfMute() {
selfMuted.value = !selfMuted.value;
syncLocalTrackState();
@@ -1174,6 +1186,7 @@ export const useChatStore = defineStore('chat', () => {
maxVideoConnectionsReached,
foregroundVideoSessionId,
floatingVideoPosition,
floatingVideoSize,
selfPreviewStream,
remoteStreams,
selfMuted,
@@ -1207,6 +1220,7 @@ export const useChatStore = defineStore('chat', () => {
bringVideoSessionToFront,
minimizeForegroundVideo,
updateFloatingVideoPosition,
updateFloatingVideoSize,
toggleSelfMute,
toggleSelfCamera
};