Skip to content

Commit

Permalink
Mp4-convert
Browse files Browse the repository at this point in the history
  • Loading branch information
MetinVn committed Aug 18, 2024
1 parent ba58b97 commit f60ba8d
Show file tree
Hide file tree
Showing 22 changed files with 733 additions and 274 deletions.
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="./public/converter.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Convert YouTube videos to MP3 quickly and easily with our online converter. Simple, fast, and free to use!" />
<title>MP3 Converter</title>
<title>YouTube Converter</title>
</head>
<body>
<div id="root"></div>
Expand Down
Binary file added public/converter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

228 changes: 84 additions & 144 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,171 +1,111 @@
import { useEffect, useRef, useState } from "react";
import axios from "axios";
import { toast, ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

import { youtube_parser } from "./utils/YoutubeParser";
import { getAllMP3s, saveMP3 } from "./utils/IndexedDB";
import { fetchStoredMP3s } from "./utils/FetchStoredMP3";
import { fetchMP3Data } from "./utils/HandleSubmitMP3";
import { fetchMP4Data } from "./utils/HandleSubmitMP4";
import { fetchStoredMP4s } from "./utils/FetchStoredMP4";

import Header from "./components/Header";
import LoadingAnimation from "./components/LoadingAnimation";
import Button from "./components/Button";
import Input from "./components/Inputfield";
import Dashboard from "./components/Dashboard";
import ResultLink from "./components/ResultLink";
import Footer from "./components/Footer";
import Select from "./components/SelectElement";

function App() {
const inputUrl = useRef();
const [result, setResult] = useState(null);
const [title, setTitle] = useState(null);
const [loading, setLoading] = useState(false);
const [mp3List, setMp3List] = useState({});
const [convertType, setConvertType] = useState("mp3");

useEffect(() => {
const fetchStoredMP3s = async () => {
const storedMP3s = await getAllMP3s();
if (storedMP3s.length > 0) {
setMp3List(
storedMP3s.reduce((acc, mp3) => {
acc[mp3.url] = mp3;
return acc;
}, {})
);
} else {
toast.info("No stored MP3s found.");
}
};

fetchStoredMP3s();
}, []);

const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);

const youtubeURL = inputUrl.current.value;
const youtubeID = youtube_parser(youtubeURL);

if (youtubeURL.trim() === "") {
setLoading(false);
toast.error("The URL field can't be empty.");
return;
}

if (!youtubeID) {
setLoading(false);
toast.error("Invalid YouTube URL. Please provide a valid video URL.");
return;
}
//Mp3 variables
const [list, setMp3List] = useState({});
//Mp4 variables
const [mp4List, setMP4List] = useState({});

toast.promise(
new Promise(async (resolve, reject) => {
const options = {
method: "get",
url: "https://youtube-mp36.p.rapidapi.com/dl",
headers: {
"X-RapidAPI-Key": import.meta.env.VITE_RAPID_API_KEY,
"X-RapidAPI-Host": "youtube-mp36.p.rapidapi.com",
},
params: {
id: youtubeID,
},
};
const options = [
{ value: "mp3", label: "MP3" },
{ value: "mp4", label: "MP4" },
];

try {
const response = await axios(options);
const mp3Data = {
title: response.data.title,
url: response.data.link,
};

if (!mp3Data.url) {
toast.error(
"The conversion was successful, but no download link was provided. Please try again."
);
setLoading(false);
reject(new Error("No download link provided"));
return;
}

setResult(mp3Data.url);
setTitle(mp3Data.title);
setMp3List((prevList) => ({
...prevList,
[mp3Data.url]: mp3Data,
}));

await saveMP3(mp3Data);
setLoading(false);
resolve();
} catch (error) {
setLoading(false);
toast.error("Error occurred during conversion. Please try again.");
reject(error);
console.warn(error);
}
}),
{
pending: "Sending request...",
success: "Conversion successful!",
error: "Error occurred during conversion. Please try again.",
}
);

inputUrl.current.value = "";
const handleSelectChange = (e) => {
setConvertType(e.target.value);
};

useEffect(() => {
fetchStoredMP3s(setMp3List, toast);
fetchStoredMP4s(setMP4List, toast);
}, []);

return (
<>
<div className="min-h-screen flex flex-col justify-between bg-white dark:bg-[#1E1E1E] transition-all duration-300">
<div className="flex flex-col justify-center items-center flex-grow">
<div className="max-w-[500px] w-full text-center">
<Header />
<h1 className="text-2xl sm:text-4xl font-bold text-[#333] dark:text-white mb-4 transition-colors duration-300">
YouTube to MP3 Converter
</h1>
<h2 className="text-sm sm:text-lg text-[#666] dark:text-[#ccc] mb-6 transition-colors duration-300">
Transform YouTube videos into MP3s in just a few clicks!
</h2>
<form
onSubmit={handleSubmit}
className="flex flex-col items-center gap-3">
<Input
ref={inputUrl}
placeholder="Paste a Youtube video URL link..."
className="text-[#333] dark:text-white dark:bg-[#333] dark:border-[#444]"
/>
{loading ? (
<LoadingAnimation />
) : (
<Button
ariaLabel="Convert"
children={null}
type="submit"
className="bg-[#4CAF50] text-white hover:bg-[#388E3C]">
Convert
</Button>
)}
</form>
<div className="mt-4">
{result && <ResultLink href={result} title={title} />}
</div>
<div className="min-h-screen flex flex-col justify-between bg-white dark:bg-[#1E1E1E] transition-all duration-300">
<div className="flex flex-col justify-center items-center flex-grow my-20 md:my-0">
<div className="max-w-[500px] w-full text-center">
<Header />
<h1 className="text-2xl sm:text-4xl font-bold text-[#333] dark:text-white mb-4 transition-colors duration-300">
YouTube to MP3 Converter
</h1>
<h2 className="text-sm sm:text-lg text-[#666] dark:text-[#ccc] mb-6 transition-colors duration-300">
Transform YouTube videos into MP3s in just a few clicks!
</h2>
<div>
{loading ? (
<LoadingAnimation />
) : (
<div className="w-full flex flex-col md:flex-row items-center justify-center gap-2">
<Input
ref={inputUrl}
placeholder="Paste a Youtube video URL link..."
className="text-[#333] dark:text-white dark:bg-[#333] dark:border-[#444]"
/>
{convertType === "mp3" && (
<Button
onClick={(e) =>
fetchMP3Data(e, setLoading, setMp3List, inputUrl, toast)
}
ariaLabel="Convert"
className="bg-[#4CAF50] text-white hover:bg-[#388E3C]">
Convert
</Button>
)}
{convertType === "mp4" && (
<Button
onClick={(e) =>
fetchMP4Data(e, setLoading, setMP4List, inputUrl, toast)
}
ariaLabel="Convert"
className="bg-[#4CAF50] text-white hover:bg-[#388E3C]">
Convert
</Button>
)}
<Select
value={convertType}
onChange={handleSelectChange}
options={options}
className="w-40"
/>
</div>
)}
</div>
<ToastContainer
position="bottom-right"
draggable="touch"
draggableDirection="y"
/>
<Dashboard
mp3List={mp3List}
setMp3List={setMp3List}
toast={toast}
toastContainer={ToastContainer}
/>
</div>
<Footer />
<ToastContainer
position="bottom-right"
draggable="touch"
draggableDirection="y"
/>
<Dashboard
mp4List={mp4List}
mp3List={list}
setMp3List={setMp3List}
setMP4List={setMP4List}
toast={toast}
toastContainer={ToastContainer}
/>
</div>
</>
<Footer />
</div>
);
}

Expand Down
11 changes: 1 addition & 10 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
const Button = ({
onClick = () => {},
children = null,
className = "",
ariaLabel = "",
}) => {
const accessibleLabel =
ariaLabel || (typeof children === "string" ? children : "Button");

const Button = ({ onClick = () => {}, children = null, className = "" }) => {
return (
<button
aria-label={accessibleLabel}
onClick={onClick}
className={`px-4 py-2 rounded transition-colors duration-300 ${className}`}>
{children}
Expand Down
Loading

0 comments on commit f60ba8d

Please sign in to comment.