DOWNLOAD (ga)
Signed-off-by: FTCHD <144691102+FTCHD@users.noreply.github.com>
This commit is contained in:
+1
-1
@@ -715,7 +715,7 @@ export async function startDownload({
|
||||
fs,
|
||||
remote,
|
||||
url,
|
||||
autoFilename = true,
|
||||
autoFilename = false,
|
||||
}: {
|
||||
fs: string // a remote name string e.g. "drive:"
|
||||
remote: string // a path within that remote e.g. "dir"
|
||||
|
||||
Generated
+162
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^0.9.0",
|
||||
"@heroui/react": "^2.7.11",
|
||||
"@mux/mux-player-react": "^3.8.0",
|
||||
"@sentry/browser": "^10.8.0",
|
||||
"@tauri-apps/api": "~2.8.0",
|
||||
"@tauri-apps/plugin-autostart": "^2.5.0",
|
||||
@@ -2625,6 +2626,74 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@mux/mux-data-google-ima": {
|
||||
"version": "0.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@mux/mux-data-google-ima/-/mux-data-google-ima-0.2.8.tgz",
|
||||
"integrity": "sha512-0ZEkHdcZ6bS8QtcjFcoJeZxJTpX7qRIledf4q1trMWPznugvtajCjCM2kieK/pzkZj1JM6liDRFs1PJSfVUs2A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mux-embed": "5.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mux/mux-player": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@mux/mux-player/-/mux-player-3.8.0.tgz",
|
||||
"integrity": "sha512-2KcJdW4BBX8JDcXpclFKaNBsqpebtaEfTzwm5lPP1Lf6y5OMILvf2tqVCOczurREVFyaEoVD71vL0I5Vvqb1dA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mux/mux-video": "0.27.2",
|
||||
"@mux/playback-core": "0.31.2",
|
||||
"media-chrome": "~4.15.1",
|
||||
"player.style": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mux/mux-player-react": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@mux/mux-player-react/-/mux-player-react-3.8.0.tgz",
|
||||
"integrity": "sha512-c9TKtK9nsSpXOuC1LVLmmHA+Zlpcx4mzgGaA7ZlukrGMfoXWvA90ROSVAAjXRA+UKSHdLIbvNofgG3P6rEE/4Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mux/mux-player": "3.8.0",
|
||||
"@mux/playback-core": "0.31.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.0 || ^17.0.0-0 || ^18 || ^18.0.0-0 || ^19 || ^19.0.0-0",
|
||||
"react": "^17.0.2 || ^17.0.0-0 || ^18 || ^18.0.0-0 || ^19 || ^19.0.0-0",
|
||||
"react-dom": "^17.0.2 || ^17.0.2-0 || ^18 || ^18.0.0-0 || ^19 || ^19.0.0-0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@mux/mux-video": {
|
||||
"version": "0.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@mux/mux-video/-/mux-video-0.27.2.tgz",
|
||||
"integrity": "sha512-VAqSw/3kS/qBzjyFSX3wClIX5Kdk6eXXlhxIJRWlClYvUKGm9ruhd7HzkwZVOJguvUh5QbGoiGWBEW2xkNIXzw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mux/mux-data-google-ima": "0.2.8",
|
||||
"@mux/playback-core": "0.31.2",
|
||||
"castable-video": "~1.1.11",
|
||||
"custom-media-element": "~1.4.5",
|
||||
"media-tracks": "~0.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@mux/playback-core": {
|
||||
"version": "0.31.2",
|
||||
"resolved": "https://registry.npmjs.org/@mux/playback-core/-/playback-core-0.31.2.tgz",
|
||||
"integrity": "sha512-bhOVTGAuKCQuDzNOc3XvDq7vsgqy2DAacLP0WdJciUKjfZhs3oA11NbKG7qAN6akPnZVfgn0Jn/sJN8TRjE30A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hls.js": "~1.6.13",
|
||||
"mux-embed": "^5.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -5890,6 +5959,24 @@
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/castable-video": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/castable-video/-/castable-video-1.1.11.tgz",
|
||||
"integrity": "sha512-LCRTK6oe7SB1SiUQFzZCo6D6gcEzijqBTVIuj3smKpQdesXM18QTbCVqWgh9MfOeQgTx/i9ji5jGcdqNPeWg2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"custom-media-element": "~1.4.5"
|
||||
}
|
||||
},
|
||||
"node_modules/ce-la-react": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ce-la-react/-/ce-la-react-0.3.1.tgz",
|
||||
"integrity": "sha512-g0YwpZDPIwTwFumGTzNHcgJA6VhFfFCJkSNdUdC04br2UfU+56JDrJrJva3FZ7MToB4NDHAFBiPE/PZdNl1mQA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
@@ -6050,6 +6137,12 @@
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/custom-media-element": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/custom-media-element/-/custom-media-element-1.4.5.tgz",
|
||||
"integrity": "sha512-cjrsQufETwxjvwZbYbKBCJNvmQ2++G9AvT45zDi7NXL9k2PdVcs2h0jQz96J6G4TMKRCcEsoJ+QTgQD00Igtjw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
@@ -6353,6 +6446,12 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hls.js": {
|
||||
"version": "1.6.14",
|
||||
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.14.tgz",
|
||||
"integrity": "sha512-CSpT2aXsv71HST8C5ETeVo+6YybqCpHBiYrCRQSn3U5QUZuLTSsvtq/bj+zuvjLVADeKxoebzo16OkH8m1+65Q==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/input-otp": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.1.tgz",
|
||||
@@ -6565,6 +6664,21 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/media-chrome": {
|
||||
"version": "4.15.1",
|
||||
"resolved": "https://registry.npmjs.org/media-chrome/-/media-chrome-4.15.1.tgz",
|
||||
"integrity": "sha512-Hxqr0qQ67ewmRaLJBqe5ayu53txFX+DODb9xBSHgTbw7j+gITGZ4llbPPEmqMlDnatw7IsF+AUh9rJYbpnn4ZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ce-la-react": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/media-tracks": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/media-tracks/-/media-tracks-0.3.3.tgz",
|
||||
"integrity": "sha512-9P2FuUHnZZ3iji+2RQk7Zkh5AmZTnOG5fODACnjhCVveX1McY3jmCRHofIEI+yTBqplz7LXy48c7fQ3Uigp88w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
@@ -6629,6 +6743,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mux-embed": {
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/mux-embed/-/mux-embed-5.9.0.tgz",
|
||||
"integrity": "sha512-wmunL3uoPhma/tWy8PrDPZkvJpXvSFBwbD3KkC4PG8Ztjfb1X3hRJwGUAQyRz7z99b/ovLm2UTTitrkvStjH4w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
@@ -6782,6 +6902,31 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/player.style": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/player.style/-/player.style-0.3.0.tgz",
|
||||
"integrity": "sha512-ny1TbqA2ZsUd6jzN+F034+UMXVK7n5SrwepsrZ2gIqVz00Hn0ohCUbbUdst/2IOFCy0oiTbaOXkSFxRw1RmSlg==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
".",
|
||||
"site",
|
||||
"examples/*",
|
||||
"scripts/*",
|
||||
"themes/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"media-chrome": "~4.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/player.style/node_modules/media-chrome": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/media-chrome/-/media-chrome-4.14.0.tgz",
|
||||
"integrity": "sha512-IEdFb4blyF15vLvQzLIn6USJBv7Kf2ne+TfLQKBYI5Z0f9VEBVZz5MKy4Uhi0iA9lStl2S9ENIujJRuJIa5OiA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ce-la-react": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
@@ -6919,6 +7064,17 @@
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@@ -6971,6 +7127,12 @@
|
||||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^0.9.0",
|
||||
"@heroui/react": "^2.7.11",
|
||||
"@mux/mux-player-react": "^3.8.0",
|
||||
"@sentry/browser": "^10.8.0",
|
||||
"@tauri-apps/api": "~2.8.0",
|
||||
"@tauri-apps/plugin-autostart": "^2.5.0",
|
||||
|
||||
+177
-24
@@ -1,23 +1,60 @@
|
||||
import { Button, Input } from '@heroui/react'
|
||||
import { Button, Image, Input, Spinner } from '@heroui/react'
|
||||
import MuxPlayer from '@mux/mux-player-react'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { message } from '@tauri-apps/plugin-dialog'
|
||||
import { DownloadIcon, FoldersIcon, XIcon } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { startDownload } from '../../lib/rclone/api'
|
||||
import { PathField } from '../components/PathFinder'
|
||||
|
||||
export default function Download() {
|
||||
const [searchParams] = useSearchParams()
|
||||
function isValidUrl(url: string) {
|
||||
try {
|
||||
new URL(url)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function isYoutubeUrl(url: string) {
|
||||
return url.includes('youtube.com') || url.includes('youtu.be')
|
||||
}
|
||||
|
||||
function getDateFilename() {
|
||||
return new Date()
|
||||
.toLocaleString(undefined, {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'medium',
|
||||
})
|
||||
.replace(',', ' at')
|
||||
.replace(/[\/]/g, '-')
|
||||
.replace(/[:]/g, '.')
|
||||
}
|
||||
|
||||
function getUrlDomain(url: string) {
|
||||
const hostname = new URL(url).hostname
|
||||
return hostname.split('.').slice(0, -1).join('.') || hostname.split('.')[0]
|
||||
}
|
||||
|
||||
export default function Download() {
|
||||
const [url, setUrl] = useState<string | undefined>()
|
||||
const [source, setSource] = useState<string | undefined>(
|
||||
searchParams.get('initialSource') ? searchParams.get('initialSource')! : undefined
|
||||
)
|
||||
const [destination, setDestination] = useState<string | undefined>()
|
||||
const [filename, setFilename] = useState<string | undefined>()
|
||||
|
||||
const [isStarted, setIsStarted] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
|
||||
const [downloadData, setDownloadData] = useState<
|
||||
| {
|
||||
url: string
|
||||
title: string
|
||||
extension: string
|
||||
type: 'video' | 'audio' | 'file' | 'image'
|
||||
}
|
||||
| undefined
|
||||
>()
|
||||
const [isFetchingDownloadData, setIsFetchingDownloadData] = useState(false)
|
||||
|
||||
async function handleStartDownload() {
|
||||
setIsLoading(true)
|
||||
|
||||
@@ -30,7 +67,7 @@ export default function Download() {
|
||||
return
|
||||
}
|
||||
|
||||
if (!source) {
|
||||
if (!destination) {
|
||||
await message('Please select a destination path', {
|
||||
title: 'Error',
|
||||
kind: 'error',
|
||||
@@ -39,10 +76,8 @@ export default function Download() {
|
||||
return
|
||||
}
|
||||
|
||||
const [fs, remote] = source.split(':')
|
||||
|
||||
if (!fs || !remote) {
|
||||
await message('Invalid destination path', {
|
||||
if (!filename) {
|
||||
await message('Please enter a filename', {
|
||||
title: 'Error',
|
||||
kind: 'error',
|
||||
})
|
||||
@@ -50,13 +85,17 @@ export default function Download() {
|
||||
return
|
||||
}
|
||||
|
||||
const downloadUrl = downloadData?.url || url
|
||||
|
||||
try {
|
||||
await startDownload({
|
||||
fs,
|
||||
remote,
|
||||
url,
|
||||
fs: destination,
|
||||
remote: filename,
|
||||
url: downloadUrl,
|
||||
})
|
||||
|
||||
// await _startDownload()
|
||||
|
||||
setIsStarted(true)
|
||||
|
||||
await message('Download job started', {
|
||||
@@ -76,26 +115,95 @@ export default function Download() {
|
||||
|
||||
const buttonText = (() => {
|
||||
if (isLoading) return 'STARTING...'
|
||||
if (!source) return 'Please select a destination path'
|
||||
if (!url) return 'Please enter a URL'
|
||||
if (!isValidUrl(url)) return 'Invalid URL'
|
||||
if (!destination) return 'Please select a destination path'
|
||||
return 'DOWNLOAD'
|
||||
})()
|
||||
|
||||
const buttonIcon = (() => {
|
||||
if (isLoading) return
|
||||
if (!source) return <FoldersIcon className="w-5 h-5" />
|
||||
if (!url) return <XIcon className="w-5 h-5" />
|
||||
if (!isValidUrl(url)) return <XIcon className="w-5 h-5" />
|
||||
if (!destination) return <FoldersIcon className="w-5 h-5" />
|
||||
return <DownloadIcon className="w-5 h-5 fill-current" />
|
||||
})()
|
||||
|
||||
useEffect(() => {
|
||||
if (!url || !isValidUrl(url)) {
|
||||
setFilename(undefined)
|
||||
setDownloadData(undefined)
|
||||
setIsFetchingDownloadData(false)
|
||||
return
|
||||
}
|
||||
|
||||
console.log('[Download] Fetching download data for URL:', url)
|
||||
|
||||
const abortController = new AbortController()
|
||||
setIsFetchingDownloadData(true)
|
||||
|
||||
let parsedFilename: typeof filename
|
||||
let parsedDownloadData: typeof downloadData
|
||||
|
||||
fetch(`https://rcloneui.com/api/download?url=${encodeURIComponent(url)}`, {
|
||||
signal: abortController.signal,
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (response.ok) {
|
||||
const result = await response.json()
|
||||
|
||||
if (result.data && Array.isArray(result.data) && result.data.length > 0) {
|
||||
console.log('[Download] Successfully fetched download data')
|
||||
const item = result.data[0]
|
||||
parsedDownloadData = {
|
||||
url: item.url,
|
||||
title: item.title,
|
||||
extension: item.extension,
|
||||
type: item.type,
|
||||
}
|
||||
parsedFilename = `${item.title.substring(0, 42).trim()}.${item.extension || 'txt'}`
|
||||
console.log(parsedDownloadData)
|
||||
console.log(parsedFilename)
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedFilename && parsedDownloadData) {
|
||||
console.log('[Download] Setting filename and download data')
|
||||
setFilename(parsedFilename)
|
||||
setDownloadData(parsedDownloadData)
|
||||
} else {
|
||||
const extractedExtension = url.split('.').pop()?.split('?')[0]?.toLowerCase()
|
||||
|
||||
if (extractedExtension) {
|
||||
parsedFilename = url.split('/').pop()?.split('?')[0]
|
||||
} else {
|
||||
parsedFilename = `${getUrlDomain(url)} ${getDateFilename()}.txt`
|
||||
}
|
||||
|
||||
setFilename(parsedFilename)
|
||||
setDownloadData(undefined)
|
||||
}
|
||||
|
||||
setIsFetchingDownloadData(false)
|
||||
})
|
||||
.catch()
|
||||
|
||||
return () => {
|
||||
abortController.abort()
|
||||
}
|
||||
}, [url])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen gap-10 pt-10">
|
||||
<div className="flex flex-col h-screen gap-2 pt-10">
|
||||
{/* Main Content */}
|
||||
<div className="flex flex-col flex-1 w-full max-w-3xl gap-6 mx-auto">
|
||||
<div className="flex flex-col flex-1 w-full max-w-3xl gap-4 mx-auto">
|
||||
<Input
|
||||
label="URL"
|
||||
placeholder="Enter a URL"
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
fullWidth={true}
|
||||
description="Supports Youtube, TikTok, SoundCloud, Google Drive, etc."
|
||||
size="lg"
|
||||
data-focus-visible="false"
|
||||
autoComplete="off"
|
||||
@@ -105,6 +213,7 @@ export default function Download() {
|
||||
endContent={
|
||||
<Button
|
||||
variant="faded"
|
||||
color="primary"
|
||||
onPress={() => {
|
||||
setTimeout(() => {
|
||||
navigator.clipboard.readText().then((text) => {
|
||||
@@ -120,13 +229,57 @@ export default function Download() {
|
||||
|
||||
{/* Path Display */}
|
||||
<PathField
|
||||
path={source || ''}
|
||||
setPath={setSource}
|
||||
path={destination || ''}
|
||||
setPath={setDestination}
|
||||
label="Destination"
|
||||
description="Select the destination folder or manually enter a folder path"
|
||||
placeholder="Enter a remote:/path as destination"
|
||||
showPicker={true}
|
||||
showFiles={false}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Filename"
|
||||
placeholder="Enter a filename"
|
||||
description="Make sure to include an extension"
|
||||
value={filename}
|
||||
onChange={(e) => setFilename(e.target.value)}
|
||||
fullWidth={true}
|
||||
isDisabled={!url || !destination}
|
||||
size="lg"
|
||||
data-focus-visible="false"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center flex-1 overflow-hidden">
|
||||
{isFetchingDownloadData && <Spinner size="lg" />}
|
||||
|
||||
{!isFetchingDownloadData &&
|
||||
downloadData &&
|
||||
downloadData.type === 'video' &&
|
||||
!isYoutubeUrl(url || '') && (
|
||||
<MuxPlayer
|
||||
autoPlay={true}
|
||||
muted={true}
|
||||
// controls={true}
|
||||
src={downloadData.url}
|
||||
className="object-contain w-full h-64"
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isFetchingDownloadData && downloadData && downloadData.type === 'image' && (
|
||||
<Image src={downloadData.url} className="object-contain w-full h-64" />
|
||||
)}
|
||||
|
||||
{!isFetchingDownloadData && downloadData && downloadData.type === 'audio' && (
|
||||
<audio src={downloadData.url} controls={true}>
|
||||
<track kind="captions" src="" srcLang="en" />
|
||||
</audio>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="sticky bottom-0 z-50 flex items-center justify-center flex-none gap-2 p-4 border-t border-neutral-500/20 bg-neutral-900/50 backdrop-blur-lg">
|
||||
@@ -137,7 +290,7 @@ export default function Download() {
|
||||
color="primary"
|
||||
size="lg"
|
||||
onPress={() => {
|
||||
setSource(undefined)
|
||||
setDestination(undefined)
|
||||
setIsStarted(false)
|
||||
}}
|
||||
data-focus-visible="false"
|
||||
@@ -164,7 +317,7 @@ export default function Download() {
|
||||
fullWidth={true}
|
||||
type="button"
|
||||
color="primary"
|
||||
isDisabled={isLoading || !source}
|
||||
isDisabled={isLoading || !destination || isFetchingDownloadData}
|
||||
isLoading={isLoading}
|
||||
endContent={buttonIcon}
|
||||
className="max-w-2xl gap-2"
|
||||
|
||||
Reference in New Issue
Block a user