Files
Arkie-Library-Frontend/src/App.tsx

194 lines
8.5 KiB
TypeScript
Raw Normal View History

import {
BrowserRouter,
Navigate,
Route,
Routes,
useLocation,
useParams,
} from "react-router-dom";
2026-05-16 00:18:22 +08:00
import { I18nProvider } from "./i18n";
import { MotionProvider } from "./motion";
import { ToastProvider } from "./components/Toast";
2026-06-01 23:00:28 +08:00
import { SaveToAlbumGuideProvider } from "./components/SaveToAlbumGuide";
import { InAppDownloadGuideProvider } from "./components/InAppDownloadGuide";
2026-06-02 00:36:11 +08:00
import { FavoritesProvider } from "./favorites/FavoritesProvider";
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
import { AutoInjectedLogin } from "./wallet/AutoInjectedLogin";
2026-06-02 00:28:22 +08:00
import { RainbowWalletProvider } from "./wallet/RainbowWalletProvider";
2026-06-02 00:32:46 +08:00
import { WalletLoginModal } from "./wallet/WalletLoginModal";
2026-06-02 00:28:22 +08:00
import { WalletProvider } from "./wallet/WalletProvider";
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
import { WalletStackErrorBoundary } from "./wallet/WalletStackErrorBoundary";
2026-05-16 00:18:22 +08:00
import { PublicLayout } from "./layouts/PublicLayout";
2026-06-01 15:09:58 +08:00
import { LocalizedHomePage } from "./pages/LocalizedHome";
2026-05-16 00:18:22 +08:00
import { Browse } from "./pages/Browse";
import { CategoriesPage } from "./pages/Categories";
2026-05-28 22:36:08 +08:00
import { CategoryPage } from "./pages/Category";
import { OfficialRecommendationsPage } from "./pages/OfficialRecommendations";
2026-05-26 14:46:05 +08:00
import { SearchPage } from "./pages/Search";
import { PostRedirect } from "./pages/PostRedirect";
import { ScrollToTop } from "./components/ScrollToTop";
import { PageTitleProvider } from "./components/PageTitleContext";
import Favorites from "./pages/Favorites";
2026-05-16 00:18:22 +08:00
import { adminUiPrefix } from "./adminPaths";
import { AdminRouteTree } from "./adminRouteTree";
import { AdminRouterModeProvider } from "./adminRouterMode";
import { ImageLightboxProvider } from "./components/messageStream/overlays/ImageLightbox";
import { VideoPlayerProvider } from "./components/messageStream/overlays/VideoPlayer";
import { legacyLanguageRedirects, localizedHomeRoutes } from "./languageRoutes";
/**
* Redirects shared links that still use the old long-form language prefix
* (e.g. /chinese, /malay/browse) to the new short codes (/cn, /ms/browse).
* Preserves the sub-path, query string, and hash.
*/
function LegacyLangRedirect({ to }: { to: string }) {
const params = useParams();
const { search, hash } = useLocation();
const splat = params["*"];
const sub = splat ? `/${splat}` : "";
return <Navigate to={`${to}${sub}${search}${hash}`} replace />;
}
2026-05-16 00:18:22 +08:00
const adminEnabled = import.meta.env.VITE_DISABLE_ADMIN !== "true";
export default function App() {
return (
<I18nProvider>
<MotionProvider>
<ToastProvider>
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
<WalletProvider>
<AutoInjectedLogin />
<WalletStackErrorBoundary>
<RainbowWalletProvider>
<WalletLoginModal />
</RainbowWalletProvider>
</WalletStackErrorBoundary>
<FavoritesProvider>
<InAppDownloadGuideProvider>
<SaveToAlbumGuideProvider>
<AdminRouterModeProvider value="absolute">
<ImageLightboxProvider>
<VideoPlayerProvider>
<PageTitleProvider>
<BrowserRouter>
<ScrollToTop />
<Routes>
<Route element={<PublicLayout />}>
<Route
path="/"
element={
<LocalizedHomePage targetLang="en" />
}
/>
<Route path="/browse" element={<Browse />} />
<Route
path="/categories"
element={<CategoriesPage />}
/>
<Route
path="/official-recommendations"
element={<OfficialRecommendationsPage />}
/>
<Route
path="/category/:slug"
element={<CategoryPage />}
/>
<Route
path="/search"
element={<SearchPage />}
/>
<Route
path="/resource/:id"
element={<PostRedirect />}
/>
<Route
path="/favorites"
element={<Favorites />}
/>
{localizedHomeRoutes.map((route) => (
<Route key={route.path} path={route.path}>
<Route
index
element={
<LocalizedHomePage
targetLang={route.lang}
/>
}
/>
<Route path="browse" element={<Browse />} />
<Route
path="categories"
element={<CategoriesPage />}
/>
<Route
path="official-recommendations"
element={<OfficialRecommendationsPage />}
/>
<Route
path="category/:slug"
element={<CategoryPage />}
/>
<Route
path="search"
element={<SearchPage />}
/>
<Route
path="resource/:id"
element={<PostRedirect />}
/>
<Route
path="favorites"
element={<Favorites />}
/>
</Route>
))}
</Route>
2026-06-02 00:28:22 +08:00
{/* Legacy long-form language URLs short-code
redirects. Shared links (e.g. WeChat) keep working. */}
{legacyLanguageRedirects.map((redirect) => (
<Route key={redirect.from}>
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
<Route
path={redirect.from}
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
element={
<LegacyLangRedirect to={redirect.to} />
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
}
/>
<Route
path={`${redirect.from}/*`}
element={
<LegacyLangRedirect to={redirect.to} />
}
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
/>
</Route>
))}
2026-05-16 00:18:22 +08:00
{adminEnabled ? (
AdminRouteTree()
) : (
<Route
path={`${adminUiPrefix}/*`}
element={<Navigate to="/" replace />}
/>
)}
2026-06-02 00:28:22 +08:00
<Route
path="*"
2026-06-02 00:28:22 +08:00
element={<Navigate to="/" replace />}
/>
</Routes>
</BrowserRouter>
</PageTitleProvider>
</VideoPlayerProvider>
</ImageLightboxProvider>
</AdminRouterModeProvider>
</SaveToAlbumGuideProvider>
</InAppDownloadGuideProvider>
feat(wallet): bypass WalletConnect for TP/imToken on mobile to fix China users The WalletConnect relay (wss://relay.walletconnect.org) is unreliable/blocked in mainland China. Every wallet flow (desktop QR, mobile deeplink, mobile QR) depends on it, so Chinese users see the login button hang forever and the QR code never appears. When RainbowKit's render fails, the whole site goes white because nothing catches the error. Changes: - Add WalletStackErrorBoundary around <RainbowWalletProvider> + modal so RainbowKit init failures no longer blank the entire app. - Hoist <WalletProvider> above the boundary; it only depends on the injected provider, so useWallet keeps working for header / favorites / etc. even when the WC stack is dead. - On mobile, the TP/imToken 'Open Wallet App' button now navigates directly to tpdapp://open / imtokenv2://navigate/DappView with an ?autoLogin=<kind> query, pulling the site into the wallet's in-app browser without ever touching the WC relay. MetaMask still uses the WC path (no equivalent deeplink). - Add AutoInjectedLogin: when the page loads with ?autoLogin=<kind>, wait up to 8s for window.ethereum, then connectInjectedWallet + completeLogin. Strips the param via history.replaceState to avoid re-firing on reload. - Guard against the in-app-browser disconnect/reconnect case: if getInjectedWallet(kind) is already truthy, skip the deeplink and let useWalletConnectLogin's deeplink mode take the injected fast path (avoids TP trying to open TP recursively).
2026-06-03 20:07:23 +08:00
</FavoritesProvider>
</WalletProvider>
</ToastProvider>
</MotionProvider>
2026-05-16 00:18:22 +08:00
</I18nProvider>
);
}