This commit is contained in:
@@ -39,6 +39,13 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="floating-video-resize-handle"
|
||||||
|
title="Fenstergröße ändern"
|
||||||
|
@mousedown.stop.prevent="startResize"
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -53,7 +60,8 @@ const selfVideoRef = ref(null);
|
|||||||
|
|
||||||
const windowStyle = computed(() => ({
|
const windowStyle = computed(() => ({
|
||||||
left: `${chatStore.floatingVideoPosition.x}px`,
|
left: `${chatStore.floatingVideoPosition.x}px`,
|
||||||
top: `${chatStore.floatingVideoPosition.y}px`
|
top: `${chatStore.floatingVideoPosition.y}px`,
|
||||||
|
width: `${chatStore.floatingVideoSize.width}px`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -100,6 +108,29 @@ function startDrag(event) {
|
|||||||
window.addEventListener('mouseup', handleUp);
|
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(() => {
|
onBeforeUnmount(() => {
|
||||||
if (selfVideoRef.value) {
|
if (selfVideoRef.value) {
|
||||||
selfVideoRef.value.srcObject = null;
|
selfVideoRef.value.srcObject = null;
|
||||||
@@ -111,7 +142,6 @@ onBeforeUnmount(() => {
|
|||||||
.floating-video-window {
|
.floating-video-window {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1300;
|
z-index: 1300;
|
||||||
width: min(46vw, 720px);
|
|
||||||
min-width: 340px;
|
min-width: 340px;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
border: 1px solid #cad5ce;
|
border: 1px solid #cad5ce;
|
||||||
@@ -224,9 +254,22 @@ onBeforeUnmount(() => {
|
|||||||
color: #ffffff;
|
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) {
|
@media (max-width: 860px) {
|
||||||
.floating-video-window {
|
.floating-video-window {
|
||||||
width: calc(100vw - 24px);
|
width: calc(100vw - 24px) !important;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
left: 12px !important;
|
left: 12px !important;
|
||||||
top: 12px !important;
|
top: 12px !important;
|
||||||
|
|||||||
@@ -19,7 +19,15 @@
|
|||||||
:key="session.callId"
|
:key="session.callId"
|
||||||
class="video-dock-card"
|
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" />
|
<VideoSessionSurface :session="session" :muted="true" />
|
||||||
</div>
|
</div>
|
||||||
<div class="video-card-meta">
|
<div class="video-card-meta">
|
||||||
@@ -133,6 +141,10 @@ function statusLabel(status) {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video-card-frame-clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.video-card-frame video {
|
.video-card-frame video {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ function createDefaultFloatingPosition() {
|
|||||||
return { x: 24, y: 24 };
|
return { x: 24, y: 24 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createDefaultFloatingSize() {
|
||||||
|
return { width: 720, height: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
export const useChatStore = defineStore('chat', () => {
|
export const useChatStore = defineStore('chat', () => {
|
||||||
const isLoggedIn = ref(false);
|
const isLoggedIn = ref(false);
|
||||||
const userName = ref('');
|
const userName = ref('');
|
||||||
@@ -73,6 +77,7 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
const maxVideoConnectionsReached = ref(false);
|
const maxVideoConnectionsReached = ref(false);
|
||||||
const foregroundVideoSessionId = ref(null);
|
const foregroundVideoSessionId = ref(null);
|
||||||
const floatingVideoPosition = ref(createDefaultFloatingPosition());
|
const floatingVideoPosition = ref(createDefaultFloatingPosition());
|
||||||
|
const floatingVideoSize = ref(createDefaultFloatingSize());
|
||||||
const selfPreviewStream = shallowRef(null);
|
const selfPreviewStream = shallowRef(null);
|
||||||
const remoteStreams = ref({});
|
const remoteStreams = ref({});
|
||||||
const selfMuted = ref(false);
|
const selfMuted = ref(false);
|
||||||
@@ -287,6 +292,7 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
selfMuted.value = false;
|
selfMuted.value = false;
|
||||||
selfCameraEnabled.value = true;
|
selfCameraEnabled.value = true;
|
||||||
floatingVideoPosition.value = createDefaultFloatingPosition();
|
floatingVideoPosition.value = createDefaultFloatingPosition();
|
||||||
|
floatingVideoSize.value = createDefaultFloatingSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ensureLocalPreviewStream() {
|
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() {
|
function toggleSelfMute() {
|
||||||
selfMuted.value = !selfMuted.value;
|
selfMuted.value = !selfMuted.value;
|
||||||
syncLocalTrackState();
|
syncLocalTrackState();
|
||||||
@@ -1174,6 +1186,7 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
maxVideoConnectionsReached,
|
maxVideoConnectionsReached,
|
||||||
foregroundVideoSessionId,
|
foregroundVideoSessionId,
|
||||||
floatingVideoPosition,
|
floatingVideoPosition,
|
||||||
|
floatingVideoSize,
|
||||||
selfPreviewStream,
|
selfPreviewStream,
|
||||||
remoteStreams,
|
remoteStreams,
|
||||||
selfMuted,
|
selfMuted,
|
||||||
@@ -1207,6 +1220,7 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
bringVideoSessionToFront,
|
bringVideoSessionToFront,
|
||||||
minimizeForegroundVideo,
|
minimizeForegroundVideo,
|
||||||
updateFloatingVideoPosition,
|
updateFloatingVideoPosition,
|
||||||
|
updateFloatingVideoSize,
|
||||||
toggleSelfMute,
|
toggleSelfMute,
|
||||||
toggleSelfCamera
|
toggleSelfCamera
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user