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

kiosk: download targetconfig.json at startup #9723

Merged
merged 3 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,12 @@ ${gcards.map(gcard => `[${gcard.name}](${gcard.url})`).join(',\n')}
if (game.subtitle) targetStrings[`{id:game-subtitle}${game.subtitle}`] = game.subtitle;
}

const kioskGames = targetConfig?.kiosk?.games;
for (const game of (kioskGames ?? [])) {
if (game.name) targetStrings[`{id:game-name}${game.name}`] = game.name;
if (game.description) targetStrings[`{id:game-description}${game.description}`] = game.description;
}

const approvedRepoLib = targetConfig?.packages?.approvedRepoLib;
for (const [extension, repoData] of Object.entries(approvedRepoLib ?? {})) {
for (const tag of (repoData.tags ?? [])) {
Expand Down
26 changes: 17 additions & 9 deletions kiosk/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { useLocationHash, usePromise } from "./Hooks";
import { launchGame } from "./Transforms/launchGame";
import { navigate } from "./Transforms/navigate";
import { AppStateContext, AppStateReady } from "./State/AppStateContext";
import { downloadGameListAsync } from "./Transforms/downloadGameListAsync";
import { downloadTargetConfigAsync } from "./Transforms/downloadTargetConfigAsync";
import * as Actions from "./State/Actions";
import * as SimHost from "./Services/SimHostService";
import * as NotificationService from "./Services/NotificationService";
Expand All @@ -40,14 +40,22 @@ function App() {
// Load persistent state from local storage.
dispatch(Actions.loadHighScores());
dispatch(Actions.loadKioskCode());
// Download the game list from the server and set it in the app state.
downloadGameListAsync().then(gameList => {
dispatch(Actions.setGameList(gameList));
// Load user-added games from local storage.
dispatch(Actions.loadUserAddedGames());
// Select the first game in the list.
dispatch(Actions.setSelectedGameId(gameList[0].id));
});
// Download targetconfig.json, then initialize game list.
downloadTargetConfigAsync().then(cfg => {
if (cfg) {
dispatch(Actions.setTargetConfig(cfg));
if (cfg.kiosk) {
dispatch(Actions.setGameList(cfg.kiosk.games));
// Load user-added games from local storage.
dispatch(Actions.loadUserAddedGames());
// Select the first game in the list.
dispatch(Actions.setSelectedGameId(cfg.kiosk.games[0].id));
}
} else {
// TODO: Handle this better
dispatch(Actions.setTargetConfig({}));
}
});
// Init subsystems.
SimHost.initialize();
NotificationService.initialize();
Expand Down
8 changes: 5 additions & 3 deletions kiosk/src/Components/MainMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ const MainMenu: React.FC<IProps> = ({}) => {
launchAddGame();
};

const canShowMainMenu = ready && kiosk.targetConfig;

return (
<>
{!ready && (
{!canShowMainMenu && (
<div className="mainMenu">
<nav className="mainMenuTopBar">
<h1 className={`mainMenuHeader${lockedClassName}`}>
{lf("Initializing...")}
{lf("Loading...")}
</h1>
</nav>
</div>
)}
{ready && (
{canShowMainMenu && (
<div className="mainMenu">
<nav className="mainMenuTopBar">
<h1 className={`mainMenuHeader${lockedClassName}`}>
Expand Down
15 changes: 14 additions & 1 deletion kiosk/src/State/Actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ type HideModal = ActionBase & {
type: "HIDE_MODAL";
};

type SetTargetConfig = ActionBase & {
type: "SET_TARGET_CONFIG";
targetConfig: pxt.TargetConfig;
};


/**
* Union of all actions
*/
Expand All @@ -151,7 +157,8 @@ export type Action =
| RemoveNotification
| LoadKioskCode
| ShowModal
| HideModal;
| HideModal
| SetTargetConfig;

/**
* Action creators
Expand Down Expand Up @@ -272,6 +279,11 @@ const hideModal = (): HideModal => ({
type: "HIDE_MODAL",
});

const setTargetConfig = (targetConfig: pxt.TargetConfig): SetTargetConfig => ({
type: "SET_TARGET_CONFIG",
targetConfig,
});

export {
setGameList,
setSelectedGameId,
Expand All @@ -295,4 +307,5 @@ export {
loadKioskCode,
showModal,
hideModal,
setTargetConfig,
};
6 changes: 6 additions & 0 deletions kiosk/src/State/Reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,5 +217,11 @@ export default function reducer(state: AppState, action: Action): AppState {
modal: undefined,
};
}
case "SET_TARGET_CONFIG": {
return {
...state,
targetConfig: action.targetConfig,
};
}
}
}
1 change: 1 addition & 0 deletions kiosk/src/State/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type AppState = {
locked: boolean;
time?: string;
volume?: number;
targetConfig?: pxt.TargetConfig;
};

export const initialAppState: AppState = {
Expand Down
24 changes: 0 additions & 24 deletions kiosk/src/Transforms/downloadGameListAsync.ts

This file was deleted.

9 changes: 9 additions & 0 deletions kiosk/src/Transforms/downloadTargetConfigAsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export async function downloadTargetConfigAsync(): Promise<
pxt.TargetConfig | undefined
> {
try {
return await pxt.targetConfigAsync();
} catch (e) {
console.error(e);
}
}
12 changes: 12 additions & 0 deletions localtypings/pxtarget.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ declare namespace pxt {
// release manifest for the electron app
electronManifest?: pxt.electron.ElectronManifest;
profileNotification?: ProfileNotification;
kiosk?: KioskConfig;
}

interface PackagesConfig {
Expand Down Expand Up @@ -77,6 +78,17 @@ declare namespace pxt {
image?: string;
}

interface KioskConfig {
games: KioskGame[];
}

interface KioskGame {
id: string;
name: string;
description: string;
highScoreMode: string;
}

interface AppTarget {
id: string; // has to match ^[a-z]+$; used in URLs and domain names
platformid?: string; // eg "codal"; used when search for gh packages ("for PXT/codal"); defaults to id
Expand Down
2 changes: 1 addition & 1 deletion pxtlib/browserutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ namespace pxt.BrowserUtils {
export function isLocalHost(ignoreFlags?: boolean): boolean {
try {
return typeof window !== "undefined"
&& /^http:\/\/(localhost|127\.0\.0\.1):\d+\//.test(window.location.href)
&& /^http:\/\/(localhost|127\.0\.0\.1|192\.168\.\d+\.\d+):\d+\//.test(window.location.href)
&& (ignoreFlags || !/nolocalhost=1/.test(window.location.href))
&& !(pxt?.webConfig?.isStatic);
} catch (e) { return false; }
Expand Down
Loading