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:
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user