diff --git a/kiosk/src/Components/AddingGame.tsx b/kiosk/src/Components/AddingGame.tsx index fe6439eb7167..38ab8338bbfb 100644 --- a/kiosk/src/Components/AddingGame.tsx +++ b/kiosk/src/Components/AddingGame.tsx @@ -6,7 +6,6 @@ import "../Kiosk.css"; import AddGameButton from "./AddGameButton"; import { QRCodeSVG } from "qrcode.react"; import { generateKioskCodeAsync, getGameCodesAsync } from "../BackendRequests"; -import { isLocal, tickEvent } from "../browserUtils"; import { GameData } from "../Models/GameData"; import KioskNotification from "./KioskNotification"; import { playSoundEffect } from "../Services/SoundEffectService"; @@ -49,7 +48,7 @@ const AddingGame: React.FC = ({ kiosk }) => { playSoundEffect("switch"); } if ((menuButtonSelected && kiosk.gamepadManager.isAButtonPressed()) || kiosk.gamepadManager.isBButtonPressed()) { - tickEvent("kiosk.toMainMenu"); + pxt.tickEvent("kiosk.toMainMenu"); kiosk.showMainMenu(); playSoundEffect("select"); } @@ -59,14 +58,14 @@ const AddingGame: React.FC = ({ kiosk }) => { playSoundEffect("switch"); } if (qrCodeButtonSelected && kiosk.gamepadManager.isAButtonPressed()) { - tickEvent("kiosk.newKioskCode"); + pxt.tickEvent("kiosk.newKioskCode"); setRenderQRCode(true); playSoundEffect("select"); } }; const kioskLinkClicked = () => { - tickEvent("kiosk.addGameLink"); + pxt.tickEvent("kiosk.addGameLink"); return true; }; diff --git a/kiosk/src/Components/DeletionModal.tsx b/kiosk/src/Components/DeletionModal.tsx index bb419eddf644..f353472ad128 100644 --- a/kiosk/src/Components/DeletionModal.tsx +++ b/kiosk/src/Components/DeletionModal.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "react"; -import { tickEvent } from "../browserUtils"; import "../Kiosk.css"; import { Kiosk } from "../Models/Kiosk"; import configData from "../config.json"; @@ -55,14 +54,14 @@ const DeletionModal: React.FC = ({ kiosk, active, changeFocus }) => { } if (cancelButtonState && kiosk.gamepadManager.isAButtonPressed()) { kiosk.gamepadManager.blockAPressUntilRelease(); - tickEvent("kiosk.deleteGame.cancelled"); + pxt.tickEvent("kiosk.deleteGame.cancelled"); playSoundEffect("select"); cancelClicked(); } if (confirmButtonState && kiosk.gamepadManager.isAButtonPressed()) { kiosk.gamepadManager.blockAPressUntilRelease(); - tickEvent("kiosk.deleteGame.confirmed"); + pxt.tickEvent("kiosk.deleteGame.confirmed"); playSoundEffect("select"); confirmClicked(); } diff --git a/kiosk/src/Components/ErrorModal.tsx b/kiosk/src/Components/ErrorModal.tsx index 97fe5053e376..6200449584ea 100644 --- a/kiosk/src/Components/ErrorModal.tsx +++ b/kiosk/src/Components/ErrorModal.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "react"; -import { tickEvent } from "../browserUtils"; import "../Kiosk.css"; interface IProps { @@ -13,7 +12,7 @@ const ErrorModal: React.FC = ({ setShowing, }) => { const cancelClicked = () => { - tickEvent("kiosk.scanError.dismissed"); + pxt.tickEvent("kiosk.scanError.dismissed"); setShowing(""); }; diff --git a/kiosk/src/Components/GameList.tsx b/kiosk/src/Components/GameList.tsx index adcb343dac8a..272263d38e23 100644 --- a/kiosk/src/Components/GameList.tsx +++ b/kiosk/src/Components/GameList.tsx @@ -8,7 +8,6 @@ import { EffectCoverflow, Keyboard, Navigation, Pagination } from "swiper"; import "swiper/css"; import "swiper/css/keyboard"; import GameSlide from "./GameSlide"; -import { tickEvent } from "../browserUtils"; import { playSoundEffect } from "../Services/SoundEffectService"; interface IProps { @@ -73,7 +72,7 @@ const GameList: React.FC = ({ const gameId = kiosk.selectedGame?.id; if (gameId) { - tickEvent("kiosk.gameLaunched", { game: gameId }); + pxt.tickEvent("kiosk.gameLaunched", { game: gameId }); kiosk.launchGame(gameId); playSoundEffect("select"); } diff --git a/kiosk/src/Components/GameOver.tsx b/kiosk/src/Components/GameOver.tsx index 45cc582905fc..0bfee793940f 100644 --- a/kiosk/src/Components/GameOver.tsx +++ b/kiosk/src/Components/GameOver.tsx @@ -3,7 +3,6 @@ import { Kiosk } from "../Models/Kiosk"; import AddGameButton from "./AddGameButton"; import configData from "../config.json"; import { KioskState } from "../Models/KioskState"; -import { tickEvent } from "../browserUtils"; import { playSoundEffect } from "../Services/SoundEffectService"; interface IProps { @@ -27,13 +26,13 @@ const GameOver: React.FC = ({ kiosk }) => { playSoundEffect("switch"); } if (homeButtonSelected && kiosk.gamepadManager.isAButtonPressed()) { - tickEvent("kiosk.gameOver.mainMenu"); + pxt.tickEvent("kiosk.gameOver.mainMenu"); playSoundEffect("select"); kiosk.navigate(KioskState.MainMenu); } if (retryButtonSelected && kiosk.gamepadManager.isAButtonPressed()) { - tickEvent("kiosk.gameOver.retry"); + pxt.tickEvent("kiosk.gameOver.retry"); playSoundEffect("select"); kiosk.launchGame(gameId); } diff --git a/kiosk/src/Components/HighScoreInitial.tsx b/kiosk/src/Components/HighScoreInitial.tsx index a5a003ef0ca7..19d1d900103e 100644 --- a/kiosk/src/Components/HighScoreInitial.tsx +++ b/kiosk/src/Components/HighScoreInitial.tsx @@ -1,7 +1,6 @@ import { useEffect, useState } from "react"; import { Kiosk } from "../Models/Kiosk"; import configData from "../config.json"; -import { tickEvent } from "../browserUtils"; interface IProps { kiosk: Kiosk; @@ -45,12 +44,12 @@ const HighScoreInitial: React.FC = ({ } if (kiosk.gamepadManager.isUpPressed()) { - tickEvent("kiosk.newHighScore.upPressed"); + pxt.tickEvent("kiosk.newHighScore.upPressed"); previousInitial(); } if (kiosk.gamepadManager.isDownPressed()) { - tickEvent("kiosk.newHighScore.downPressed"); + pxt.tickEvent("kiosk.newHighScore.downPressed"); nextInitial(); } }; diff --git a/kiosk/src/Components/KioskNotification.tsx b/kiosk/src/Components/KioskNotification.tsx index 87b26c51a22b..c3fb4cd6e727 100644 --- a/kiosk/src/Components/KioskNotification.tsx +++ b/kiosk/src/Components/KioskNotification.tsx @@ -1,5 +1,4 @@ import { useEffect, useState } from "react"; -import { tickEvent } from "../browserUtils"; import "../Kiosk.css"; interface IProps { diff --git a/kiosk/src/Components/MainMenu.tsx b/kiosk/src/Components/MainMenu.tsx index 89e8c53ea7f8..b3c7136d9fd0 100644 --- a/kiosk/src/Components/MainMenu.tsx +++ b/kiosk/src/Components/MainMenu.tsx @@ -5,7 +5,6 @@ import GameList from "./GameList"; import configData from "../config.json"; import HighScoresList from "./HighScoresList"; import { DeleteButton } from "./DeleteButton"; -import { tickEvent } from "../browserUtils"; import DeletionModal from "./DeletionModal"; import { playSoundEffect } from "../Services/SoundEffectService"; @@ -48,7 +47,7 @@ const MainMenu: React.FC = ({ kiosk }) => { (kiosk.gamepadManager.isAButtonPressed() || kiosk.gamepadManager.isBButtonPressed()) ) { - tickEvent("kiosk.addGamePageLoaded"); + pxt.tickEvent("kiosk.addGamePageLoaded"); kiosk.launchAddGame(); playSoundEffect("select"); } @@ -78,7 +77,7 @@ const MainMenu: React.FC = ({ kiosk }) => { } }; } else { - tickEvent("kiosk.locked"); + pxt.tickEvent("kiosk.locked"); } }); diff --git a/kiosk/src/Components/NewScoreEntry.tsx b/kiosk/src/Components/NewScoreEntry.tsx index fb7add35a3d2..c32ae6ce4fbc 100644 --- a/kiosk/src/Components/NewScoreEntry.tsx +++ b/kiosk/src/Components/NewScoreEntry.tsx @@ -4,7 +4,6 @@ import { Kiosk } from "../Models/Kiosk"; import { KioskState } from "../Models/KioskState"; import HighScoreInitial from "./HighScoreInitial"; import configData from "../config.json"; -import { tickEvent } from "../browserUtils"; interface IProps { kiosk: Kiosk; @@ -30,11 +29,11 @@ const NewScoreEntry: React.FC = ({ kiosk }) => { } if (kiosk.gamepadManager.isAButtonPressed()) { - tickEvent("kiosk.newHighScore.nextInitial"); + pxt.tickEvent("kiosk.newHighScore.nextInitial"); setIndexChanged(true); setNextIndex(true); } else if (kiosk.gamepadManager.isBButtonPressed()) { - tickEvent("kiosk.newHighScore.prevInitial"); + pxt.tickEvent("kiosk.newHighScore.prevInitial"); setIndexChanged(true); setPreviousIndex(true); } else { @@ -44,7 +43,7 @@ const NewScoreEntry: React.FC = ({ kiosk }) => { } if (kiosk.gamepadManager.isEscapeButtonPressed()) { - tickEvent("kiosk.newHighScore.defaultInitialsUsed"); + pxt.tickEvent("kiosk.newHighScore.defaultInitialsUsed"); kiosk.saveHighScore( kiosk.selectedGame!.id, initials, @@ -108,7 +107,7 @@ const NewScoreEntry: React.FC = ({ kiosk }) => { if (updatedPressed >= 3) { setTimesAPressed(0); - tickEvent("kiosk.newHighScore.initialsEntered"); + pxt.tickEvent("kiosk.newHighScore.initialsEntered"); kiosk.saveHighScore( kiosk.selectedGame!.id, initials, diff --git a/kiosk/src/Components/QrScanner.tsx b/kiosk/src/Components/QrScanner.tsx index d9cf296a586e..0e640dbe2fb4 100644 --- a/kiosk/src/Components/QrScanner.tsx +++ b/kiosk/src/Components/QrScanner.tsx @@ -3,7 +3,6 @@ import { Html5Qrcode } from "html5-qrcode"; import { Kiosk } from "../Models/Kiosk"; import { addGameToKioskAsync } from "../BackendRequests"; import { KioskState } from "../Models/KioskState"; -import { tickEvent } from "../browserUtils"; export const play = async ( kiosk: Kiosk, @@ -18,7 +17,7 @@ export const play = async ( const shareId = /\/([^\/]+)\/?$/.exec(decodedText)?.[1]; try { await addGameToKioskAsync(kioskId, shareId); - tickEvent("kiosk.gameQrScanned.success"); + pxt.tickEvent("kiosk.gameQrScanned.success"); await html5QrCode.stop(); kiosk.navigate(KioskState.QrSuccess); } catch (error: any) { diff --git a/kiosk/src/Components/QrSuccess.tsx b/kiosk/src/Components/QrSuccess.tsx index 6d7fab0b1a61..a5f6ffecc7da 100644 --- a/kiosk/src/Components/QrSuccess.tsx +++ b/kiosk/src/Components/QrSuccess.tsx @@ -1,11 +1,10 @@ import { useEffect } from "react"; -import { tickEvent } from "../browserUtils"; import "../Kiosk.css"; const QrSuccess: React.FC<{}> = () => { // TODO: pass the game's title and the kiosk's id through to give more feedback to the user useEffect(() => { - tickEvent("kiosk.qrSuccessLoaded"); + pxt.tickEvent("kiosk.qrSuccessLoaded"); }, []); return ( diff --git a/kiosk/src/Components/ScanQR.tsx b/kiosk/src/Components/ScanQR.tsx index f7b177f5f0bf..d859621545b2 100644 --- a/kiosk/src/Components/ScanQR.tsx +++ b/kiosk/src/Components/ScanQR.tsx @@ -5,7 +5,6 @@ import { play, stopScan } from "./QrScanner"; import { addGameToKioskAsync } from "../BackendRequests"; import { KioskState } from "../Models/KioskState"; import { Html5Qrcode } from "html5-qrcode"; -import { tickEvent } from "../browserUtils"; import ErrorModal from "./ErrorModal"; interface IProps { @@ -24,13 +23,13 @@ const ScanQR: React.FC = ({ kiosk }) => { const [html5QrCode, setHtml5QrCode] = useState(); const renderQrScanner = () => { - tickEvent("kiosk.scanQrClicked"); + pxt.tickEvent("kiosk.scanQrClicked"); play(kiosk, kioskId!, html5QrCode!, setAddingError, setErrorDesc); setScannerVisible(true); }; const stopQrScanner = () => { - tickEvent("kiosk.stopScanClicked"); + pxt.tickEvent("kiosk.stopScanClicked"); stopScan(html5QrCode!); setScannerVisible(false); }; @@ -43,12 +42,12 @@ const ScanQR: React.FC = ({ kiosk }) => { }; const clickHelp = () => { - tickEvent("kiosk.helpLink"); + pxt.tickEvent("kiosk.helpLink"); return true; }; useEffect(() => { - tickEvent("kiosk.scanQrLoaded"); + pxt.tickEvent("kiosk.scanQrLoaded"); initiateQrCode(); }, []); @@ -71,12 +70,12 @@ const ScanQR: React.FC = ({ kiosk }) => { } else if (shareCode) { shareId = shareCode[1]; } - tickEvent("kiosk.submitGameId.clicked", { submitVal: inputValue }); + pxt.tickEvent("kiosk.submitGameId.clicked", { submitVal: inputValue }); if (shareId) { setLinkError(false); try { await addGameToKioskAsync(kioskId, shareId); - tickEvent("kiosk.submitGameId.submitSuccess"); + pxt.tickEvent("kiosk.submitGameId.submitSuccess"); kiosk.navigate(KioskState.QrSuccess); } catch (error: any) { setAddingError(error.toString()); diff --git a/kiosk/src/Models/Kiosk.ts b/kiosk/src/Models/Kiosk.ts index f511ccbf1771..2d9022154eeb 100644 --- a/kiosk/src/Models/Kiosk.ts +++ b/kiosk/src/Models/Kiosk.ts @@ -5,7 +5,6 @@ import { BuiltSimJSInfo } from "./BuiltSimJsInfo"; import { KioskState } from "./KioskState"; import configData from "../config.json"; import { getGameDetailsAsync } from "../BackendRequests"; -import { tickEvent } from "../browserUtils"; import { setSoundEffectVolume } from "../Services/SoundEffectService"; export class Kiosk { @@ -64,7 +63,7 @@ export class Kiosk { ); } } else { - tickEvent("kiosk.clean"); + pxt.tickEvent("kiosk.clean"); } // the added games persist in local storage, but not the live game list diff --git a/kiosk/src/browserUtils.ts b/kiosk/src/browserUtils.ts deleted file mode 100644 index 0770c6f9a5b6..000000000000 --- a/kiosk/src/browserUtils.ts +++ /dev/null @@ -1,28 +0,0 @@ -export function tickEvent( - id: string, - data?: { [key: string]: string | number } -) { - (window as any).pxtTickEvent?.(id, data); -} - -export function devicePixelRatio(): number { - if (typeof window === "undefined" || !window.screen) return 1; - - // these are IE specific - const sysXDPI = (window.screen as any).systemXDPI; - const logicalXDPI = (window.screen as any).logicalXDPI; - if ( - sysXDPI !== undefined && - logicalXDPI !== undefined && - sysXDPI > logicalXDPI - ) { - return sysXDPI / logicalXDPI; - } else if (window && window.devicePixelRatio !== undefined) { - return window.devicePixelRatio; - } - return 1; -} - -export function isLocal() { - return window.location.hostname === "localhost"; -} diff --git a/kiosk/src/index.tsx b/kiosk/src/index.tsx index a4992e972e4e..ccb95078e7d8 100644 --- a/kiosk/src/index.tsx +++ b/kiosk/src/index.tsx @@ -1,15 +1,19 @@ +// TODO: pxtcompiler type is only needed for a few compiler service types, +// we should get rid of this somehow. +/// +/// +/// + import React from "react"; import ReactDOM from "react-dom/client"; +// eslint-disable-next-line import/no-unassigned-import import "./Kiosk.css"; import App from "./App"; -import { devicePixelRatio, isLocal, tickEvent } from "./browserUtils"; - -interface Map { - [index: string]: T; -} function enableAnalytics() { - const stats: Map = {}; + pxt.analytics.enable(pxt.Util.userLanguage()); + + const stats: pxt.Map = {}; if (typeof window !== "undefined") { const screen = window.screen; stats["screen.width"] = screen.width; @@ -18,19 +22,32 @@ function enableAnalytics() { stats["screen.availheight"] = screen.availHeight; stats["screen.innerWidth"] = window.innerWidth; stats["screen.innerHeight"] = window.innerHeight; - stats["screen.devicepixelratio"] = devicePixelRatio(); + stats["screen.devicepixelratio"] = pxt.BrowserUtils.devicePixelRatio(); const body = document.firstElementChild; // body if (body) { stats["screen.clientWidth"] = body.clientWidth; stats["screen.clientHeight"] = body.clientHeight; } } - tickEvent("kiosk.loaded", stats); + pxt.tickEvent("kiosk.loaded", stats); } window.addEventListener("DOMContentLoaded", () => { + const bundle = (window as any).pxtTargetBundle as pxt.TargetBundle; + + pxt.options.debug = /dbg=1/i.test(window.location.href); + if (pxt.options.debug) pxt.debug = console.debug; + + pxt.setupWebConfig((window as any).pxtConfig || pxt.webConfig); + pxt.setAppTarget(bundle); + + pxt.Cloud.apiRoot = "https://www.makecode.com/api/"; + enableAnalytics(); + // prefetch worker on load + pxt.worker.getWorker(pxt.webConfig.workerjs); + const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement );