UNPKG

analytica-frontend-lib

Version:

Repositório público dos componentes utilizados nas plataformas da Analytica Ensino

254 lines (245 loc) 9.14 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkKTHF7N26js = require('./chunk-KTHF7N26.js'); var _chunkBVUPM6EYjs = require('./chunk-BVUPM6EY.js'); var _chunkTN3AYOMVjs = require('./chunk-TN3AYOMV.js'); // src/components/DownloadButton/DownloadButton.tsx var _react = require('react'); var _DownloadSimple = require('@phosphor-icons/react/dist/csr/DownloadSimple'); var _jsxruntime = require('react/jsx-runtime'); var supportsDirectoryPicker = () => typeof globalThis.showDirectoryPicker === "function"; var getFileExtension = (url) => { try { const u = new URL(url, _optionalChain([globalThis, 'access', _ => _.location, 'optionalAccess', _2 => _2.origin]) || "http://localhost"); url = u.pathname; } catch (e) { } const path = url.split(/[?#]/)[0]; const dot = path.lastIndexOf("."); return dot > -1 ? path.slice(dot + 1).toLowerCase() : "file"; }; var slugifyTitle = (lessonTitle) => lessonTitle.toLowerCase().replaceAll(/[^a-z0-9\s]/g, "").replaceAll(/\s+/g, "-").substring(0, 50); var generateFilename = (contentType, url, lessonTitle = "aula") => `${slugifyTitle(lessonTitle)}-${contentType}.${getFileExtension(url)}`; var getRemoteFileSize = async (url) => { try { const response = await fetch(url, { method: "HEAD", mode: "cors" }); if (!response.ok) return 0; return Number(response.headers.get("content-length")) || 0; } catch (e2) { return 0; } }; var streamToDisk = async (url, dirHandle, filename, onBytes) => { const response = await fetch(url, { mode: "cors" }); if (!response.ok) { throw new Error( `Failed to fetch file: ${response.status} ${response.statusText}` ); } if (!response.body) { throw new Error("Response has no readable body"); } const fileHandle = await dirHandle.getFileHandle(filename, { create: true }); const writable = await fileHandle.createWritable(); try { const reader = response.body.getReader(); for (; ; ) { const { done, value } = await reader.read(); if (done) break; await writable.write(value); onBytes(value.length); } await writable.close(); } catch (error) { await _optionalChain([writable, 'access', _3 => _3.abort, 'optionalCall', _4 => _4()]); throw error; } }; var triggerBrowserDownload = (url, filename) => { const link = document.createElement("a"); link.href = url; link.download = filename; link.rel = "noopener noreferrer"; document.body.appendChild(link); link.click(); link.remove(); }; var DownloadButton = ({ content, className, onDownloadStart, onDownloadComplete, onDownloadError, lessonTitle = "aula", disabled = false }) => { const [isDownloading, setIsDownloading] = _react.useState.call(void 0, false); const [progress, setProgress] = _react.useState.call(void 0, 0); const isValidUrl = _react.useCallback.call(void 0, (url) => { return Boolean( url && url.trim() !== "" && url !== "undefined" && url !== "null" ); }, []); const getAvailableContent = _react.useCallback.call(void 0, () => { const downloads = []; if (isValidUrl(content.urlVideo)) { downloads.push({ type: "video", url: content.urlVideo, label: "V\xEDdeo" }); } if (isValidUrl(content.urlPodcast)) { downloads.push({ type: "podcast", url: content.urlPodcast, label: "Podcast" }); } if (isValidUrl(content.urlInitialFrame)) { downloads.push({ type: "quadro-inicial", url: content.urlInitialFrame, label: "Quadro Inicial" }); } if (isValidUrl(content.urlFinalFrame)) { downloads.push({ type: "quadro-final", url: content.urlFinalFrame, label: "Quadro Final" }); } return downloads; }, [content, isValidUrl]); const downloadToFolder = _react.useCallback.call(void 0, async (items, dirHandle) => { const sizes = await Promise.all( items.map((item) => getRemoteFileSize(item.url)) ); const totalBytes = sizes.reduce((sum, size) => sum + size, 0); const weighByFile = totalBytes === 0; let downloadedBytes = 0; let succeeded = 0; for (const [index, item] of items.entries()) { try { _optionalChain([onDownloadStart, 'optionalCall', _5 => _5(item.type)]); await streamToDisk( item.url, dirHandle, generateFilename(item.type, item.url, lessonTitle), (chunkSize) => { downloadedBytes += chunkSize; if (!weighByFile) { setProgress( Math.min(99, Math.round(downloadedBytes / totalBytes * 100)) ); } } ); succeeded++; _optionalChain([onDownloadComplete, 'optionalCall', _6 => _6(item.type)]); } catch (error) { _optionalChain([onDownloadError, 'optionalCall', _7 => _7( item.type, error instanceof Error ? error : new Error(`Falha ao baixar ${item.label}`) )]); } finally { if (weighByFile) { setProgress( Math.min(99, Math.round((index + 1) / items.length * 100)) ); } } } if (succeeded === 0) { throw new Error("Nenhum conte\xFAdo da aula p\xF4de ser baixado"); } setProgress(100); }, [lessonTitle, onDownloadStart, onDownloadComplete, onDownloadError] ); const downloadViaBrowser = _react.useCallback.call(void 0, async (items) => { for (const [index, item] of items.entries()) { _optionalChain([onDownloadStart, 'optionalCall', _8 => _8(item.type)]); triggerBrowserDownload( item.url, generateFilename(item.type, item.url, lessonTitle) ); _optionalChain([onDownloadComplete, 'optionalCall', _9 => _9(item.type)]); setProgress(Math.round((index + 1) / items.length * 100)); if (index < items.length - 1) { await new Promise((resolve) => setTimeout(resolve, 800)); } } }, [lessonTitle, onDownloadStart, onDownloadComplete] ); const handleDownload = _react.useCallback.call(void 0, async () => { if (disabled || isDownloading) return; const availableContent = getAvailableContent(); if (availableContent.length === 0) return; let dirHandle = null; if (supportsDirectoryPicker()) { try { const picker = globalThis.showDirectoryPicker; dirHandle = await picker({ mode: "readwrite", id: "aulas" }); } catch (e3) { return; } } setIsDownloading(true); setProgress(0); try { if (dirHandle) { await downloadToFolder(availableContent, dirHandle); } else { await downloadViaBrowser(availableContent); } } catch (error) { _optionalChain([onDownloadError, 'optionalCall', _10 => _10( "aula", error instanceof Error ? error : new Error("Falha ao baixar o conte\xFAdo da aula") )]); } finally { setIsDownloading(false); setProgress(0); } }, [ disabled, isDownloading, getAvailableContent, downloadToFolder, downloadViaBrowser, onDownloadError ]); const availableCount = getAvailableContent().length; if (availableCount === 0) { return null; } const suffix = availableCount > 1 ? "s" : ""; return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunkTN3AYOMVjs.cn.call(void 0, "flex items-center", className), children: [ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBVUPM6EYjs.IconButton_default, { icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _DownloadSimple.DownloadSimpleIcon, { size: 24 }), onClick: handleDownload, disabled: disabled || isDownloading, "aria-label": isDownloading ? "Baixando conte\xFAdo..." : `Baixar conte\xFAdo da aula (${availableCount} arquivo${suffix})`, className: _chunkTN3AYOMVjs.cn.call(void 0, "!bg-transparent hover:!bg-black/10 transition-colors", isDownloading && "opacity-60 cursor-not-allowed" ) } ), /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkKTHF7N26js.ProgressModal_default, { isOpen: isDownloading, onClose: () => { }, message: "Baixando conte\xFAdo da aula...", progress } ) ] }); }; var DownloadButton_default = DownloadButton; exports.DownloadButton_default = DownloadButton_default; //# sourceMappingURL=chunk-7CYRHMOF.js.map