Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Handle Mobile and Desktop Specific routes #394

Merged
merged 14 commits into from
Apr 17, 2024
Merged
51 changes: 35 additions & 16 deletions packages/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IonApp, IonRouterOutlet } from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query";
import { Web3Modal } from "@web3modal/react";
import { Route } from "react-router-dom";
import { Redirect, Route } from "react-router-dom";
import * as userStore from "src/api/store/slices/user";
import ToastContainer from "src/containers/toasts/ToastContainer";
import {
Expand Down Expand Up @@ -40,19 +40,25 @@ const AppRoutes = () => {
});

const resolvedView = useResolvedView();
const { pathContainsHashOrSlug, isRoot } = useViewRoute();
const { pathContainsHashOrSlug, isRoot, isSuperfeed } = useViewRoute();

const errorCode = useMemo<number | undefined>(() => {
/**
* At this moment, we do not support any other routes than the root and the hash/slug routes
* If the path does not contain a hash or slug, we show the 404 error page
*/
if (!pathContainsHashOrSlug && !isRoot) {
if (!pathContainsHashOrSlug && !isRoot && !isSuperfeed) {
return 404;
}
const errorInfo = error ?? resolvedView.error;
return errorInfo && getRtkErrorCode(errorInfo);
}, [error, resolvedView.error, pathContainsHashOrSlug, isRoot]);
}, [
pathContainsHashOrSlug,
isRoot,
isSuperfeed,
error,
resolvedView.error,
]);

