From 74e769ba3be76b53a9f7f3f5620d78d4b1e014b8 Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Wed, 18 Sep 2024 16:38:46 +0300 Subject: [PATCH] app_store UI: fix launch buttons --- .../app_store/ui/src/pages/AppPage.tsx | 34 ++++++++++++++----- .../app_store/ui/src/pages/DownloadPage.tsx | 25 +++++++++++--- .../packages/app_store/ui/src/store/index.ts | 28 ++++++++++++++- .../packages/app_store/ui/src/types/Apps.ts | 13 +++++++ 4 files changed, 85 insertions(+), 15 deletions(-) diff --git a/kinode/packages/app_store/ui/src/pages/AppPage.tsx b/kinode/packages/app_store/ui/src/pages/AppPage.tsx index b7e6a9bc..44ce3f32 100644 --- a/kinode/packages/app_store/ui/src/pages/AppPage.tsx +++ b/kinode/packages/app_store/ui/src/pages/AppPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useCallback } from "react"; +import React, { useEffect, useState, useCallback, useMemo } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { FaDownload, FaCheck, FaTimes, FaPlay, FaSpinner, FaTrash, FaSync } from "react-icons/fa"; import useAppsStore from "../store"; @@ -8,7 +8,7 @@ import { compareVersions } from "../utils/compareVersions"; export default function AppPage() { const { id } = useParams(); const navigate = useNavigate(); - const { fetchListing, fetchInstalledApp, uninstallApp, setAutoUpdate } = useAppsStore(); + const { fetchListing, fetchInstalledApp, uninstallApp, setAutoUpdate, getLaunchUrl, fetchHomepageApps } = useAppsStore(); const [app, setApp] = useState(null); const [installedApp, setInstalledApp] = useState(null); const [currentVersion, setCurrentVersion] = useState(null); @@ -57,6 +57,21 @@ export default function AppPage() { } }, [id, fetchListing, fetchInstalledApp]); + + const handleLaunch = useCallback(() => { + if (app) { + const launchUrl = getLaunchUrl(`${app.package_id.package_name}:${app.package_id.publisher_node}`); + if (launchUrl) { + window.location.href = launchUrl; + } + } + }, [app, getLaunchUrl]); + + const canLaunch = useMemo(() => { + if (!app) return false; + return !!getLaunchUrl(`${app.package_id.package_name}:${app.package_id.publisher_node}`); + }, [app, getLaunchUrl]); + const handleUninstall = async () => { if (!app) return; setIsUninstalling(true); @@ -88,16 +103,13 @@ export default function AppPage() { useEffect(() => { loadData(); - }, [loadData]); + fetchHomepageApps(); + }, [loadData, fetchHomepageApps]); const handleDownload = () => { navigate(`/download/${id}`); }; - const handleLaunch = () => { - window.location.href = `/${app?.package_id.package_name}:${app?.package_id.package_name}:${app?.package_id.publisher_node}/`; - }; - if (isLoading) { return

Loading app details...

; } @@ -150,8 +162,12 @@ export default function AppPage() {
{installedApp && ( <> - )}
diff --git a/kinode/packages/app_store/ui/src/store/index.ts b/kinode/packages/app_store/ui/src/store/index.ts index 350ef82c..8fdf1ca8 100644 --- a/kinode/packages/app_store/ui/src/store/index.ts +++ b/kinode/packages/app_store/ui/src/store/index.ts @@ -1,6 +1,6 @@ import { create } from 'zustand' import { persist } from 'zustand/middleware' -import { PackageState, AppListing, MirrorCheckFile, PackageManifest, DownloadItem } from '../types/Apps' +import { PackageState, AppListing, MirrorCheckFile, PackageManifest, DownloadItem, HomepageApp } from '../types/Apps' import { HTTP_STATUS } from '../constants/http' import KinodeClientApi from "@kinode/client-api" import { WEBSOCKET_URL } from '../utils/ws' @@ -13,6 +13,7 @@ interface AppsStore { downloads: Record ourApps: AppListing[] ws: KinodeClientApi + homepageApps: HomepageApp[] activeDownloads: Record fetchData: (id: string) => Promise @@ -25,6 +26,9 @@ interface AppsStore { fetchDownloadsForApp: (id: string) => Promise checkMirror: (node: string) => Promise + fetchHomepageApps: () => Promise + getLaunchUrl: (id: string) => string | null + installApp: (id: string, version_hash: string) => Promise uninstallApp: (id: string) => Promise downloadApp: (id: string, version_hash: string, downloadFrom: string) => Promise @@ -49,6 +53,8 @@ const useAppsStore = create()( downloads: {}, ourApps: [], activeDownloads: {}, + homepageApps: [], + fetchData: async (id: string) => { if (!id) return; @@ -174,6 +180,26 @@ const useAppsStore = create()( return []; }, + fetchHomepageApps: async () => { + try { + const res = await fetch('/apps'); + if (res.status === HTTP_STATUS.OK) { + const data: HomepageApp[] = await res.json(); + set({ homepageApps: data }); + } + } catch (error) { + console.error("Error fetching homepage apps:", error); + } + }, + + getLaunchUrl: (id: string) => { + const app = get().homepageApps.find(app => `${app.package}:${app.publisher}` === id); + if (app && app.path) { + return app.path; + } + return null; + }, + checkMirror: async (node: string) => { try { const res = await fetch(`${BASE_URL}/mirrorcheck/${node}`); diff --git a/kinode/packages/app_store/ui/src/types/Apps.ts b/kinode/packages/app_store/ui/src/types/Apps.ts index a9698d07..a7f5b0f0 100644 --- a/kinode/packages/app_store/ui/src/types/Apps.ts +++ b/kinode/packages/app_store/ui/src/types/Apps.ts @@ -70,3 +70,16 @@ export interface PackageManifest { grant_capabilities: any[] public: boolean } + +export interface HomepageApp { + id: string; + process: string; + package: string; + publisher: string; + path?: string; + label: string; + base64_icon?: string; + widget?: string; + order: number; + favorite: boolean; +}