فهرست منبع

Ajustes no tamanho do modal de exibição do video

Ranghetti 2 هفته پیش
والد
کامیت
e61da27554
2فایلهای تغییر یافته به همراه92 افزوده شده و 6 حذف شده
  1. 8 1
      src/lib/components/trading/ModalBase.svelte
  2. 84 5
      src/routes/trading/+page.svelte

+ 8 - 1
src/lib/components/trading/ModalBase.svelte

@@ -3,6 +3,10 @@
   export let title = '';
   export let visible = false;
   export let onClose = () => {};
+  export let maxWidthClass = 'max-w-lg';
+  export let maxHeightClass = 'max-h-[80vh]';
+  export let modalClass = '';
+  export let modalStyle = '';
   const dispatch = createEventDispatcher();
   function close() { try { onClose?.(); } catch {} dispatch('close'); }
   function overlayClick(e) { if (e.target === e.currentTarget) close(); }
@@ -22,7 +26,10 @@
       }
     }}
   ></div>
-  <div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700 w-full max-w-lg mx-4 max-h-[80vh] flex flex-col">
+  <div
+    class={`relative bg-white dark:bg-gray-800 rounded-lg shadow-xl border border-gray-200 dark:border-gray-700 w-full ${maxWidthClass} mx-4 ${maxHeightClass} flex flex-col ${modalClass}`.trim()}
+    style={modalStyle}
+  >
     <div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
       <h3 class="text-base font-semibold text-gray-900 dark:text-gray-100">{title}</h3>
       <button class="p-1 rounded text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200" on:click={close}>✕</button>

+ 84 - 5
src/routes/trading/+page.svelte

@@ -78,6 +78,10 @@
   let orderMonitoringError = '';
   let orderMonitoringRows = [];
 
+  let monitoringVideoModalVisible = false;
+  let monitoringVideoUrl = '';
+  let monitoringVideoError = '';
+
   async function parseResponse(res) {
     const raw = await res.text();
     return raw ? JSON.parse(raw) : null;
@@ -372,6 +376,51 @@
     orderMonitoringLoading = false;
   }
 
+  function closeMonitoringVideoModal() {
+    monitoringVideoModalVisible = false;
+    monitoringVideoUrl = '';
+    monitoringVideoError = '';
+  }
+
+  function convertToEmbedUrl(url) {
+    if (!url) return url;
+
+    // Vimeo: https://vimeo.com/962745565 -> https://player.vimeo.com/video/962745565?autoplay=1&muted=1
+    const vimeoMatch = url.match(/vimeo\.com\/(\d+)/);
+    if (vimeoMatch) {
+      return `https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=1&muted=1`;
+    }
+
+    // YouTube: várias variações -> https://www.youtube.com/embed/VIDEO_ID?autoplay=1&mute=1
+    const youtubeMatch = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]+)/);
+    if (youtubeMatch) {
+      return `https://www.youtube.com/embed/${youtubeMatch[1]}?autoplay=1&mute=1`;
+    }
+
+    // Google Drive: https://drive.google.com/file/d/FILE_ID/view -> https://drive.google.com/file/d/FILE_ID/preview
+    const driveMatch = url.match(/drive\.google\.com\/file\/d\/([a-zA-Z0-9_-]+)/);
+    if (driveMatch) {
+      return `https://drive.google.com/file/d/${driveMatch[1]}/preview`;
+    }
+
+    // Retorna URL original se não for reconhecido
+    return url;
+  }
+
+  function openMonitoringVideoModal(link) {
+    const url = typeof link === 'string' ? link.trim() : '';
+    if (!url) {
+      monitoringVideoError = 'Link de vídeo inválido.';
+      monitoringVideoUrl = '';
+      monitoringVideoModalVisible = true;
+      return;
+    }
+
+    monitoringVideoError = '';
+    monitoringVideoUrl = convertToEmbedUrl(url);
+    monitoringVideoModalVisible = true;
+  }
+
   async function openOrderMonitoringModal() {
     if (!orderDetailSelected) return;
     if (orderMonitoringLoading) return;
@@ -1571,14 +1620,13 @@ $: displayPendingSells = pendingSells.map((o) => ({
                   <div class="mt-1 text-sm break-words">{row?.description ?? '—'}</div>
                 </div>
                 {#if row?.link}
-                  <a
+                  <button
+                    type="button"
                     class="shrink-0 text-blue-600 hover:text-blue-500 underline text-sm"
-                    href={row.link}
-                    target="_blank"
-                    rel="noreferrer"
+                    on:click={() => openMonitoringVideoModal(row.link)}
                   >
                     Abrir
-                  </a>
+                  </button>
                 {/if}
               </div>
             </li>
@@ -1587,6 +1635,37 @@ $: displayPendingSells = pendingSells.map((o) => ({
       {/if}
     </div>
   </ModalBase>
+  <ModalBase
+    title="Vídeo do monitoramento"
+    visible={monitoringVideoModalVisible}
+    onClose={closeMonitoringVideoModal}
+    maxWidthClass=""
+    maxHeightClass=""
+    modalStyle="width: 45vw; height: 85vh;"
+  >
+    <div class="space-y-3 text-sm text-gray-800 dark:text-gray-100">
+      {#if monitoringVideoError}
+        <div class="rounded border border-red-200 dark:border-red-700 bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-200 px-3 py-2">
+          {monitoringVideoError}
+        </div>
+      {/if}
+
+      {#if monitoringVideoUrl}
+        <div class="w-full aspect-video rounded overflow-hidden border border-gray-200 dark:border-gray-700 bg-black">
+          <iframe
+            title="Vídeo do monitoramento"
+            class="w-full h-full"
+            src={monitoringVideoUrl}
+            frameborder="0"
+            allow="autoplay; fullscreen; picture-in-picture"
+            allowfullscreen
+          />
+        </div>
+      {:else if !monitoringVideoError}
+        <p class="text-sm text-gray-500">Nenhum link selecionado.</p>
+      {/if}
+    </div>
+  </ModalBase>
   <ModalBase
     title="Pagamento via Pix"
     visible={orderPaymentModalVisible}