Skip to content

Commit

Permalink
Merge pull request #243 from microbit-foundation/add-simple-routing
Browse files Browse the repository at this point in the history
Add simple routing
  • Loading branch information
JonAlexandra authored Jul 3, 2023
2 parents 7d03f76 + 7369b68 commit b128f00
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 126 deletions.
69 changes: 36 additions & 33 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import CookieManager from './script/CookieManager';
import { DeviceRequestStates } from './script/stores/connectDialogStore';
import Environment from './script/Environment';
import Router from './router/Router.svelte';
ConnectionBehaviours.setInputBehaviour(new InputBehaviour());
ConnectionBehaviours.setOutputBehaviour(new OutputBehaviour());
Expand All @@ -50,40 +51,42 @@
document.title = Environment.pageTitle;
</script>

{#if !checkCompatibility().platformAllowed}
<!-- Denies mobile users access to the platform -->
<IncompatiblePlatformView />
{:else}
{#if $state.isLoading}
<main class="h-screen w-screen bg-primary flex absolute z-10" transition:fade>
<LoadingSpinner />
</main>
{/if}
<!-- Here we use the hidden class, to allow for it to load in. -->
<main class="h-screen w-screen m-0 relative flex" class:hidden={$state.isLoading}>
<!-- OVERLAY ITEMS -->
<CookieBanner />
<OverlayView />
<BluetoothIncompatibilityWarningDialog />

<!-- SIDE BAR -->
<div class="h-full flex min-w-75 max-w-75">
<SideBarMenuView />
</div>
<Router>
{#if !checkCompatibility().platformAllowed}
<!-- Denies mobile users access to the platform -->
<IncompatiblePlatformView />
{:else}
{#if $state.isLoading}
<main class="h-screen w-screen bg-primary flex absolute z-10" transition:fade>
<LoadingSpinner />
</main>
{/if}
<!-- Here we use the hidden class, to allow for it to load in. -->
<!-- <main class="h-screen w-screen m-0 relative flex" class:hidden={$state.isLoading}> -->
<main class="h-screen w-screen m-0 relative flex">
<!-- OVERLAY ITEMS -->
<CookieBanner />
<OverlayView />
<BluetoothIncompatibilityWarningDialog />

<div
class="h-full w-full overflow-y-hidden overflow-x-auto
flex flex-col bg-backgrounddark shadow-2xl">
<!-- CONTENT -->
<div class="relative z-1 flex-1 overflow-y-auto flex-row">
<PageContentView />
<!-- SIDE BAR -->
<div class="h-full flex min-w-75 max-w-75">
<SideBarMenuView />
</div>

<!-- BOTTOM BAR -->
<div class="h-160px w-full">
<BottomBarMenuView />
<div
class="h-full w-full overflow-y-hidden overflow-x-auto
flex flex-col bg-backgrounddark shadow-2xl">
<!-- CONTENT -->
<div class="relative z-1 flex-1 overflow-y-auto flex-row">
<PageContentView />
</div>

<!-- BOTTOM BAR -->
<div class="h-160px w-full">
<BottomBarMenuView />
</div>
</div>
</div>
<!-- </div> -->
</main>
{/if}
</main>
{/if}
</Router>
2 changes: 1 addition & 1 deletion src/components/Gesture.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@
<ImageSkeleton
height={95}
width={140}
src="imgs/microbit_record_guide.svg"
src="/imgs/microbit_record_guide.svg"
alt="microbit recording guide" />
</div>
<p class=" text-center absolute w-60px right-23px top-30px">
Expand Down
2 changes: 1 addition & 1 deletion src/components/LoadingSpinner.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script></script>

<div class="justify-center items-center self-center m-auto">
<img alt="loading" src="imgs/loadingspinner.gif" width="150px" />
<img alt="loading" src="/imgs/loadingspinner.gif" width="150px" />
</div>
2 changes: 1 addition & 1 deletion src/components/PleaseConnectFirst.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<div class="text-center ml-auto mr-auto mb-2 mt-10">
<img
class="m-auto arrow-filter-color"
src="imgs/down_arrow.svg"
src="/imgs/down_arrow.svg"
alt="down arrow icon"
width="100px" />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/bottom/ConnectedLiveGraphButtons.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
>{$t('footer.disconnectButton')}</StandardButton>
{:else}
<StandardButton onClick={TypingUtils.emptyFunction} color="disabled">
<img alt="loading" src="imgs/loadingspinner.gif" style="height:24px" />
<img alt="loading" src="/imgs/loadingspinner.gif" style="height:24px" />
</StandardButton>
{/if}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
<!-- Show spinner while connecting -->
<div class="w-650px flex flex-col justify-center items-center">
<p>{$t('popup.connectMB.bluetooth.connecting')}</p>
<img alt="loading" src="imgs/loadingspinner.gif" width="100px" />
<img alt="loading" src="/imgs/loadingspinner.gif" width="100px" />
</div>
{:else}
<div class="grid grid-cols-3 mb-5 w-650px">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<ImageSkeleton
alt="microbit recording guide"
height={134}
src="imgs/microbit_record_guide.svg"
src="/imgs/microbit_record_guide.svg"
width={200} />
</div>
<p class=" text-center absolute w-60px right-10px top-35px">
Expand Down
37 changes: 21 additions & 16 deletions src/pages/Homepage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,35 @@
import ContactUsControlBarButton from '../components/control-bar/control-bar-items/ContactUsControlBarButton.svelte';
import SelectLanguageControlBarDropdown from '../components/control-bar/control-bar-items/SelectLanguageControlBarDropdown.svelte';
import { t } from '../i18n';
import { state } from '../script/stores/uiStore';
// Just add the content titles you wish to put on front page, in the order you wish them to be there
const contentTiles = [DoItYourselfMachineLearningTile, IntroVideoTile];
</script>

<main class="h-full flex flex-col">
<div>
<ControlBar>
<div class="w-full">
<div class="float-right flex flex-row">
<ContactUsControlBarButton />
<SelectLanguageControlBarDropdown />
<div class:hidden={$state.isLoading}>
<div>
<ControlBar>
<div class="w-full">
<div class="float-right flex flex-row">
<ContactUsControlBarButton />
<SelectLanguageControlBarDropdown />
</div>
</div>
</ControlBar>
</div>
<div class="p-10 pb-2 pt-2 mt-3">
<div class="grid-container grid-cols-2 min-w-800px">
{#each contentTiles as contentTile}
<FrontPageContentTile contentComponent={contentTile} />
{/each}
</div>
</div>
<div class="flex-grow flex items-end">
<div class="pb-2 pl-10">
<p>{$t('content.index.acknowledgement')}</p>
</div>
</ControlBar>
</div>
<div class="p-10 pb-2 pt-2 mt-3">
<div class="grid-container grid-cols-2 min-w-800px">
{#each contentTiles as contentTile}
<FrontPageContentTile contentComponent={contentTile} />
{/each}
</div>
</div>
<div class="flex-grow flex items-end">
<div class="pb-2 pl-10"><p>{$t('content.index.acknowledgement')}</p></div>
</div>
</main>
2 changes: 1 addition & 1 deletion src/pages/ModelPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
<div class="text-center ml-0 mb-2 mt-8">
<img
class="m-auto arrow-filter-color"
src="imgs/down_arrow.svg"
src="/imgs/down_arrow.svg"
alt="down arrow icon"
width="80px" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<ImageSkeleton
alt="microbit guide"
height={114}
src="imgs/microbit_guide.svg"
src="/imgs/microbit_guide.svg"
width={200} />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/training/TrainingPage.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import { slide } from 'svelte/transition';
import TrainingButton from './TrainingButton.svelte';
import PleaseConnectFirst from '../../components/PleaseConnectFirst.svelte';
import { Paths, navigate } from '../../script/navigation/Navigation';
import ControlBar from '../../components/control-bar/ControlBar.svelte';
import ExpandableControlBarMenu from '../../components/control-bar/control-bar-items/ExpandableControlBarMenu.svelte';
import StandardButton from '../../components/StandardButton.svelte';
import { Paths, navigate } from '../../router/paths';
const sufficientData = hasSufficientData();
Expand Down
96 changes: 96 additions & 0 deletions src/router/Router.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<script lang="ts">
import { onMount } from 'svelte';
import DataPage from '../pages/DataPage.svelte';
import Homepage from '../pages/Homepage.svelte';
import ModelPage from '../pages/ModelPage.svelte';
import FilterPage from '../pages/filter/FilterPage.svelte';
import TrainingPage from '../pages/training/TrainingPage.svelte';
import { currentPageComponent } from '../views/currentComponentStore';
import { currentPath, navigate, Paths, PathType } from './paths';
function getRoutedComponent(path: PathType) {
switch (path) {
case Paths.HOME:
return Homepage;
case Paths.DATA:
return DataPage;
case Paths.TRAINING:
return TrainingPage;
case Paths.MODEL:
return ModelPage;
case Paths.FILTERS:
return FilterPage;
}
// Hacky way of ensuring exhaustive switch statement (at compile time)
// since typescript does not have this by default.
const exhaustiveCheck: never = path;
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Non Exhaustive switch. ${exhaustiveCheck} not handled.`);
}
const onPathChange = (path: PathType) => {
currentPageComponent.set(getRoutedComponent(path));
let shouldPushState = true;
const historyState = pathFromBrowserHistoryState(history.state);
if (historyState !== undefined && historyState === path) {
shouldPushState = false;
}
if (shouldPushState) {
const url = window.location.origin + (path.startsWith('/') ? '' : '/') + path;
history.pushState({ path: path }, '', url);
}
};
const pathFromBrowserHistoryState = (state: unknown): PathType | undefined => {
if (typeof state !== 'object' || state == null) {
return undefined;
}
if (!('path' in state)) {
return undefined;
}
if (typeof state.path !== 'string') {
return undefined;
}
if (!Object.values(Paths).includes(state.path as PathType)) {
return undefined;
}
return state.path as PathType;
};
const navigateFromUrl = () => {
let urlPath = window.location.pathname;
if (urlPath.startsWith('/')) {
urlPath = urlPath.substring(1, urlPath.length);
}
let path: PathType = Paths.HOME;
if (Object.values(Paths).includes(urlPath as PathType)) {
path = urlPath as PathType;
navigate(path);
} else {
history.replaceState({}, '', Paths.HOME);
}
};
navigateFromUrl();
$: onPathChange($currentPath);
const onPopstateEvent = (event: PopStateEvent) => {
const state: unknown = event.state;
const path = pathFromBrowserHistoryState(state);
if (path !== undefined) {
navigate(path);
}
};
onMount(() => {
addEventListener('popstate', onPopstateEvent);
return () => {
removeEventListener('popstate', onPopstateEvent);
};
});
</script>

<slot />
21 changes: 21 additions & 0 deletions src/router/paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { writable, Writable, get, derived } from 'svelte/store';

export const Paths = {
HOME: '/',
DATA: 'data',
TRAINING: 'training',
MODEL: 'model',
FILTERS: 'training/filters',
} as const;

export type PathType = (typeof Paths)[keyof typeof Paths];

export const currentPathPrivate: Writable<PathType> = writable(Paths.HOME);
export const currentPath = derived(currentPathPrivate, path => path);

export function navigate(path: PathType) {
if (path === get(currentPath)) {
return;
}
currentPathPrivate.set(path);
}
6 changes: 3 additions & 3 deletions src/script/navigation/Menus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { writable } from 'svelte/store';
import GestureMenu from '../../menus/DataMenu.svelte';
import NewTrainerMenu from '../../menus/TrainingMenu.svelte';
import NewModelMenu from '../../menus/ModelMenu.svelte';
import { Paths } from './Navigation';
import { Paths, PathType } from '../../router/paths';

export type MenuProperties = {
title: string;
infoBubbleTitle: string;
infoBubbleContent: string;
navigationPath: Paths;
navigationPath: PathType;
collapsedButtonContent: typeof SvelteComponent | undefined;
expandedButtonContent: typeof SvelteComponent;
additionalExpandPaths?: Paths[];
additionalExpandPaths?: PathType[];
};

/**
Expand Down
Loading

0 comments on commit b128f00

Please sign in to comment.