@@ -9,12 +9,13 @@ import { setDownloaderState, updateDownloaderStatus, updateDownloaderTask, updat
99import { setFpfssUser } from '@renderer/store/fpfss/slice' ;
1010import { pushHistory } from '@renderer/store/history/slice' ;
1111import { addLogEntries , setEntries } from '@renderer/store/logs/slice' ;
12- import { addLoaded , cancelDialog , changeService , createDialog , openDynamicPage , removeService , setDisplaySettingsFromCallback , setExtOrderablesFromCallback , setMainState , setUpdateInfo , updateDialog , updateDialogField , updateMetadataSource } from '@renderer/store/main/slice' ;
12+ import { addLoaded , cancelDialog , changeService , createDialog , dsAddCustomRoute , openDynamicPage , removeService , setDisplaySettingsFromCallback , setExtOrderablesFromCallback , setMainState , setUpdateInfo , updateDialog , updateDialogField , updateMetadataSource } from '@renderer/store/main/slice' ;
1313import { setPreferences , updatePreferences } from '@renderer/store/preferences/slice' ;
1414import { addData , createViews , GENERAL_VIEW_ID , resetDropdownData } from '@renderer/store/search/slice' ;
1515import store , { AppDispatch , RootState } from '@renderer/store/store' ;
1616import { setTagCategories } from '@renderer/store/tagCategories/slice' ;
1717import { addTask , setTask , setTaskBarOpen } from '@renderer/store/tasks/slice' ;
18+ import { idToGame } from '@renderer/util/async' ;
1819import * as extUtils from '@renderer/util/ext' ;
1920import { BackIn , BackInit , BackOut , FpfssUser } from '@shared/back/types' ;
2021import { APP_TITLE } from '@shared/constants' ;
@@ -34,6 +35,7 @@ import { LangContext } from '../util/lang';
3435import { ActivityRoutes } from './ActivityRoutes' ;
3536import { Dialog } from './Dialog' ;
3637import { GameComponentDropdownSelectField , GameComponentInputField } from './DisplayComponent' ;
38+ import { DynamicComponent } from './DynamicComponent' ;
3739import { DynamicComponentProvider , RemoteModule } from './DynamicComponentProvider' ;
3840import { DynamicThemeProvider } from './DynamicThemeProvider' ;
3941import { FloatingContainer } from './FloatingContainer' ;
@@ -134,6 +136,7 @@ export function App() {
134136 const manualUrl = useAppSelector ( state => state . preferences . onlineManual || pathToFileUrl ( path . join ( window . Shared . config . fullFlashpointPath , state . preferences . offlineManual ) ) ) ;
135137 const dynamicThemeFileList = useAppSelector ( selectDynamicThemes ) ;
136138 const remoteModules = useAppSelector ( selectRemoteModules ) ;
139+ const customRoutes = useAppSelector ( state => state . main . displaySettings . customRoutes ) ;
137140 const currentView = useView ( ) ;
138141 const firstBrowsePageViewName = useAppSelector ( state => Object . keys ( state . search . views ) . find ( v => v !== GENERAL_VIEW_ID ) ) ;
139142 const showRightSidebar = currentView ?. selectedGame !== undefined && browsePageShowRightSidebar && ! hiddenRightSidebarPages . reduce ( ( prev , cur ) => prev || location . pathname . startsWith ( cur ) , false ) ;
@@ -219,12 +222,10 @@ export function App() {
219222 < DynamicThemeProvider fileList = { dynamicThemeFileList } >
220223 < DynamicComponentProvider manifests = { remoteModules } >
221224 < MenuProvider >
222-
223225 < ToastContainer
224226 theme = 'dark'
225227 className = 'toast-container'
226228 progressClassName = 'toast-container-progress'
227- hideProgressBar = { true }
228229 position = 'bottom-center' />
229230 { ! stopRender ? (
230231 < >
@@ -280,7 +281,8 @@ export function App() {
280281 < >
281282 { useActivityRoutes && (
282283 < ActivityRoutes
283- manualUrl = { manualUrl } />
284+ manualUrl = { manualUrl }
285+ customRoutes = { customRoutes } />
284286 ) }
285287 < Routes >
286288 < Route
@@ -322,6 +324,12 @@ export function App() {
322324 < Route
323325 path = { Paths . DYNAMIC }
324326 element = { < DynamicPage name = { dynamicPage ?. name || '' } props = { dynamicPage ?. props } /> } />
327+ { customRoutes . map ( route =>
328+ < Route
329+ key = { route . path }
330+ path = { route . path }
331+ element = { useActivityRoutes ? < > </ > : < DynamicComponent name = { route . component } props = { { } } /> } />
332+ ) }
325333 < Route element = { < NotFoundPage /> } />
326334 </ Routes >
327335 < Activity mode = { isBrowsePage ? 'visible' : 'hidden' } >
@@ -406,10 +414,14 @@ function initApp(dispatch: AppDispatch) {
406414 window . ext = {
407415 utils : {
408416 getPointer,
409- getFileServerURL : getFileServerURL ,
417+ getFileServerURL,
410418 getExtensionFileURL : ( extId , filePath ) => {
411419 return `${ getFileServerURL ( ) } /extdata/${ extId } /${ filePath } ` ;
412420 } ,
421+ idToGame,
422+ runCommand : ( command , args ) => {
423+ return window . Shared . back . request ( BackIn . RUN_COMMAND , command , args ) ;
424+ } ,
413425 search : {
414426 onWhitelistFactory : extUtils . onWhitelistFactory ,
415427 onBlacklistFactory : extUtils . onBlacklistFactory ,
@@ -427,12 +439,17 @@ function initApp(dispatch: AppDispatch) {
427439 RandomGames,
428440 } ,
429441 hooks : {
430- useNavigate : ( ) => useNavigate ( ) ,
442+ useNavigate,
431443 useAppDispatch,
432444 useAppSelector,
433445 useContextMenu,
434446 useLocalization,
435447 } ,
448+ actions : {
449+ main : {
450+ dsAddCustomRoute,
451+ }
452+ }
436453 } ;
437454 window . setDisplaySettings = ( ( cb ) => {
438455 dispatch ( setDisplaySettingsFromCallback ( cb ) ) ;
0 commit comments