diff --git a/client/package.json b/client/package.json index f7a487760..43e36fee4 100644 --- a/client/package.json +++ b/client/package.json @@ -88,6 +88,7 @@ "resolve-url-loader": "3.1.0", "rg-stats": "^0.2.0", "socicon": "3.0.5", + "sync-fetch": "^0.3.1", "tachi-common": "0.5.7" }, "devDependencies": { diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 6abb9c969..d31b197db 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -90,6 +90,7 @@ specifiers: serve: 11.2.0 socicon: 3.0.5 style-loader: 1.0.0 + sync-fetch: ^0.3.1 tachi-common: 0.5.7 terser-webpack-plugin: 1.4.1 ts-pnp: 1.1.4 @@ -168,6 +169,7 @@ dependencies: resolve-url-loader: 3.1.0 rg-stats: 0.2.0 socicon: 3.0.5 + sync-fetch: 0.3.1 tachi-common: 0.5.7 devDependencies: @@ -8622,6 +8624,18 @@ packages: is-stream: 1.1.0 dev: false + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + /node-forge/0.10.0: resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==} engines: {node: '>= 6.0.0'} @@ -11553,6 +11567,16 @@ packages: unquote: 1.1.1 util.promisify: 1.0.1 + /sync-fetch/0.3.1: + resolution: {integrity: sha512-xj5qiCDap/03kpci5a+qc5wSJjc8ZSixgG2EUmH1B8Ea2sfWclQA7eH40hiHPCtkCn6MCk4Wb+dqcXdCy2PP3g==} + engines: {node: '>=8'} + dependencies: + buffer: 5.7.1 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: false + /table/6.7.1: resolution: {integrity: sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==} engines: {node: '>=10.0.0'} @@ -11712,6 +11736,10 @@ packages: engines: {node: '>=0.6'} dev: true + /tr46/0.0.3: + resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=} + dev: false + /trough/2.0.2: resolution: {integrity: sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==} dev: false @@ -12139,6 +12167,10 @@ packages: minimalistic-assert: 1.0.1 dev: true + /webidl-conversions/3.0.1: + resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} + dev: false + /webpack-cli/3.3.11_webpack@4.41.0: resolution: {integrity: sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==} engines: {node: '>=6.11.5'} @@ -12330,6 +12362,13 @@ packages: resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} dev: false + /whatwg-url/5.0.0: + resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: diff --git a/client/src/app/pages/dashboard/DashboardPage.tsx b/client/src/app/pages/dashboard/DashboardPage.tsx index 3c1b18245..6c0b05c44 100644 --- a/client/src/app/pages/dashboard/DashboardPage.tsx +++ b/client/src/app/pages/dashboard/DashboardPage.tsx @@ -127,8 +127,8 @@ function UserGameStatsInfo({ user }: { user: PublicUserDocument }) { ); } - const i1 = TachiConfig.supportedGames.indexOf(a.game); - const i2 = TachiConfig.supportedGames.indexOf(b.game); + const i1 = TachiConfig.games.indexOf(a.game); + const i2 = TachiConfig.games.indexOf(b.game); return i1 - i2; }); diff --git a/client/src/app/pages/dashboard/import/BatchManualPage.tsx b/client/src/app/pages/dashboard/import/BatchManualPage.tsx index 135fd910e..6ba057548 100644 --- a/client/src/app/pages/dashboard/import/BatchManualPage.tsx +++ b/client/src/app/pages/dashboard/import/BatchManualPage.tsx @@ -24,7 +24,7 @@ export default function BatchManualPage() { if (!gameConfig) { throw new Error( - `Invalid game ${data.meta.game}. Expected any of ${TachiConfig.supportedGames}.` + `Invalid game ${data.meta.game}. Expected any of ${TachiConfig.games}.` ); } diff --git a/client/src/app/pages/dashboard/import/ImportPage.tsx b/client/src/app/pages/dashboard/import/ImportPage.tsx index 69f7b72cf..1b686e7b6 100644 --- a/client/src/app/pages/dashboard/import/ImportPage.tsx +++ b/client/src/app/pages/dashboard/import/ImportPage.tsx @@ -35,7 +35,7 @@ export default function ImportPage() { onChange={e => setGame(e.target.value === "" ? null : (e.target.value as Game))} > - {TachiConfig.supportedGames.map(e => ( + {TachiConfig.games.map(e => ( diff --git a/client/src/components/layout/header/AllGames.tsx b/client/src/components/layout/header/AllGames.tsx index b78b185e8..2090ed43c 100644 --- a/client/src/components/layout/header/AllGames.tsx +++ b/client/src/components/layout/header/AllGames.tsx @@ -7,7 +7,7 @@ import MenuLink from "./MenuLink"; export default function AllGames() { const links = []; - for (const game of TachiConfig.supportedGames) { + for (const game of TachiConfig.games) { const gameConfig = GetGameConfig(game); for (const playtype of gameConfig.validPlaytypes) { diff --git a/client/src/components/layout/header/HeaderMenu.tsx b/client/src/components/layout/header/HeaderMenu.tsx index b7ed9082b..60374d986 100644 --- a/client/src/components/layout/header/HeaderMenu.tsx +++ b/client/src/components/layout/header/HeaderMenu.tsx @@ -57,7 +57,7 @@ export function HeaderMenu() { ugsMap.set(`${s.game}:${s.playtype}`, s); } - for (const game of TachiConfig.supportedGames) { + for (const game of TachiConfig.games) { for (const playtype of GetGameConfig(game).validPlaytypes) { const e = ugsMap.get(`${game}:${playtype}`); diff --git a/client/src/components/layout/header/SearchBar.tsx b/client/src/components/layout/header/SearchBar.tsx index e651758f3..5293ebf90 100644 --- a/client/src/components/layout/header/SearchBar.tsx +++ b/client/src/components/layout/header/SearchBar.tsx @@ -81,7 +81,7 @@ function SearchResults({ results }: { results: SearchReturns }) { const params = useLocation<{ game?: Game; playtype?: Playtype }>(); const { game, playtype } = useMemo(() => { - const regexp = `/games/(${TachiConfig.supportedGames.join("|")})/[^/]*/?`; + const regexp = `/games/(${TachiConfig.games.join("|")})/[^/]*/?`; if (params.pathname.match(new RegExp(regexp, "u"))) { const hack = params.pathname.split("/games/")[1].split("/"); diff --git a/client/src/lib/config.ts b/client/src/lib/config.ts index 119850d00..ad9f6f8a5 100644 --- a/client/src/lib/config.ts +++ b/client/src/lib/config.ts @@ -1,5 +1,8 @@ import { Game, ImportTypes } from "tachi-common"; import { allImportTypes, allSupportedGames } from "tachi-common/js/config/static-config"; +// @ts-expect-error No types available... +import syncFetch from "sync-fetch"; +import { ToAPIURL } from "util/api"; export const mode = process.env.REACT_APP_TCHIC_MODE; @@ -7,58 +10,36 @@ if (!mode) { throw new Error("No REACT_APP_TCHIC_MODE set in Process Environment, refusing to boot."); } -let conf: { +export interface TachiConfig { name: string; type: "ktchi" | "btchi" | "omni"; - supportedGames: Game[]; + games: Game[]; importTypes: ImportTypes[]; -}; +} + +let configRes; +try { + configRes = syncFetch(ToAPIURL("/config")).json(); + + if (!configRes.success) { + throw new Error(`Failed to fetch config -- ${configRes.description}.`); + } +} catch (err) { + throw new Error(`Site is (probably) down. Sorry. (${(err as Error).message})`); +} + +const conf: TachiConfig = configRes.body; let colourConf; if (mode === "ktchi") { - conf = { - name: "Kamaitachi", - type: "ktchi", - // TODO: #78 This should inherit in some way from the server config. Can we reflect - // this out somehow? - supportedGames: ["iidx", "chunithm", "museca", "sdvx", "wacca", "popn", "jubeat"], - importTypes: [ - "api/arc-iidx", - "api/arc-sdvx", - "api/eag-iidx", - "api/eag-sdvx", - "api/flo-iidx", - "api/flo-sdvx", - "api/min-sdvx", - "ir/direct-manual", - "ir/fervidex", - "ir/fervidex-static", - "file/eamusement-iidx-csv", - "file/eamusement-sdvx-csv", - "file/solid-state-squad", - "file/pli-iidx-csv", - ], - }; colourConf = { primary: "#e61c6e", }; } else if (mode === "btchi") { - conf = { - name: "Bokutachi", - type: "btchi", - supportedGames: ["bms", "usc"], - importTypes: ["ir/beatoraja", "ir/usc", "ir/direct-manual", "file/batch-manual"], - }; colourConf = { primary: "#4974a5", }; } else if (mode === "omni") { - conf = { - name: "Omnitachi", - type: "omni", - supportedGames: allSupportedGames, - importTypes: allImportTypes, - }; colourConf = { primary: "#e61c6e", }; diff --git a/client/src/util/asserts.ts b/client/src/util/asserts.ts index 72d12d6fb..5824d4956 100644 --- a/client/src/util/asserts.ts +++ b/client/src/util/asserts.ts @@ -9,7 +9,7 @@ import { } from "tachi-common"; export function IsSupportedGame(str: string): str is Game { - return TachiConfig.supportedGames.includes((str as unknown) as Game); + return TachiConfig.games.includes((str as unknown) as Game); } export function IsSupportedPlaytype( diff --git a/client/src/util/site.ts b/client/src/util/site.ts index 7607ec434..903d7f9e0 100644 --- a/client/src/util/site.ts +++ b/client/src/util/site.ts @@ -3,7 +3,7 @@ import { GetGameConfig } from "tachi-common"; export function GetSortedGPTs() { const arr = []; - for (const game of TachiConfig.supportedGames) { + for (const game of TachiConfig.games) { const gameConfig = GetGameConfig(game); for (const playtype of gameConfig.validPlaytypes) { arr.push({ game, playtype });