SettingsRouteRoute,
} as any)
+const SettingsTasksRoute = SettingsTasksRouteImport.update({
+ id: '/tasks',
+ path: '/tasks',
+ getParentRoute: () => SettingsRouteRoute,
+} as any)
const SettingsPluginsRoute = SettingsPluginsRouteImport.update({
id: '/plugins',
path: '/plugins',
@@ -98,6 +108,11 @@ const StoreTabIndexRoute = StoreTabIndexRouteImport.update({
path: '/',
getParentRoute: () => StoreTabRouteRoute,
} as any)
+const StoreTabPluginsRoute = StoreTabPluginsRouteImport.update({
+ id: '/plugins',
+ path: '/plugins',
+ getParentRoute: () => StoreTabRouteRoute,
+} as any)
const StoreTabGamesRoute = StoreTabGamesRouteImport.update({
id: '/games',
path: '/games',
@@ -108,6 +123,11 @@ const StoreTabEmulatorsRoute = StoreTabEmulatorsRouteImport.update({
path: '/emulators',
getParentRoute: () => StoreTabRouteRoute,
} as any)
+const StoreTabDownloadRoute = StoreTabDownloadRouteImport.update({
+ id: '/download',
+ path: '/download',
+ getParentRoute: () => StoreTabRouteRoute,
+} as any)
const SettingsPluginSourceRoute = SettingsPluginSourceRouteImport.update({
id: '/plugin/$source',
path: '/plugin/$source',
@@ -138,6 +158,11 @@ const CollectionSourceIdRoute = CollectionSourceIdRouteImport.update({
path: '/collection/$source/$id',
getParentRoute: () => rootRouteImport,
} as any)
+const StoreDetailsPluginIdRoute = StoreDetailsPluginIdRouteImport.update({
+ id: '/store/details/plugin/$id',
+ path: '/store/details/plugin/$id',
+ getParentRoute: () => rootRouteImport,
+} as any)
const StoreDetailsEmulatorIdRoute = StoreDetailsEmulatorIdRouteImport.update({
id: '/store/details/emulator/$id',
path: '/store/details/emulator/$id',
@@ -148,6 +173,12 @@ const GameUpdateSourceIdRoute = GameUpdateSourceIdRouteImport.update({
path: '/game/update/$source/$id',
getParentRoute: () => rootRouteImport,
} as any)
+const StoreDetailsDownloadSourceIdRoute =
+ StoreDetailsDownloadSourceIdRouteImport.update({
+ id: '/store/details/download/$source/$id',
+ path: '/store/details/download/$source/$id',
+ getParentRoute: () => rootRouteImport,
+ } as any)
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
@@ -161,6 +192,7 @@ export interface FileRoutesByFullPath {
'/settings/emulators': typeof SettingsEmulatorsRoute
'/settings/interface': typeof SettingsInterfaceRoute
'/settings/plugins': typeof SettingsPluginsRoute
+ '/settings/tasks': typeof SettingsTasksRoute
'/settings/update': typeof SettingsUpdateRoute
'/collection/$source/$id': typeof CollectionSourceIdRoute
'/embedded/$source/$id': typeof EmbeddedSourceIdRoute
@@ -168,11 +200,15 @@ export interface FileRoutesByFullPath {
'/launcher/$source/$id': typeof LauncherSourceIdRoute
'/platform/$source/$id': typeof PlatformSourceIdRoute
'/settings/plugin/$source': typeof SettingsPluginSourceRoute
+ '/store/tab/download': typeof StoreTabDownloadRoute
'/store/tab/emulators': typeof StoreTabEmulatorsRoute
'/store/tab/games': typeof StoreTabGamesRoute
+ '/store/tab/plugins': typeof StoreTabPluginsRoute
'/store/tab/': typeof StoreTabIndexRoute
'/game/update/$source/$id': typeof GameUpdateSourceIdRoute
'/store/details/emulator/$id': typeof StoreDetailsEmulatorIdRoute
+ '/store/details/plugin/$id': typeof StoreDetailsPluginIdRoute
+ '/store/details/download/$source/$id': typeof StoreDetailsDownloadSourceIdRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
@@ -185,6 +221,7 @@ export interface FileRoutesByTo {
'/settings/emulators': typeof SettingsEmulatorsRoute
'/settings/interface': typeof SettingsInterfaceRoute
'/settings/plugins': typeof SettingsPluginsRoute
+ '/settings/tasks': typeof SettingsTasksRoute
'/settings/update': typeof SettingsUpdateRoute
'/collection/$source/$id': typeof CollectionSourceIdRoute
'/embedded/$source/$id': typeof EmbeddedSourceIdRoute
@@ -192,11 +229,15 @@ export interface FileRoutesByTo {
'/launcher/$source/$id': typeof LauncherSourceIdRoute
'/platform/$source/$id': typeof PlatformSourceIdRoute
'/settings/plugin/$source': typeof SettingsPluginSourceRoute
+ '/store/tab/download': typeof StoreTabDownloadRoute
'/store/tab/emulators': typeof StoreTabEmulatorsRoute
'/store/tab/games': typeof StoreTabGamesRoute
+ '/store/tab/plugins': typeof StoreTabPluginsRoute
'/store/tab': typeof StoreTabIndexRoute
'/game/update/$source/$id': typeof GameUpdateSourceIdRoute
'/store/details/emulator/$id': typeof StoreDetailsEmulatorIdRoute
+ '/store/details/plugin/$id': typeof StoreDetailsPluginIdRoute
+ '/store/details/download/$source/$id': typeof StoreDetailsDownloadSourceIdRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
@@ -211,6 +252,7 @@ export interface FileRoutesById {
'/settings/emulators': typeof SettingsEmulatorsRoute
'/settings/interface': typeof SettingsInterfaceRoute
'/settings/plugins': typeof SettingsPluginsRoute
+ '/settings/tasks': typeof SettingsTasksRoute
'/settings/update': typeof SettingsUpdateRoute
'/collection/$source/$id': typeof CollectionSourceIdRoute
'/embedded/$source/$id': typeof EmbeddedSourceIdRoute
@@ -218,11 +260,15 @@ export interface FileRoutesById {
'/launcher/$source/$id': typeof LauncherSourceIdRoute
'/platform/$source/$id': typeof PlatformSourceIdRoute
'/settings/plugin/$source': typeof SettingsPluginSourceRoute
+ '/store/tab/download': typeof StoreTabDownloadRoute
'/store/tab/emulators': typeof StoreTabEmulatorsRoute
'/store/tab/games': typeof StoreTabGamesRoute
+ '/store/tab/plugins': typeof StoreTabPluginsRoute
'/store/tab/': typeof StoreTabIndexRoute
'/game/update/$source/$id': typeof GameUpdateSourceIdRoute
'/store/details/emulator/$id': typeof StoreDetailsEmulatorIdRoute
+ '/store/details/plugin/$id': typeof StoreDetailsPluginIdRoute
+ '/store/details/download/$source/$id': typeof StoreDetailsDownloadSourceIdRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
@@ -238,6 +284,7 @@ export interface FileRouteTypes {
| '/settings/emulators'
| '/settings/interface'
| '/settings/plugins'
+ | '/settings/tasks'
| '/settings/update'
| '/collection/$source/$id'
| '/embedded/$source/$id'
@@ -245,11 +292,15 @@ export interface FileRouteTypes {
| '/launcher/$source/$id'
| '/platform/$source/$id'
| '/settings/plugin/$source'
+ | '/store/tab/download'
| '/store/tab/emulators'
| '/store/tab/games'
+ | '/store/tab/plugins'
| '/store/tab/'
| '/game/update/$source/$id'
| '/store/details/emulator/$id'
+ | '/store/details/plugin/$id'
+ | '/store/details/download/$source/$id'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
@@ -262,6 +313,7 @@ export interface FileRouteTypes {
| '/settings/emulators'
| '/settings/interface'
| '/settings/plugins'
+ | '/settings/tasks'
| '/settings/update'
| '/collection/$source/$id'
| '/embedded/$source/$id'
@@ -269,11 +321,15 @@ export interface FileRouteTypes {
| '/launcher/$source/$id'
| '/platform/$source/$id'
| '/settings/plugin/$source'
+ | '/store/tab/download'
| '/store/tab/emulators'
| '/store/tab/games'
+ | '/store/tab/plugins'
| '/store/tab'
| '/game/update/$source/$id'
| '/store/details/emulator/$id'
+ | '/store/details/plugin/$id'
+ | '/store/details/download/$source/$id'
id:
| '__root__'
| '/'
@@ -287,6 +343,7 @@ export interface FileRouteTypes {
| '/settings/emulators'
| '/settings/interface'
| '/settings/plugins'
+ | '/settings/tasks'
| '/settings/update'
| '/collection/$source/$id'
| '/embedded/$source/$id'
@@ -294,11 +351,15 @@ export interface FileRouteTypes {
| '/launcher/$source/$id'
| '/platform/$source/$id'
| '/settings/plugin/$source'
+ | '/store/tab/download'
| '/store/tab/emulators'
| '/store/tab/games'
+ | '/store/tab/plugins'
| '/store/tab/'
| '/game/update/$source/$id'
| '/store/details/emulator/$id'
+ | '/store/details/plugin/$id'
+ | '/store/details/download/$source/$id'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
@@ -314,6 +375,8 @@ export interface RootRouteChildren {
PlatformSourceIdRoute: typeof PlatformSourceIdRoute
GameUpdateSourceIdRoute: typeof GameUpdateSourceIdRoute
StoreDetailsEmulatorIdRoute: typeof StoreDetailsEmulatorIdRoute
+ StoreDetailsPluginIdRoute: typeof StoreDetailsPluginIdRoute
+ StoreDetailsDownloadSourceIdRoute: typeof StoreDetailsDownloadSourceIdRoute
}
declare module '@tanstack/react-router' {
@@ -346,6 +409,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof SettingsUpdateRouteImport
parentRoute: typeof SettingsRouteRoute
}
+ '/settings/tasks': {
+ id: '/settings/tasks'
+ path: '/tasks'
+ fullPath: '/settings/tasks'
+ preLoaderRoute: typeof SettingsTasksRouteImport
+ parentRoute: typeof SettingsRouteRoute
+ }
'/settings/plugins': {
id: '/settings/plugins'
path: '/plugins'
@@ -409,6 +479,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof StoreTabIndexRouteImport
parentRoute: typeof StoreTabRouteRoute
}
+ '/store/tab/plugins': {
+ id: '/store/tab/plugins'
+ path: '/plugins'
+ fullPath: '/store/tab/plugins'
+ preLoaderRoute: typeof StoreTabPluginsRouteImport
+ parentRoute: typeof StoreTabRouteRoute
+ }
'/store/tab/games': {
id: '/store/tab/games'
path: '/games'
@@ -423,6 +500,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof StoreTabEmulatorsRouteImport
parentRoute: typeof StoreTabRouteRoute
}
+ '/store/tab/download': {
+ id: '/store/tab/download'
+ path: '/download'
+ fullPath: '/store/tab/download'
+ preLoaderRoute: typeof StoreTabDownloadRouteImport
+ parentRoute: typeof StoreTabRouteRoute
+ }
'/settings/plugin/$source': {
id: '/settings/plugin/$source'
path: '/plugin/$source'
@@ -465,6 +549,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof CollectionSourceIdRouteImport
parentRoute: typeof rootRouteImport
}
+ '/store/details/plugin/$id': {
+ id: '/store/details/plugin/$id'
+ path: '/store/details/plugin/$id'
+ fullPath: '/store/details/plugin/$id'
+ preLoaderRoute: typeof StoreDetailsPluginIdRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/store/details/emulator/$id': {
id: '/store/details/emulator/$id'
path: '/store/details/emulator/$id'
@@ -479,6 +570,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof GameUpdateSourceIdRouteImport
parentRoute: typeof rootRouteImport
}
+ '/store/details/download/$source/$id': {
+ id: '/store/details/download/$source/$id'
+ path: '/store/details/download/$source/$id'
+ fullPath: '/store/details/download/$source/$id'
+ preLoaderRoute: typeof StoreDetailsDownloadSourceIdRouteImport
+ parentRoute: typeof rootRouteImport
+ }
}
}
@@ -489,6 +587,7 @@ interface SettingsRouteRouteChildren {
SettingsEmulatorsRoute: typeof SettingsEmulatorsRoute
SettingsInterfaceRoute: typeof SettingsInterfaceRoute
SettingsPluginsRoute: typeof SettingsPluginsRoute
+ SettingsTasksRoute: typeof SettingsTasksRoute
SettingsUpdateRoute: typeof SettingsUpdateRoute
SettingsPluginSourceRoute: typeof SettingsPluginSourceRoute
}
@@ -500,6 +599,7 @@ const SettingsRouteRouteChildren: SettingsRouteRouteChildren = {
SettingsEmulatorsRoute: SettingsEmulatorsRoute,
SettingsInterfaceRoute: SettingsInterfaceRoute,
SettingsPluginsRoute: SettingsPluginsRoute,
+ SettingsTasksRoute: SettingsTasksRoute,
SettingsUpdateRoute: SettingsUpdateRoute,
SettingsPluginSourceRoute: SettingsPluginSourceRoute,
}
@@ -509,14 +609,18 @@ const SettingsRouteRouteWithChildren = SettingsRouteRoute._addFileChildren(
)
interface StoreTabRouteRouteChildren {
+ StoreTabDownloadRoute: typeof StoreTabDownloadRoute
StoreTabEmulatorsRoute: typeof StoreTabEmulatorsRoute
StoreTabGamesRoute: typeof StoreTabGamesRoute
+ StoreTabPluginsRoute: typeof StoreTabPluginsRoute
StoreTabIndexRoute: typeof StoreTabIndexRoute
}
const StoreTabRouteRouteChildren: StoreTabRouteRouteChildren = {
+ StoreTabDownloadRoute: StoreTabDownloadRoute,
StoreTabEmulatorsRoute: StoreTabEmulatorsRoute,
StoreTabGamesRoute: StoreTabGamesRoute,
+ StoreTabPluginsRoute: StoreTabPluginsRoute,
StoreTabIndexRoute: StoreTabIndexRoute,
}
@@ -537,6 +641,8 @@ const rootRouteChildren: RootRouteChildren = {
PlatformSourceIdRoute: PlatformSourceIdRoute,
GameUpdateSourceIdRoute: GameUpdateSourceIdRoute,
StoreDetailsEmulatorIdRoute: StoreDetailsEmulatorIdRoute,
+ StoreDetailsPluginIdRoute: StoreDetailsPluginIdRoute,
+ StoreDetailsDownloadSourceIdRoute: StoreDetailsDownloadSourceIdRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
diff --git a/src/mainview/index.css b/src/mainview/index.css
index 4c82b71..332862e 100644
--- a/src/mainview/index.css
+++ b/src/mainview/index.css
@@ -9,6 +9,7 @@
@theme {
--breakpoint-sm: 0px;
--breakpoint-md: 1024px;
+ --breakpoint-lg: 1280px;
--page-scroll-bg: transparent;
--animation-size: 1;
diff --git a/src/mainview/index.tsx b/src/mainview/index.tsx
index f5639f9..166cc4f 100644
--- a/src/mainview/index.tsx
+++ b/src/mainview/index.tsx
@@ -8,7 +8,7 @@ import
RouterProvider,
} from "@tanstack/react-router";
import { routeTree } from "./gen/routeTree.gen";
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { QueryClient } from "@tanstack/react-query";
import "./scripts/gamepads";
import "./scripts/windowEvents";
import "./scripts/spatialNavigation";
@@ -16,6 +16,16 @@ import NotFound from "./components/NotFound";
import Error from "./components/Error";
import serviceWorker from './scripts/serviceWorker?worker&url';
import App from "./App";
+import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
+import { createStore, get, set, del } from "idb-keyval";
+import
+{
+ PersistedClient,
+ Persister,
+} from '@tanstack/react-query-persist-client';
+import pkg from '../../package.json';
+
+const idbStore = createStore("tanstack-query", "cache");
if ('serviceWorker' in navigator)
{
@@ -24,7 +34,31 @@ if ('serviceWorker' in navigator)
const hashHistory = createHashHistory({});
-const queryClient = new QueryClient();
+const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ gcTime: 1000 * 60 * 60 * 24 * 5, // 5 days
+ }
+ }
+});
+
+export function createIDBPersister (idbValidKey: IDBValidKey = 'reactQuery'): Persister
+{
+ return {
+ persistClient: async (client: PersistedClient) =>
+ {
+ await set(idbValidKey, client, idbStore);
+ },
+ restoreClient: async () =>
+ {
+ return await get
(idbValidKey, idbStore);
+ },
+ removeClient: async () =>
+ {
+ await del(idbValidKey, idbStore);
+ },
+ } satisfies Persister;
+}
export interface RouterContext
{
@@ -74,9 +108,9 @@ if (!rootElement.innerHTML)
root.render(
-
+
-
+
,
);
diff --git a/src/mainview/query-options.ts b/src/mainview/query-options.ts
index a52c649..879d632 100644
--- a/src/mainview/query-options.ts
+++ b/src/mainview/query-options.ts
@@ -1,6 +1,7 @@
import { keepPreviousData, queryOptions } from "@tanstack/react-query";
import { getRomApiRomsIdGetOptions, getRomsApiRomsGetOptions } from "../clients/romm/@tanstack/react-query.gen";
-import { DefaultRommStaleTime, GameListFilterType } from "../shared/constants";
+import { DefaultRommStaleTime } from "../shared/constants";
+import { GameListFilterType } from '@simeonradivoev/gameflow-sdk/shared';
export function gamesQueryOptions (filter?: GameListFilterType)
{
diff --git a/src/mainview/routes/__root.tsx b/src/mainview/routes/__root.tsx
index fbe2f26..cafbab4 100644
--- a/src/mainview/routes/__root.tsx
+++ b/src/mainview/routes/__root.tsx
@@ -8,6 +8,7 @@ import { useEffect } from "react";
import AppCommunication from "../components/AppCommunication";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
+import GlobalContextDialog from "../components/GlobalContextDialog";
export const Route = createRootRouteWithContext()({
component: RootComponent,
@@ -39,9 +40,11 @@ function RootComponent ()
return (
-
-
-
+
+
+
+
+
{queryDevOptions &&
}
diff --git a/src/mainview/routes/collection.$source.$id.tsx b/src/mainview/routes/collection.$source.$id.tsx
index 3b73d25..a08c164 100644
--- a/src/mainview/routes/collection.$source.$id.tsx
+++ b/src/mainview/routes/collection.$source.$id.tsx
@@ -6,7 +6,7 @@ import { AnimatedBackgroundContext } from '../scripts/contexts';
import { getCollectionQuery } from '@queries/romm';
import { zodValidator } from '@tanstack/zod-adapter';
import z from 'zod';
-import { GameListFilterType } from '@/shared/constants';
+import { GameListFilterType } from '@simeonradivoev/gameflow-sdk/shared';
import { useLocalStorage } from 'usehooks-ts';
export const Route = createFileRoute('/collection/$source/$id')({
diff --git a/src/mainview/routes/game/$source.$id.tsx b/src/mainview/routes/game/$source.$id.tsx
index 064deee..13ea8ac 100644
--- a/src/mainview/routes/game/$source.$id.tsx
+++ b/src/mainview/routes/game/$source.$id.tsx
@@ -24,7 +24,7 @@ import Details from "@/mainview/components/game/Details";
import { AutoFocus } from "@/mainview/components/AutoFocus";
import SelectMenu from "@/mainview/components/SelectMenu";
import { IGDBIcon } from "@/mainview/scripts/brandIcons";
-import { FrontEndGameTypeDetailed } from "@/shared/types";
+import { FrontEndGameTypeDetailed } from "@simeonradivoev/gameflow-sdk/shared";
export const Route = createFileRoute("/game/$source/$id")({
loader: async ({ params, context }) =>
@@ -33,7 +33,9 @@ export const Route = createFileRoute("/game/$source/$id")({
},
component: RouteComponent,
errorComponent: Error,
- validateSearch: zodValidator(z.object({ focus: z.string().optional() })),
+ validateSearch: zodValidator(z.object({
+ focus: z.string().optional(),
+ })),
staticData: {
enterSound: 'openDetails',
goBackSound: "returnDetails"
diff --git a/src/mainview/routes/game/add.tsx b/src/mainview/routes/game/add.tsx
index 3a6a2f8..6399cd0 100644
--- a/src/mainview/routes/game/add.tsx
+++ b/src/mainview/routes/game/add.tsx
@@ -8,15 +8,18 @@ import { PathSettingsOptionBase } from '@/mainview/components/options/PathSettin
import SelectMenu from '@/mainview/components/SelectMenu';
import { FloatingShortcuts } from '@/mainview/components/Shortcuts';
import { oneShot } from '@/mainview/scripts/audio/audio';
+import { rommApi } from '@/mainview/scripts/clientApi';
import { addManualGameMutation, allGamesInvalidateQuery, gameLookupDetails, platformLookupMatchQuery } from '@/mainview/scripts/queries/romm';
import { GamePadButtonCode, useShortcuts } from '@/mainview/scripts/shortcuts';
import { HandleGoBack } from '@/mainview/scripts/utils';
+import { isUrl } from '@/shared/utils';
import { FocusContext, useFocusable } from '@noriginmedia/norigin-spatial-navigation';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { createFileRoute, useNavigate, useRouter } from '@tanstack/react-router';
import { zodValidator } from '@tanstack/zod-adapter';
-import { ArrowBigRightDash, Check, CirclePlus, CircleQuestionMark, CircleX, FileSearch, FolderOpen, HardDrive } from 'lucide-react';
+import { ArrowBigRightDash, Check, CirclePlus, CircleQuestionMark, CircleX, File, FileSearch, FolderOpen, Globe, HardDrive, Link, Save } from 'lucide-react';
import { basename } from 'pathe';
+import prettyBytes from 'pretty-bytes';
import { JSX, useState } from 'react';
import toast from 'react-hot-toast';
import { twMerge } from 'tailwind-merge';
@@ -39,6 +42,7 @@ export const Route = createFileRoute('/game/add')({
function FileSelectionField (data: { location: string | undefined, setLocation: (location: string | undefined) => void; })
{
const [localLocation, setLocalLocation] = useState
(data.location);
+ const navigate = useNavigate();
return ;
+ >
+
+ ;
}
const TAG_REGEX = /\(([^)]+)\)|\[([^\]]+)\]/g;
@@ -95,6 +101,17 @@ function Overview (data: {})
const navigate = useNavigate();
const router = useRouter();
const state = Route.useSearch();
+ const linkInfo = useQuery({
+ enabled (query)
+ {
+ return isUrl(query.queryKey[1]);
+ },
+ queryKey: ['dl-link-info', state.gameLocation],
+ queryFn: async () =>
+ {
+ return rommApi.api.romm.download.file.info.get({ query: { file_url: state.gameLocation! } });
+ }
+ });
const { data: game } = useQuery(gameLookupDetails(state.selectedGame?.source, state.selectedGame?.id));
const { data: platform } = useQuery(platformLookupMatchQuery(state.selectedGame?.source, state.platformId));
const addGame = useMutation({
@@ -105,7 +122,7 @@ function Overview (data: {})
},
async onSuccess (data, variables, onMutateResult, context)
{
- if (data.id === null) return;
+ if (data.id === null || isUrl(state.gameLocation)) return;
await context.client.invalidateQueries(allGamesInvalidateQuery);
navigate({
to: '/game/$source/$id', params: {
@@ -136,7 +153,13 @@ function Overview (data: {})
{platform?.match.type}
-