mirror of
https://github.com/arkorty/DownLink.git
synced 2026-03-17 16:51:45 +00:00
UI: did a visual overhaul
This commit is contained in:
Binary file not shown.
@@ -3,6 +3,9 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.13.3",
|
||||||
|
"@emotion/styled": "^11.13.0",
|
||||||
|
"@mui/material": "^5.16.7",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ import React from "react";
|
|||||||
import Particles from "react-particles";
|
import Particles from "react-particles";
|
||||||
import { loadSlim } from "tsparticles-slim";
|
import { loadSlim } from "tsparticles-slim";
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
background: "191825",
|
||||||
|
particle: "FFA3FD",
|
||||||
|
link: "865DFF",
|
||||||
|
};
|
||||||
|
|
||||||
const Background = () => {
|
const Background = () => {
|
||||||
const particlesInit = async (engine) => {
|
const particlesInit = async (engine) => {
|
||||||
await loadSlim(engine);
|
await loadSlim(engine);
|
||||||
@@ -14,16 +20,12 @@ const Background = () => {
|
|||||||
options={{
|
options={{
|
||||||
background: {
|
background: {
|
||||||
color: {
|
color: {
|
||||||
value: "#2c2c2c",
|
value: colors.background,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fpsLimit: 60,
|
fpsLimit: 60,
|
||||||
interactivity: {
|
interactivity: {
|
||||||
events: {
|
events: {
|
||||||
onClick: {
|
|
||||||
enable: true,
|
|
||||||
mode: "push",
|
|
||||||
},
|
|
||||||
onHover: {
|
onHover: {
|
||||||
enable: true,
|
enable: true,
|
||||||
mode: "repulse",
|
mode: "repulse",
|
||||||
@@ -31,26 +33,19 @@ const Background = () => {
|
|||||||
resize: true,
|
resize: true,
|
||||||
},
|
},
|
||||||
modes: {
|
modes: {
|
||||||
push: {
|
|
||||||
quantity: 4,
|
|
||||||
limit: 20,
|
|
||||||
},
|
|
||||||
remove: {
|
|
||||||
quantity: 4,
|
|
||||||
},
|
|
||||||
repulse: {
|
repulse: {
|
||||||
distance: 200,
|
distance: 200,
|
||||||
duration: 0.8,
|
duration: 0.8,
|
||||||
speed: 0.03,
|
speed: 0.05,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
particles: {
|
particles: {
|
||||||
color: {
|
color: {
|
||||||
value: "#d0d0d0",
|
value: colors.particle,
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
color: "#a0a0a0",
|
color: colors.link,
|
||||||
distance: 150,
|
distance: 150,
|
||||||
enable: true,
|
enable: true,
|
||||||
opacity: 0.5,
|
opacity: 0.5,
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ import axios from "axios";
|
|||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import Confetti from "react-confetti";
|
import Confetti from "react-confetti";
|
||||||
import Notification from "./Notification";
|
import Notification from "./Notification";
|
||||||
|
import {
|
||||||
|
TextField,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
InputLabel,
|
||||||
|
FormControl,
|
||||||
|
CircularProgress,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
const DownloadForm = () => {
|
const DownloadForm = () => {
|
||||||
const [url, setUrl] = useState("");
|
const [url, setUrl] = useState("");
|
||||||
@@ -71,7 +79,7 @@ const DownloadForm = () => {
|
|||||||
const getBarClass = () => {
|
const getBarClass = () => {
|
||||||
if (message === "Download Complete") return "bg-green-400";
|
if (message === "Download Complete") return "bg-green-400";
|
||||||
if (message === "Download Failed") return "bg-red-400";
|
if (message === "Download Failed") return "bg-red-400";
|
||||||
return "bg-blue-400";
|
return "bg-purple-600";
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBarStyle = () => ({
|
const getBarStyle = () => ({
|
||||||
@@ -93,42 +101,63 @@ const DownloadForm = () => {
|
|||||||
}, [showConfetti]);
|
}, [showConfetti]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="md: p-4 mt-12 relative">
|
<div className="p-6 relative">
|
||||||
<form onSubmit={handleDownload} className="space-y-4">
|
<form onSubmit={handleDownload} className="space-y-4">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
<label
|
<FormControl fullWidth variant="outlined" size="small">
|
||||||
htmlFor="url"
|
<TextField
|
||||||
className="block text-sm font-medium text-gray-300 text-left"
|
id="url"
|
||||||
>
|
value={url}
|
||||||
Video URL
|
onChange={(e) => setUrl(e.target.value)}
|
||||||
</label>
|
label="Video URL"
|
||||||
<input
|
placeholder="Enter video URL"
|
||||||
type="text"
|
variant="outlined"
|
||||||
id="url"
|
size="small"
|
||||||
value={url}
|
InputProps={{
|
||||||
onChange={(e) => setUrl(e.target.value)}
|
style: {
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 bg-zinc-800 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm text-gray-300"
|
color: "#fff",
|
||||||
placeholder="Enter video URL"
|
backgroundColor: "#1f2937",
|
||||||
/>
|
},
|
||||||
|
}}
|
||||||
|
InputLabelProps={{
|
||||||
|
style: { color: "#9ca3af" },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 w-18">
|
<div className="flex-shrink-0 w-18">
|
||||||
<label
|
<FormControl
|
||||||
htmlFor="quality"
|
fullWidth
|
||||||
className="block text-sm font-medium text-gray-300 text-left"
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
sx={{ minWidth: 112 }}
|
||||||
>
|
>
|
||||||
Quality
|
<InputLabel htmlFor="quality" sx={{ color: "#9ca3af" }}>
|
||||||
</label>
|
Quality
|
||||||
<select
|
</InputLabel>
|
||||||
id="quality"
|
<Select
|
||||||
value={quality}
|
id="quality"
|
||||||
onChange={(e) => setQuality(e.target.value)}
|
value={quality}
|
||||||
className="mt-1 block w-full px-3 py-2 border border-gray-300 bg-zinc-800 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm text-gray-300"
|
onChange={(e) => setQuality(e.target.value)}
|
||||||
>
|
label="Quality"
|
||||||
<option value="360p">Standard</option>
|
variant="outlined"
|
||||||
<option value="480p">High</option>
|
size="small"
|
||||||
<option value="720p">Ultra</option>
|
MenuProps={{
|
||||||
</select>
|
PaperProps: {
|
||||||
|
style: {
|
||||||
|
backgroundColor: "#1f2937",
|
||||||
|
color: "#fff",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
sx={{ backgroundColor: "#1f2937", color: "#fff" }}
|
||||||
|
>
|
||||||
|
<MenuItem value="360p">Standard</MenuItem>
|
||||||
|
<MenuItem value="480p">High</MenuItem>
|
||||||
|
<MenuItem value="720p">Ultra</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -147,7 +176,7 @@ const DownloadForm = () => {
|
|||||||
></div>
|
></div>
|
||||||
{isDownloading && progress === 0 && (
|
{isDownloading && progress === 0 && (
|
||||||
<div
|
<div
|
||||||
className={`absolute top-0 left-0 w-full h-full bg-blue-400 rounded-full`}
|
className={`absolute top-0 left-0 w-full h-full bg-purple-400 rounded-full`}
|
||||||
style={getAnimationStyle()}
|
style={getAnimationStyle()}
|
||||||
></div>
|
></div>
|
||||||
)}
|
)}
|
||||||
@@ -165,10 +194,14 @@ const DownloadForm = () => {
|
|||||||
{!isDownloading && !message.startsWith("Downloading") && (
|
{!isDownloading && !message.startsWith("Downloading") && (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="relative inline-flex items-center px-10 py-6 text-2xl font-bold rounded-2xl text-white bg-black bg-opacity-60 border border-white hover:shadow-lg focus:outline-none transition-all duration-300"
|
className="relative inline-flex items-center px-10 py-6 text-2xl font-bold rounded-2xl text-white bg-purple-900 bg-opacity-60 focus:outline-none transition-all duration-300"
|
||||||
>
|
>
|
||||||
<span className="absolute inset-0 bg-black opacity-0 transition-opacity duration-300 ease-in-out active:opacity-40 rounded-2xl"></span>
|
<span className="absolute inset-0 bg-black opacity-0 transition-opacity duration-300 ease-in-out active:opacity-40 rounded-2xl"></span>
|
||||||
Download
|
{isDownloading ? (
|
||||||
|
<CircularProgress size={24} color="inherit" />
|
||||||
|
) : (
|
||||||
|
"Download"
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -194,33 +227,6 @@ const DownloadForm = () => {
|
|||||||
onClose={() => setNotification(null)}
|
onClose={() => setNotification(null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<style jsx>{`
|
|
||||||
@keyframes loading {
|
|
||||||
0% {
|
|
||||||
transform: translateX(-100%);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(100%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes gradientFlow {
|
|
||||||
0% {
|
|
||||||
background-position: 0% 0%;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
background-position: 100% 100%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-position: 0% 0%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.animate-gradient {
|
|
||||||
background-size: 300% 300%;
|
|
||||||
animation: gradientFlow 15s ease infinite;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import React from "react";
|
|||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="text-white bg-black bg-opacity-60 p-4">
|
<header className="text-white bg-purple-900 bg-opacity-60 px-8 py-6">
|
||||||
<h1 className="text-xl font-bold">DownLink</h1>
|
<h1 className="text-3xl font-bold">DownLink</h1>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,3 +15,29 @@ code {
|
|||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
|
||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes loading {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gradientFlow {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 0%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-position: 100% 100%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 0% 0%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-gradient {
|
||||||
|
background-size: 300% 300%;
|
||||||
|
animation: gradientFlow 15s ease infinite;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user