[mirotalk] - add option widget draggable

This commit is contained in:
Miroslav Pejic
2025-11-22 04:16:34 +01:00
parent 23ff8f5716
commit fcab33ba6f
8 changed files with 96 additions and 7 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ dependencies: {
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.6.41
* @version 1.6.42
*
*/
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mirotalk",
"version": "1.6.41",
"version": "1.6.42",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mirotalk",
"version": "1.6.41",
"version": "1.6.42",
"license": "AGPL-3.0",
"dependencies": {
"@mattermost/client": "11.1.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "mirotalk",
"version": "1.6.41",
"version": "1.6.42",
"description": "A free WebRTC browser-based video call",
"main": "server.js",
"scripts": {
+1 -1
View File
@@ -77,7 +77,7 @@ let brand = {
},
about: {
imageUrl: '../images/mirotalk-logo.gif',
title: 'WebRTC P2P v1.6.41',
title: 'WebRTC P2P v1.6.42',
html: `
<button
id="support-button"
+2 -2
View File
@@ -15,7 +15,7 @@
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.6.41
* @version 1.6.42
*
*/
@@ -12322,7 +12322,7 @@ function showAbout() {
Swal.fire({
background: swBg,
position: 'center',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.41',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.42',
imageUrl: brand.about?.imageUrl && brand.about.imageUrl.trim() !== '' ? brand.about.imageUrl : images.about,
customClass: { image: 'img-about' },
html: `
+87
View File
@@ -10,6 +10,7 @@ class MiroTalkWidget {
widgetState: 'normal', // 'normal', 'minimized', 'closed'
widgetType: 'support', // 'support', 'meeting', 'chat' (future)
supportWidget: {
draggable: false,
position: 'bottom-right',
expertImages: [
'https://i.pravatar.cc/40?img=1',
@@ -111,6 +112,11 @@ class MiroTalkWidget {
// Start status checking if enabled
this.initStatusChecking();
// Make widget draggable if enabled
if (this.options.supportWidget.draggable) {
this.makeDraggable(widget);
}
// Automatically minimize on creation
if (this.options.widgetState === 'minimized' && this.isInitialized) {
window.miroTalkWidgetAction('minimize', widget);
@@ -140,6 +146,83 @@ class MiroTalkWidget {
}
}
// ============================================================================
// WIDGET DRAGGABLE
// ============================================================================
makeDraggable(element) {
let isDragging = false;
let startX = 0,
startY = 0,
startLeft = 0,
startTop = 0;
let rafId = null;
let pendingLeft = null,
pendingTop = null;
const dragHandle = element.querySelector('.online-indicator') || element;
dragHandle.style.cursor = 'move';
element.style.position = 'fixed';
element.style.left = element.offsetLeft + 'px';
element.style.top = element.offsetTop + 'px';
element.style.transform = 'translate(0,0)';
dragHandle.addEventListener('pointerdown', onPointerDown);
function onPointerDown(e) {
if (e.button !== 0) return;
e.preventDefault();
isDragging = true;
startX = e.clientX;
startY = e.clientY;
const rect = element.getBoundingClientRect();
startLeft = rect.left;
startTop = rect.top;
element.setPointerCapture(e.pointerId);
element.style.zIndex = 9999;
element.style.willChange = 'left, top';
document.addEventListener('pointermove', onPointerMove);
document.addEventListener('pointerup', onPointerUp);
}
function onPointerMove(e) {
if (!isDragging) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
scheduleMove(startLeft + dx, startTop + dy);
}
function onPointerUp(e) {
if (!isDragging) return;
isDragging = false;
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerup', onPointerUp);
element.style.willChange = '';
try {
element.releasePointerCapture(e.pointerId);
} catch (err) {}
}
function scheduleMove(left, top) {
// Prevent dragging out of viewport
const minLeft = 0;
const minTop = 0;
const maxLeft = window.innerWidth - element.offsetWidth;
const maxTop = window.innerHeight - element.offsetHeight;
left = Math.max(minLeft, Math.min(left, maxLeft));
top = Math.max(minTop, Math.min(top, maxTop));
pendingLeft = left;
pendingTop = top;
if (rafId) return;
rafId = requestAnimationFrame(() => {
element.style.left = pendingLeft + 'px';
element.style.top = pendingTop + 'px';
element.style.transform = 'translate(0,0)';
rafId = null;
});
}
}
// ============================================================================
// WIDGET CREATION METHODS
// ============================================================================
@@ -743,6 +826,9 @@ document.addEventListener('DOMContentLoaded', function () {
userName: autoInit.getAttribute('data-user') || `guest-${Math.floor(Math.random() * 10000)}`,
theme: autoInit.getAttribute('data-theme') || MiroTalkWidget.DEFAULT_OPTIONS.theme,
widgetState: autoInit.getAttribute('data-widget-state') || MiroTalkWidget.DEFAULT_OPTIONS.widgetState,
draggable:
autoInit.getAttribute('data-draggable') === 'true' ||
MiroTalkWidget.DEFAULT_OPTIONS.supportWidget.draggable,
position: autoInit.getAttribute('data-position') || MiroTalkWidget.DEFAULT_OPTIONS.supportWidget.position,
checkOnline: autoInit.getAttribute('data-check-online') === 'true',
expertImages: autoInit.getAttribute('data-expert-images')
@@ -780,6 +866,7 @@ document.addEventListener('DOMContentLoaded', function () {
theme: config.theme,
supportWidget: {
...MiroTalkWidget.DEFAULT_OPTIONS.supportWidget,
draggable: config.draggable,
position: config.position,
expertImages: config.expertImages,
checkOnlineStatus: config.checkOnline,
+1
View File
@@ -13,6 +13,7 @@
data-widget-type="support"
data-widget-state="normal"
data-position="bottom-right"
data-draggable="false"
data-check-online="false"
data-expert-images="https://i.pravatar.cc/40?img=1,https://i.pravatar.cc/40?img=2,https://i.pravatar.cc/40?img=3"
data-buttons="audio,video,screen,chat,join"
+1
View File
@@ -17,6 +17,7 @@
widgetState: 'normal', // 'normal', 'minimized', 'closed'
widgetType: 'support',
supportWidget: {
draggable: false,
position: 'bottom-right', // 'bottom-right', 'bottom-left', 'top-right', 'top-left'
expertImages: [
'https://i.pravatar.cc/40?img=1',