mirror of
https://github.com/neosubhamoy/pytubepp-helper.git
synced 2026-02-04 11:22:22 +05:30
442 lines
28 KiB
TypeScript
442 lines
28 KiB
TypeScript
import clsx from "clsx";
|
|
import { useState, useEffect } from "react";
|
|
import { Link } from "react-router-dom";
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
|
import { InstalledPrograms } from "@/types";
|
|
import { compareVersions, extractVersion, isInstalled, registerMacFiles } from "@/lib/utils";
|
|
import { CircleCheck, TriangleAlert, CircleAlert, Settings, RefreshCcw, Loader2, PackagePlus } from "lucide-react";
|
|
import { getPlatformInfo } from "@/lib/platform-utils";
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
|
import { useToast } from "@/hooks/use-toast";
|
|
|
|
export default function HomePage() {
|
|
const { toast } = useToast();
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [isWindows, setIsWindows] = useState<boolean>(false)
|
|
const [windowsVersion, setWindowsVersion] = useState<string | null>(null)
|
|
const [isMacOs, setIsMacOs] = useState<boolean>(false)
|
|
const [macOsVersion, setMacOsVersion] = useState<string | null>(null)
|
|
const [distroId, setDistroId] = useState<string | null>(null)
|
|
const [distroPkgMngr, setDistroPkgMngr] = useState<string | null>(null)
|
|
const [installedPrograms, setInstalledPrograms] = useState<InstalledPrograms>({
|
|
winget: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
apt: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
dnf: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
brew: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
python: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
pip: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
python3: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
pip3: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
ffmpeg: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
nodejs: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
pytubepp: {
|
|
installed: false,
|
|
version: null,
|
|
},
|
|
});
|
|
|
|
function checkAllPrograms() {
|
|
return Promise.all([
|
|
isInstalled('winget', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
winget: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('apt', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
apt: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('dnf', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
dnf: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('homebrew', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
brew: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('python', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
python: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('pip', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
pip: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('python3', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
python3: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('pip3', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
pip3: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('ffmpeg', '-version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
ffmpeg: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('nodejs', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
nodejs: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
}),
|
|
isInstalled('pytubepp', '--version').then((result) => {
|
|
setInstalledPrograms((prevState) => ({
|
|
...prevState,
|
|
pytubepp: {
|
|
installed: result.installed,
|
|
version: result.output ? extractVersion(result.output) : null,
|
|
}
|
|
}));
|
|
})
|
|
]);
|
|
}
|
|
|
|
const fetchPlatformInfo = async () => {
|
|
const info = await getPlatformInfo();
|
|
setIsWindows(info.isWindows);
|
|
setWindowsVersion(info.windowsVersion);
|
|
setIsMacOs(info.isMacOs);
|
|
setMacOsVersion(info.macOsVersion);
|
|
setDistroId(info.distroId);
|
|
setDistroPkgMngr(info.distroPkgMngr);
|
|
};
|
|
|
|
useEffect(() => {
|
|
const init = async () => {
|
|
try {
|
|
setIsLoading(true);
|
|
await Promise.all([
|
|
checkAllPrograms(),
|
|
fetchPlatformInfo()
|
|
]);
|
|
} catch (error) {
|
|
console.error(error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
init();
|
|
}, []);
|
|
|
|
return (
|
|
<div className="container">
|
|
<div className={clsx("topbar flex justify-between items-center mt-5", !isWindows && "mx-3")}>
|
|
<h1 className="text-xl font-bold">PytubePP Helper</h1>
|
|
<div className="flex items-center">
|
|
<Tooltip>
|
|
<TooltipTrigger>
|
|
<Button variant="outline" size="icon" asChild>
|
|
<Link to="/settings">
|
|
<Settings className="w-5 h-5"/>
|
|
</Link>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent><p>settings</p></TooltipContent>
|
|
</Tooltip>
|
|
{ isMacOs && macOsVersion && compareVersions(macOsVersion, '10.13') > 0 ?
|
|
<Tooltip>
|
|
<TooltipTrigger>
|
|
<Button className="ml-3" size="icon" onClick={async () => {
|
|
const result = await registerMacFiles();
|
|
toast({ title: result.message, variant: result.success ? 'default' : 'destructive' });
|
|
}}>
|
|
<PackagePlus className="w-5 h-5"/>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent><p>register to mac</p></TooltipContent>
|
|
</Tooltip>
|
|
:
|
|
null
|
|
}
|
|
<Tooltip>
|
|
<TooltipTrigger>
|
|
<Button className="ml-3" size="icon" disabled={isLoading} onClick={checkAllPrograms}>
|
|
<RefreshCcw className="w-5 h-5"/>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent><p>refresh</p></TooltipContent>
|
|
</Tooltip>
|
|
</div>
|
|
</div>
|
|
{ isLoading ?
|
|
<div className="mt-5 mx-3">
|
|
<div className="flex flex-col">
|
|
<div className="flex items-center justify-center py-[4.3rem]">
|
|
<div className="flex flex-col items-center justify-center">
|
|
<Loader2 className="h-8 w-8 animate-spin"/>
|
|
<p className="ml-3 mt-2 text-muted-foreground">checking...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
: distroId && distroPkgMngr && distroPkgMngr === 'apt' ? /* Section for Debian */
|
|
<div className="programstats mt-5 mx-3">
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Python:</b> {installedPrograms.python3.installed ? 'installed' : 'not installed'} {installedPrograms.python3.version ? `(${installedPrograms.python3.version})` : ''}</p>
|
|
{installedPrograms.python3.installed ? installedPrograms.python3.version ? compareVersions(installedPrograms.python3.version, '3.8') < 0 ? <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.apt.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo apt install python3 -y'})}}>install</Button> : <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>FFmpeg:</b> {installedPrograms.ffmpeg.installed ? 'installed' : 'not installed'} {installedPrograms.ffmpeg.version ? `(${installedPrograms.ffmpeg.version})` : ''}</p>
|
|
{installedPrograms.ffmpeg.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.apt.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo apt install ffmpeg -y'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Node.js:</b> {installedPrograms.nodejs.installed ? 'installed' : 'not installed'} {installedPrograms.nodejs.version ? `(${installedPrograms.nodejs.version})` : ''}</p>
|
|
{installedPrograms.nodejs.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.apt.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo apt install nodejs -y'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>PytubePP:</b> {installedPrograms.pytubepp.installed ? 'installed' : 'not installed'} {installedPrograms.pytubepp.version ? `(${installedPrograms.pytubepp.version})` : ''}</p>
|
|
{installedPrograms.pytubepp.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.pip3.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'pip3 install pytubepp || pip3 install pytubepp --break-system-packages'})}}>install</Button> : null}
|
|
</div>
|
|
{(!installedPrograms.apt.installed && (!installedPrograms.python3.installed || !installedPrograms.ffmpeg.installed)) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>APT Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
APT is required to install necessary debian packages. Please install it manually for your distro.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(!installedPrograms.pip3.installed && !installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>PIP Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
PIP is required to install necessary python packages. Please install it now to continue: <Button variant="link" className="text-blue-600 p-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo apt install python3-pip -y'})}}>install</Button>
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(installedPrograms.python3.installed && installedPrograms.ffmpeg.installed && installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5">
|
|
<CircleCheck className="h-5 w-5" />
|
|
<AlertTitle>Ready</AlertTitle>
|
|
<AlertDescription>
|
|
Everything looks ok! You can close this window now. Make sure it's always running in the background.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
</div>
|
|
: distroId && distroPkgMngr && distroPkgMngr === 'dnf' ? /* Section for RHEL */
|
|
<div className="programstats mt-5 mx-3">
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Python:</b> {installedPrograms.python3.installed ? 'installed' : 'not installed'} {installedPrograms.python3.version ? `(${installedPrograms.python3.version})` : ''}</p>
|
|
{installedPrograms.python3.installed ? installedPrograms.python3.version ? compareVersions(installedPrograms.python3.version, '3.8') < 0 ? <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.dnf.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo dnf install python3 -y'})}}>install</Button> : <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>FFmpeg:</b> {installedPrograms.ffmpeg.installed ? 'installed' : 'not installed'} {installedPrograms.ffmpeg.version ? `(${installedPrograms.ffmpeg.version})` : ''}</p>
|
|
{installedPrograms.ffmpeg.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.dnf.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo dnf install ffmpeg -y'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Node.js:</b> {installedPrograms.nodejs.installed ? 'installed' : 'not installed'} {installedPrograms.nodejs.version ? `(${installedPrograms.nodejs.version})` : ''}</p>
|
|
{installedPrograms.nodejs.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.dnf.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo dnf install nodejs -y'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>PytubePP:</b> {installedPrograms.pytubepp.installed ? 'installed' : 'not installed'} {installedPrograms.pytubepp.version ? `(${installedPrograms.pytubepp.version})` : ''}</p>
|
|
{installedPrograms.pytubepp.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.pip3.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'pip3 install pytubepp || pip3 install pytubepp --break-system-packages'})}}>install</Button> : null}
|
|
</div>
|
|
{(!installedPrograms.dnf.installed && (!installedPrograms.python3.installed || !installedPrograms.ffmpeg.installed)) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>DNF Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
DNF is required to install necessary rpm packages. Please install it manually for your distro.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(!installedPrograms.pip3.installed && !installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>PIP Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
PIP is required to install necessary python packages. Please install it now to continue: <Button variant="link" className="text-blue-600 p-0" onClick={async () => { await invoke('install_program', {icommand: 'sudo dnf install python3-pip -y'})}}>install</Button>
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(installedPrograms.python3.installed && installedPrograms.ffmpeg.installed && installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5">
|
|
<CircleCheck className="h-5 w-5" />
|
|
<AlertTitle>Ready</AlertTitle>
|
|
<AlertDescription>
|
|
Everything looks ok! You can close this window now. Make sure it's always running in the background.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
</div>
|
|
: isWindows && windowsVersion && parseInt(windowsVersion) >= 17134 ? /* Section for Windows */
|
|
<div className="programstats mt-5">
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Python:</b> {installedPrograms.python.installed ? 'installed' : 'not installed'} {installedPrograms.python.version ? `(${installedPrograms.python.version})` : ''}</p>
|
|
{installedPrograms.python.installed ? installedPrograms.python.version ? compareVersions(installedPrograms.python.version, '3.8') < 0 ? <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.winget.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'winget install Python.Python.3.12'})}}>install</Button> : <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>FFmpeg:</b> {installedPrograms.ffmpeg.installed ? 'installed' : 'not installed'} {installedPrograms.ffmpeg.version ? `(${installedPrograms.ffmpeg.version})` : ''}</p>
|
|
{installedPrograms.ffmpeg.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.winget.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'winget install ffmpeg'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Node.js:</b> {installedPrograms.nodejs.installed ? 'installed' : 'not installed'} {installedPrograms.nodejs.version ? `(${installedPrograms.nodejs.version})` : ''}</p>
|
|
{installedPrograms.nodejs.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.winget.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'winget install OpenJS.NodeJS.LTS'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>PytubePP:</b> {installedPrograms.pytubepp.installed ? 'installed' : 'not installed'} {installedPrograms.pytubepp.version ? `(${installedPrograms.pytubepp.version})` : ''}</p>
|
|
{installedPrograms.pytubepp.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.pip.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'pip install pytubepp'})}}>install</Button> : null}
|
|
</div>
|
|
{(!installedPrograms.winget.installed && (!installedPrograms.python.installed || !installedPrograms.ffmpeg.installed)) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>WinGet Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
WinGet is required to install necessary packages. Please install it manually from <a className="underline" href="https://learn.microsoft.com/en-us/windows/package-manager/winget/#install-winget" target="_blank">here</a>.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(installedPrograms.python.installed && installedPrograms.ffmpeg.installed && installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5">
|
|
<CircleCheck className="h-5 w-5" />
|
|
<AlertTitle>Ready</AlertTitle>
|
|
<AlertDescription>
|
|
Everything looks ok! You can close this window now. Make sure it's always running in the background.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
</div>
|
|
: isMacOs && macOsVersion && compareVersions(macOsVersion, '10.13') > 0 ? /* Section for macOS */
|
|
<div className="programstats mt-5 mx-3">
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Python:</b> {installedPrograms.python3.installed ? 'installed' : 'not installed'} {installedPrograms.python3.version ? `(${installedPrograms.python3.version})` : ''}</p>
|
|
{installedPrograms.python3.installed ? installedPrograms.python3.version ? compareVersions(installedPrograms.python3.version, '3.8') < 0 ? <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.brew.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'brew install python'})}}>install</Button> : <TriangleAlert className="w-5 h-5 my-2 text-orange-400"/> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>FFmpeg:</b> {installedPrograms.ffmpeg.installed ? 'installed' : 'not installed'} {installedPrograms.ffmpeg.version ? `(${installedPrograms.ffmpeg.version})` : ''}</p>
|
|
{installedPrograms.ffmpeg.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.brew.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'brew install ffmpeg'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>Node.js:</b> {installedPrograms.nodejs.installed ? 'installed' : 'not installed'} {installedPrograms.nodejs.version ? `(${installedPrograms.nodejs.version})` : ''}</p>
|
|
{installedPrograms.nodejs.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.brew.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'brew install node'})}}>install</Button> : null}
|
|
</div>
|
|
<div className="programitem flex items-center justify-between">
|
|
<p><b>PytubePP:</b> {installedPrograms.pytubepp.installed ? 'installed' : 'not installed'} {installedPrograms.pytubepp.version ? `(${installedPrograms.pytubepp.version})` : ''}</p>
|
|
{installedPrograms.pytubepp.installed ? <CircleCheck className="w-5 h-5 my-2 text-green-400"/> : installedPrograms.pip3.installed ? <Button variant="link" className="text-blue-600 px-0" onClick={async () => { await invoke('install_program', {icommand: 'pip3 install pytubepp || pip3 install pytubepp --break-system-packages'})}}>install</Button> : null}
|
|
</div>
|
|
{(!installedPrograms.brew.installed && (!installedPrograms.python3.installed || !installedPrograms.ffmpeg.installed)) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>Homebrew Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
Homebrew is required to install necessary unix packages. Please install it manually for your mac.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(!installedPrograms.pip3.installed && !installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>PIP Not Found</AlertTitle>
|
|
<AlertDescription>
|
|
PIP is required to install necessary python packages. Please install it now to continue: <Button variant="link" className="text-blue-600 p-0" onClick={async () => { await invoke('install_program', {icommand: 'brew install python3-pip -y'})}}>install</Button>
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
{(installedPrograms.python3.installed && installedPrograms.ffmpeg.installed && installedPrograms.nodejs.installed && installedPrograms.pytubepp.installed) ?
|
|
<Alert className="mt-5">
|
|
<CircleCheck className="h-5 w-5" />
|
|
<AlertTitle>Ready</AlertTitle>
|
|
<AlertDescription>
|
|
Everything looks ok! You can close this window now. Make sure it's always running in the background.
|
|
</AlertDescription>
|
|
</Alert>
|
|
: null}
|
|
</div>
|
|
:
|
|
<div className="programstats mt-5 mx-3">
|
|
<Alert className="mt-5" variant="destructive">
|
|
<CircleAlert className="h-5 w-5" />
|
|
<AlertTitle>Unsupported OS</AlertTitle>
|
|
<AlertDescription>
|
|
Sorry, your os/distro is currently not supported. If you think this is just a mistake or you want to request us to add support for your os/distro you can create a github issue <a className="underline" href="https://github.com/neosubhamoy/pytubepp-helper/issues" target="_blank">here</a>.
|
|
</AlertDescription>
|
|
</Alert>
|
|
</div>
|
|
}
|
|
</div>
|
|
);
|
|
}
|