1
1
mirror of https://github.com/neosubhamoy/neodlp.git synced 2026-02-04 15:22:23 +05:30

fix: downloading appimage update on native deb/rpm installation

This commit is contained in:
2026-01-17 22:06:06 +05:30
Verified
parent 49f5203377
commit 5f3728a8fd

View File

@@ -14,214 +14,238 @@ import { Button } from "@/components/ui/button";
import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"; import { AlertDialog, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
import { Progress } from "@/components/ui/progress"; import { Progress } from "@/components/ui/progress";
import useAppUpdater from "@/helpers/use-app-updater"; import useAppUpdater from "@/helpers/use-app-updater";
import { platform } from "@tauri-apps/plugin-os";
import * as fs from "@tauri-apps/plugin-fs";
export function AppSidebar() { export function AppSidebar() {
const downloadStates = useDownloadStatesStore(state => state.downloadStates); const downloadStates = useDownloadStatesStore(state => state.downloadStates);
const ongoingDownloads = downloadStates.filter(state => const ongoingDownloads = downloadStates.filter(state =>
['starting', 'downloading', 'queued'].includes(state.download_status) ['starting', 'downloading', 'queued'].includes(state.download_status)
); );
const appVersion = useSettingsPageStatesStore(state => state.appVersion); const appVersion = useSettingsPageStatesStore(state => state.appVersion);
const isFetchingAppVersion = useSettingsPageStatesStore(state => state.isFetchingAppVersion); const isFetchingAppVersion = useSettingsPageStatesStore(state => state.isFetchingAppVersion);
const appUpdate = useSettingsPageStatesStore(state => state.appUpdate); const appUpdate = useSettingsPageStatesStore(state => state.appUpdate);
const isUpdatingApp = useSettingsPageStatesStore(state => state.isUpdatingApp); const isUpdatingApp = useSettingsPageStatesStore(state => state.isUpdatingApp);
const appUpdateDownloadProgress = useSettingsPageStatesStore(state => state.appUpdateDownloadProgress); const appUpdateDownloadProgress = useSettingsPageStatesStore(state => state.appUpdateDownloadProgress);
const location = useLocation(); const currentPlatform = platform();
const { open } = useSidebar(); const location = useLocation();
const { downloadAndInstallAppUpdate } = useAppUpdater(); const { open } = useSidebar();
const [showBadge, setShowBadge] = useState(false); const { downloadAndInstallAppUpdate } = useAppUpdater();
const [showUpdateCard, setShowUpdateCard] = useState(false); const [showBadge, setShowBadge] = useState(false);
const [showUpdateCard, setShowUpdateCard] = useState(false);
const [isNativeLinuxApp, setIsNativeLinuxApp] = useState(false);
const topItems: Array<RoutesObj> = [ const topItems: Array<RoutesObj> = [
{ {
title: "Downloader", title: "Downloader",
url: "/", url: "/",
icon: Download, icon: Download,
}, },
{ {
title: "Library", title: "Library",
url: "/library", url: "/library",
icon: SquarePlay, icon: SquarePlay,
} }
]; ];
const bottomItems: Array<RoutesObj> = [ const bottomItems: Array<RoutesObj> = [
{ {
title: "Settings", title: "Settings",
url: "/settings", url: "/settings",
icon: Settings, icon: Settings,
} }
]; ];
useEffect(() => { useEffect(() => {
let timeout: NodeJS.Timeout; let timeout: NodeJS.Timeout;
if (open) { if (open) {
timeout = setTimeout(() => { timeout = setTimeout(() => {
setShowBadge(true); setShowBadge(true);
setShowUpdateCard(true); setShowUpdateCard(true);
}, 300); }, 300);
} else { } else {
setShowBadge(false); setShowBadge(false);
setShowUpdateCard(false); setShowUpdateCard(false);
} }
return () => { return () => {
clearTimeout(timeout); clearTimeout(timeout);
}; };
}, [open]); }, [open]);
return ( useEffect(() => {
<Sidebar collapsible="icon"> (async () => {
<SidebarHeader> if (currentPlatform === 'linux') {
<SidebarMenu> const neoDlpExists = await fs.exists('/usr/bin/neodlp');
<SidebarMenuItem> setIsNativeLinuxApp(neoDlpExists);
<SidebarMenuButton size="lg" asChild> }
<a href="#"> })();
<div className="flex aspect-square size-8 items-center justify-center rounded-lg"> }, [currentPlatform]);
<NeoDlpLogo className="size-full rounded-md border border-border [--logo-stop-color-1:#4444FF] [--logo-stop-color-2:#FF43D0] customscheme:[--logo-stop-color-1:var(--color-chart-5)] customscheme:[--logo-stop-color-2:var(--color-chart-1)]" />
</div> return (
<div className="grid flex-1 text-left text-sm leading-tight"> <Sidebar collapsible="icon">
<span className="truncate font-semibold">Neo Downloader Plus</span> <SidebarHeader>
<span className="truncate text-xs">{isFetchingAppVersion ? 'Loading...' : `v${appVersion}`}</span> <SidebarMenu>
</div> <SidebarMenuItem>
</a> <SidebarMenuButton size="lg" asChild>
</SidebarMenuButton> <a href="#">
</SidebarMenuItem> <div className="flex aspect-square size-8 items-center justify-center rounded-lg">
</SidebarMenu> <NeoDlpLogo className="size-full rounded-md border border-border [--logo-stop-color-1:#4444FF] [--logo-stop-color-2:#FF43D0] customscheme:[--logo-stop-color-1:var(--color-chart-5)] customscheme:[--logo-stop-color-2:var(--color-chart-1)]" />
</SidebarHeader> </div>
{/* <SidebarSeparator /> */} <div className="grid flex-1 text-left text-sm leading-tight">
<SidebarContent> <span className="truncate font-semibold">Neo Downloader Plus</span>
<SidebarGroup> <span className="truncate text-xs">{isFetchingAppVersion ? 'Loading...' : `v${appVersion}`}</span>
{/* <SidebarGroupLabel>Tools</SidebarGroupLabel> */} </div>
<SidebarGroupContent> </a>
<SidebarMenu>
{topItems.map((item) => (
<SidebarMenuItem key={item.title}>
{!open ? (
<Tooltip>
<TooltipTrigger asChild>
<SidebarMenuButton
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
className="relative"
asChild
>
<Link to={item.url}>
<item.icon className="stroke-primary" />
<span>{item.title}</span>
{item.title === "Library" && ongoingDownloads.length > 0 && showBadge && (
<Badge className="absolute right-2 inset-y-auto rounded-full font-bold bg-foreground/80">{ongoingDownloads.length}</Badge>
)}
</Link>
</SidebarMenuButton> </SidebarMenuButton>
</TooltipTrigger> </SidebarMenuItem>
<TooltipContent side="right"> </SidebarMenu>
<p>{item.title}</p> </SidebarHeader>
</TooltipContent> {/* <SidebarSeparator /> */}
<SidebarContent>
<SidebarGroup>
{/* <SidebarGroupLabel>Tools</SidebarGroupLabel> */}
<SidebarGroupContent>
<SidebarMenu>
{topItems.map((item) => (
<SidebarMenuItem key={item.title}>
{!open ? (
<Tooltip>
<TooltipTrigger asChild>
<SidebarMenuButton
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
className="relative"
asChild
>
<Link to={item.url}>
<item.icon className="stroke-primary" />
<span>{item.title}</span>
{item.title === "Library" && ongoingDownloads.length > 0 && showBadge && (
<Badge className="absolute right-2 inset-y-auto rounded-full font-bold bg-foreground/80">{ongoingDownloads.length}</Badge>
)}
</Link>
</SidebarMenuButton>
</TooltipTrigger>
<TooltipContent side="right">
<p>{item.title}</p>
</TooltipContent>
</Tooltip>
) : (
<SidebarMenuButton
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
className="relative"
asChild
>
<Link to={item.url}>
<item.icon className="stroke-primary" />
<span>{item.title}</span>
{item.title === "Library" && ongoingDownloads.length > 0 && showBadge && (
<Badge className="absolute right-2 inset-y-auto h-5 min-w-5 rounded-full px-1 font-mono tabular-nums flex items-center justify-center">
<span className="mt-0.5">{ongoingDownloads.length}</span>
</Badge>
)}
</Link>
</SidebarMenuButton>
)}
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
{appUpdate && !open && (
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost">
<CircleArrowUp className="size-4" />
</Button>
</TooltipTrigger>
<TooltipContent side="right">
<p>Update Available <br></br>(Expand sidebar to view update)</p>
</TooltipContent>
</Tooltip> </Tooltip>
) : ( )}
<SidebarMenuButton {appUpdate && open && showUpdateCard && (
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)} <Card className="gap-4 py-0">
className="relative" <CardHeader className="p-4 pb-0">
asChild <CardTitle className="text-sm">Update Available (v{appUpdate?.version || '0.0.0'})</CardTitle>
> <CardDescription>
<Link to={item.url}> A newer version of {config.appName} is available. Please update to the latest version for the best experience.
<item.icon className="stroke-primary" /> </CardDescription>
<span>{item.title}</span> <a className="text-xs font-semibold cursor-pointer mt-1" href={`https://github.com/${config.appRepo}/releases/tag/v${appUpdate?.version || '0.0.0'}`} target="_blank"> Read Changelog</a>
{item.title === "Library" && ongoingDownloads.length > 0 && showBadge && ( </CardHeader>
<Badge className="absolute right-2 inset-y-auto h-5 min-w-5 rounded-full px-1 font-mono tabular-nums flex items-center justify-center"> <CardContent className="grid gap-2.5 p-4">
<span className="mt-0.5">{ongoingDownloads.length}</span> {isNativeLinuxApp ? (
</Badge> <Button
className="w-full"
size="sm"
disabled={ongoingDownloads.length > 0 || isUpdatingApp}
asChild
>
<a href={`https://github.com/${config.appRepo}/releases/tag/v${appUpdate?.version || '0.0.0'}`} target="_blank">Download Now</a>
</Button>
) : (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
className="w-full"
size="sm"
disabled={ongoingDownloads.length > 0 || isUpdatingApp}
onClick={() => downloadAndInstallAppUpdate(appUpdate)}
>
Update Now
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader className="flex flex-col items-center text-center gap-2">
<CircleArrowUp className="size-7 stroke-muted-foreground" />
<AlertDialogTitle>Updating {config.appName}</AlertDialogTitle>
<AlertDialogDescription className="text-center text-xs mb-2">Updating {config.appName} to v{appUpdate?.version || '0.0.0'}, Please be patience! Do not quit the app untill the update finishes. The app will auto re-launch to complete the update, Please allow all system prompts from {config.appName} if asked.</AlertDialogDescription>
<Progress value={appUpdateDownloadProgress} className="w-full" />
<AlertDialogDescription className="text-center">Downloading update... {appUpdateDownloadProgress}%</AlertDialogDescription>
</AlertDialogHeader>
</AlertDialogContent>
</AlertDialog>
)} )}
</Link> </CardContent>
</SidebarMenuButton> </Card>
)} )}
</SidebarMenuItem> <SidebarMenu>
))} {bottomItems.map((item) => (
</SidebarMenu> <SidebarMenuItem key={item.title}>
</SidebarGroupContent> {!open ? (
</SidebarGroup> <Tooltip>
</SidebarContent> <TooltipTrigger asChild>
<SidebarFooter> <SidebarMenuButton
{appUpdate && !open && ( isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
<Tooltip> asChild
<TooltipTrigger asChild> >
<Button variant="ghost"> <Link to={item.url}>
<CircleArrowUp className="size-4" /> <item.icon className="stroke-primary" />
</Button> <span>{item.title}</span>
</TooltipTrigger> </Link>
<TooltipContent side="right"> </SidebarMenuButton>
<p>Update Available <br></br>(Expand sidebar to view update)</p> </TooltipTrigger>
</TooltipContent> <TooltipContent side="right">
</Tooltip> <p>{item.title}</p>
)} </TooltipContent>
{appUpdate && open && showUpdateCard && ( </Tooltip>
<Card className="gap-4 py-0"> ) : (
<CardHeader className="p-4 pb-0"> <SidebarMenuButton
<CardTitle className="text-sm">Update Available (v{appUpdate?.version || '0.0.0'})</CardTitle> isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
<CardDescription> asChild
A newer version of {config.appName} is available. Please update to the latest version for the best experience. >
</CardDescription> <Link to={item.url}>
<a className="text-xs font-semibold cursor-pointer mt-1" href={`https://github.com/neosubhamoy/neodlp/releases/tag/v${appUpdate?.version || '0.0.0'}`} target="_blank"> Read Changelog</a> <item.icon className="stroke-primary" />
</CardHeader> <span>{item.title}</span>
<CardContent className="grid gap-2.5 p-4"> </Link>
<AlertDialog> </SidebarMenuButton>
<AlertDialogTrigger asChild> )}
<Button </SidebarMenuItem>
className="w-full" ))}
size="sm" </SidebarMenu>
disabled={ongoingDownloads.length > 0 || isUpdatingApp} </SidebarFooter>
onClick={() => downloadAndInstallAppUpdate(appUpdate)} </Sidebar>
> );
Update Now
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader className="flex flex-col items-center text-center gap-2">
<CircleArrowUp className="size-7 stroke-muted-foreground" />
<AlertDialogTitle>Updating {config.appName}</AlertDialogTitle>
<AlertDialogDescription className="text-center text-xs mb-2">Updating {config.appName} to v{appUpdate?.version || '0.0.0'}, Please be patience! Do not quit the app untill the update finishes. The app will auto re-launch to complete the update, Please allow all system prompts from {config.appName} if asked.</AlertDialogDescription>
<Progress value={appUpdateDownloadProgress} className="w-full" />
<AlertDialogDescription className="text-center">Downloading update... {appUpdateDownloadProgress}%</AlertDialogDescription>
</AlertDialogHeader>
</AlertDialogContent>
</AlertDialog>
</CardContent>
</Card>
)}
<SidebarMenu>
{bottomItems.map((item) => (
<SidebarMenuItem key={item.title}>
{!open ? (
<Tooltip>
<TooltipTrigger asChild>
<SidebarMenuButton
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
asChild
>
<Link to={item.url}>
<item.icon className="stroke-primary" />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
</TooltipTrigger>
<TooltipContent side="right">
<p>{item.title}</p>
</TooltipContent>
</Tooltip>
) : (
<SidebarMenuButton
isActive={isActiveSidebarItem(item.url, location.pathname, item.starts_with ? item.starts_with : false)}
asChild
>
<Link to={item.url}>
<item.icon className="stroke-primary" />
<span>{item.title}</span>
</Link>
</SidebarMenuButton>
)}
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarFooter>
</Sidebar>
)
} }