diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index 25453f3..8555c2d 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -7,7 +7,7 @@ android { applicationId "com.pulse_editor.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 2 + versionCode 4 versionName "v0.1.1-beta" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { diff --git a/web/app/(extension-layout)/extension/page.tsx b/web/app/(extension-layout)/extension/page.tsx index 8d3ee4c..6801b4f 100644 --- a/web/app/(extension-layout)/extension/page.tsx +++ b/web/app/(extension-layout)/extension/page.tsx @@ -43,6 +43,7 @@ export default function ExtensionPage({}) { setIsRegistered(true); } + // Load the remote module mfHost .loadRemote(`${moduleId}/main`) .then((module) => { @@ -58,6 +59,46 @@ export default function ExtensionPage({}) { .catch((error) => { console.error("Error loading remote module:", error); }); + + // Patch fetch for Pulse App backend calling + const originalFetch = window.fetch; + + const patchedFetch = async ( + ...args: Parameters + ): Promise => { + const [resource, config] = args; + const url = + resource instanceof Request ? resource.url : resource.toString(); + + // Only patch relative URLs (not absolute http/https) + if (/^https?:\/\//i.test(url)) { + return originalFetch(resource, config); + } + + const newUrl = remoteOrigin.startsWith( + process.env.NEXT_PUBLIC_CDN_URL ?? "https://cdn.pulse-editor.com", + ) + ? `${process.env.NEXT_PUBLIC_SERVER_FUNCTION_RUNNER_URL}/${moduleId}/${moduleVersion}/${url.replace("/server-function/", "")}` + : remoteOrigin + url; + + console.log(`[FETCH INTERCEPTED]: ${url} → ${newUrl}`); + console.log(`[App Info] ID: ${moduleId}, Version: ${moduleVersion}`); + + const response = await originalFetch(newUrl, config); + + if (!response.ok) { + console.warn(`Fetch Error (${response.status}) for ${url}`); + } + + return response; + }; + + window.fetch = patchedFetch; + + // // Cleanup on unmount or dependency change + // return () => { + // window.fetch = originalFetch; + // }; }, [remoteOrigin, moduleId, moduleVersion, isMounted]); if (!isMounted) { diff --git a/web/components/app-loaders/base-app-loader.tsx b/web/components/app-loaders/base-app-loader.tsx index 4f884cf..adfcdde 100644 --- a/web/components/app-loaders/base-app-loader.tsx +++ b/web/components/app-loaders/base-app-loader.tsx @@ -32,6 +32,9 @@ export default function BaseAppLoader({ className="h-full w-full" src={src} sandbox="allow-scripts allow-same-origin allow-forms allow-popups" + role="application" + title={moduleId} + aria-label={moduleId} /> ); } diff --git a/web/components/marketplace/app/app-preview-card.tsx b/web/components/marketplace/app/app-preview-card.tsx index 0da12d2..a5b9dbe 100644 --- a/web/components/marketplace/app/app-preview-card.tsx +++ b/web/components/marketplace/app/app-preview-card.tsx @@ -13,7 +13,6 @@ import { ContextMenuState, ExtensionApp } from "@/lib/types"; import { DraggableAttributes } from "@dnd-kit/core"; import { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities"; import { - addToast, Button, Chip, Skeleton, @@ -91,7 +90,7 @@ export default function AppPreviewCard({ undefined, ); - const [showMFVersionInfo, setShowMFVersionInfo] = useState(false); + const [isHover, setIsHover] = useState(false); useEffect(() => { async function fetchVersions() { @@ -170,13 +169,13 @@ export default function AppPreviewCard({ className="relative h-full min-h-32 w-full" onMouseEnter={() => { if (getPlatform() !== PlatformEnum.Capacitor) { - setIsShowInfo(true); + setIsHover(true); } }} // Hide show info when user taps outside of the modal onMouseLeave={() => { if (getPlatform() !== PlatformEnum.Capacitor) { - setIsShowInfo(false); + setIsHover(false); } }} > @@ -275,9 +274,6 @@ export default function AppPreviewCard({ return; } - addToast({ - title: "App Preview Clicked", - }); if (onPress) { onPress(extension); } else { @@ -323,7 +319,7 @@ export default function AppPreviewCard({ )} - {isShowInfo && ( + {(isShowInfo || isHover) && (
{isShowUseButton && ( - {isShowInfo && ( + {(isShowInfo || isHover) && (