[mirotalk] - add option widget draggable
This commit is contained in:
+1
-1
@@ -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
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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: `
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user