const routes = useMemo(() => {
if (error || errorCode) {
Expand All @@ -73,19 +79,32 @@ const AppRoutes = () => {

return (
<Suspense fallback={<PreloaderPage />}>
{routes.map((route) => (
<Route
key={route.path}
path={route.path}
exact={route.exact}
render={() => (
<route.component
isFullsize={route.isFullsize}
type={errorCode}
{routes.map((route) => {
if (route.type === "redirect") {
return (
<Redirect
key={route.path}
path={route.path}
exact={route.exact}
to={route.redirectTo}
push
/>
)}
/>
))}
);
}
return (
<Route
key={route.path}
path={route.path}
exact={route.exact}
render={() => (
<route.component
isFullsize={route.isFullsize}
type={errorCode}
/>
)}
/>
);
})}
</Suspense>
);
};
Expand Down
38 changes: 34 additions & 4 deletions packages/frontend/src/MobileApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import {
IonTabs,
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { Redirect, Route, useLocation } from "react-router-dom";
import { Redirect, Route, useHistory, useLocation } from "react-router-dom";
import { ReactComponent as MarketsSVG } from "src/assets/svg/markets.svg";
import { ReactComponent as PortfolioSVG } from "src/assets/svg/portfolio.svg";
import { ReactComponent as SuperfeedSVG } from "src/assets/svg/superfeed.svg";
import { useAuth } from "./api/hooks";
import { useAuth, useViewRoute } from "./api/hooks";
import CONFIG from "./config";
import ToastContainer from "./containers/toasts/ToastContainer";
import "@alphaday/ui-kit/global.scss";
Expand All @@ -22,7 +22,26 @@ import {
mobileRoutes,
} from "./routes";

const { IS_DEV } = CONFIG;
const { IS_DEV, BOARDS } = CONFIG;

const boardRoutesHandler = (
pathname: string,
callback: (path: string) => void
) => {
if (pathname in BOARDS.BOARD_SLUG_MAP) {
const searchSlugs =
BOARDS.BOARD_SLUG_MAP[
pathname as keyof typeof BOARDS.BOARD_SLUG_MAP
];
const newRoute = `/superfeed/search/${[...new Set(searchSlugs)].join(",")}`;
v-almonacid marked this conversation as resolved.
Show resolved Hide resolved

if (pathname !== newRoute) {
callback(newRoute);
}
} else {
callback(EMobileRoutePaths.Base);
}
};

const CustomNavTab: React.FC<{
label: string;
Expand All @@ -42,13 +61,24 @@ const CustomNavTab: React.FC<{

const RouterChild = () => {
const { pathname } = useLocation();
const history = useHistory();
const { pathContainsHashOrSlug, routeInfo } = useViewRoute();

const { isAuthenticated } = useAuth();
const isTabBarHidden = !!mobileRoutes.find(
(route) =>
route.type !== "fallback" &&
route.path === pathname &&
route?.hideTabBar
);

if (pathContainsHashOrSlug && routeInfo?.value) {
const navigate = (str: string) => history.push(str);
boardRoutesHandler(routeInfo.value, navigate);

return null;
}

return (
<IonTabs>
<IonRouterOutlet ionPage>
Expand All @@ -67,7 +97,7 @@ const RouterChild = () => {
if (route.type === "fallback") {
return (
<Redirect
key={route.redirectTo}
key="fallback"
to={route.redirectTo}
push
/>
Expand Down
5 changes: 5 additions & 0 deletions packages/frontend/src/api/hooks/useViewRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ interface IViewRouteInfo {
* true if the current path is root path
*/
isRoot: boolean;
/**
* true if the current path is superfeed path
*/
isSuperfeed: boolean;
}

export const useViewRoute = (): IViewRouteInfo => {
Expand Down Expand Up @@ -117,6 +121,7 @@ export const useViewRoute = (): IViewRouteInfo => {
isFullSize: fullSizeWidgetPath !== undefined,
isViewHash,
isRoot: location.pathname === "/",
isSuperfeed: location.pathname.includes("/superfeed"),
};
};

Expand Down
92 changes: 92 additions & 0 deletions packages/frontend/src/config/boards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const BOARDS_CONFIG = {
BOARD_SLUG_MAP: {
aave: ["aave"],
ai: [
"bittensor",
"fetch-ai",
"ocean-protocol",
"singularitynet",
"chaingpt",
"arkham",
"phala-network",
"oasis",
"iexec-rlc",
"render",
"ai",
],
alchemix: ["alchemix"],
alpha: [],
aptos: ["aptos"],
arbitrum: ["arbitrum", "offchain-labs"],
avalanche: ["avalanche"],
bankless: ["bankless"],
base: ["base", "coinbase"],
beginner: [],
bitcoin: ["bitcoin"],
canto: ["canto"],
celestia: ["celestia"],
chiliz: ["chiliz"],
dfinity: ["dfinity", "internet-computer"],
eigenlayer: ["eigenlayer"],
eos: ["eos"],
ethereumclassic: ["ethereumclassic"],
ethereum: ["ethereum", "ethereum-research-forum"],
functionx: ["function-x"],
gamefi: [
"gamefi",
"blockchain-gaming",
"the-sandbox",
"decentraland",
"ronin",
"immutablex",
],
impossible: ["impossible-finance"],
injective: ["injective"],
kyber: ["kyber-network", "kyberswap"],
linea: ["linea"],
liquidstaking: [
"liquid-staking",
"lido",
"rocket-pool",
"frax",
"eigenlayer",
"coinbase-wrapped-staked-eth",
"swell",
"ankr",
"ethereum",
"swell-ethereum",
],
manta: ["manta-network"],
metis: ["metis", "metisdao"],
mina: ["mina", "mina-protocol"],
moonbeam: ["moonbeam"],
nft: ["nft"],
oceanprotocol: ["ocean-protocol"],
optimism: ["optimism"],
orbs: ["orbs"],
ordinals: ["ordinals"],
rocketpool: ["rocket-pool"],
scroll: ["scroll"],
shefi: ["shefi"],
sia: ["siacoin"],
solana: ["solana"],
starknet: ["starknet"],
thegraph: ["the-graph"],
trading: ["market", "trading-video", "economic-calendar"],
verasity: ["verasity", "verasity-source"],
vitalikbuterin: ["vitalik-buterin"],
wax: ["wax"],
zcash: [
"zcash-newsletter",
"electric-coin",
"zcash",
"the-ambassadors-reception",
"the-zf-a-v-club",
"zcash-brasil",
"zechub",
],
zksync: ["zksync", "zksync-era"],
},
};

export default BOARDS_CONFIG;
2 changes: 2 additions & 0 deletions packages/frontend/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import API_CONFIG from "./backend";
import BOARDS_CONFIG from "./boards";
import FIREBASE_CONFIG from "./firebase";
import NUMBERS from "./numbers";
import ROUTING_CONFIG from "./routing";
Expand Down Expand Up @@ -81,6 +82,7 @@ const CONFIG = {
IS_PROD,
LOGLEVEL,
API: API_CONFIG,
BOARDS: BOARDS_CONFIG,
ROUTING: ROUTING_CONFIG,
UI: UI_CONFIG,
WIDGETS: WIDGETS_CONFIG,
Expand Down
52 changes: 44 additions & 8 deletions packages/frontend/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,28 @@ const PortfolioHoldingsPage = lazyRetry(
*
* It defines the path and the page to be rendered.
*/
export interface IRoute {
path: EDesktopRoutePaths;
component: typeof ErrorPage | typeof PreloaderPage | typeof DashboardPage;
exact?: boolean;
isFullsize?: boolean;
}
export type TRoute =
| {
path: EDesktopRoutePaths;
component:
| typeof ErrorPage
| typeof PreloaderPage
| typeof DashboardPage;
exact?: boolean;
isFullsize?: boolean;
type: "regular";
}
| {
path: EDesktopRoutePaths;
component:
| typeof ErrorPage
| typeof PreloaderPage
| typeof DashboardPage;
exact?: boolean;
isFullsize?: boolean;
redirectTo: string;
type: "redirect";
};

/**
* Enum of all routes in the desktop app.
Expand All @@ -56,41 +72,54 @@ export enum EDesktopRoutePaths {
Calendar = "/b/:slug/calendar",
CalendarEvent = "/b/:slug/calendar/event/:eventId/:eventTitle",
FallBack = "*",
Superfeed = "/superfeed",
}

/**
* An array of all valid routes in the desktop app.
*/
export const desktopRoutes: IRoute[] = [
export const desktopRoutes: TRoute[] = [
{
type: "regular",
path: EDesktopRoutePaths.Base,
component: DashboardPage,
exact: true,
},
{
type: "regular",
path: EDesktopRoutePaths.Boards,
component: DashboardPage,
exact: true,
},
{
type: "regular",
path: EDesktopRoutePaths.Calendar,
component: DashboardPage,
isFullsize: true,
exact: true,
},
{
type: "regular",
path: EDesktopRoutePaths.CalendarEvent,
component: DashboardPage,
isFullsize: true,
exact: true,
},
{
type: "redirect",
path: EDesktopRoutePaths.Superfeed,
redirectTo: EDesktopRoutePaths.Base,
component: DashboardPage,
exact: true,
},
];

/**
* An array of invalid routes in the desktop app.
*/
export const errorRoutes: IRoute[] = [
export const errorRoutes: TRoute[] = [
{
type: "regular",
path: EDesktopRoutePaths.FallBack,
component: ErrorPage,
},
Expand All @@ -110,6 +139,7 @@ export enum EMobileTabRoutePaths {

export enum EMobileRoutePaths {
Base = BASE_TABS_ROUTE,
Boards = EDesktopRoutePaths.Boards,
Superfeed = `${BASE_TABS_ROUTE}superfeed`,
Search = `${BASE_TABS_ROUTE}superfeed/search/:tags`,
UserSettings = `${BASE_TABS_ROUTE}superfeed/user-settings`,
Expand Down Expand Up @@ -160,6 +190,12 @@ export const mobileRoutes: TMobileRoute[] = [
exact: true,
type: "regular",
},
{
path: EMobileRoutePaths.Boards,
elcharitas marked this conversation as resolved.
Show resolved Hide resolved
component: SuperfeedPage,
exact: true,
type: "regular",
},
{
path: EMobileRoutePaths.Search,
component: SuperfeedPage,
Expand Down
Loading