mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-07 14:28:09 +03:00
ARC support.
This commit is contained in:
+1
-1
@@ -80,7 +80,7 @@
|
||||
"resolve": "1.12.0",
|
||||
"resolve-url-loader": "3.1.0",
|
||||
"socicon": "3.0.5",
|
||||
"tachi-common": "0.3.0"
|
||||
"tachi-common": "0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/humanize-duration": "3.25.1",
|
||||
|
||||
Generated
+4
-4
@@ -82,7 +82,7 @@ specifiers:
|
||||
serve: 11.2.0
|
||||
socicon: 3.0.5
|
||||
style-loader: 1.0.0
|
||||
tachi-common: 0.3.0
|
||||
tachi-common: 0.3.2
|
||||
terser-webpack-plugin: 1.4.1
|
||||
ts-pnp: 1.1.4
|
||||
typescript: 4.3.5
|
||||
@@ -152,7 +152,7 @@ dependencies:
|
||||
resolve: 1.12.0
|
||||
resolve-url-loader: 3.1.0
|
||||
socicon: 3.0.5
|
||||
tachi-common: 0.3.0
|
||||
tachi-common: 0.3.2
|
||||
|
||||
devDependencies:
|
||||
'@types/humanize-duration': 3.25.1
|
||||
@@ -11211,8 +11211,8 @@ packages:
|
||||
strip-ansi: 6.0.0
|
||||
dev: true
|
||||
|
||||
/tachi-common/0.3.0:
|
||||
resolution: {integrity: sha512-ch7Msau97/on1d18bqRMUNUQhF9ZixzvNxMsLJNN14DBfS1AVxaoAfIRiQzWQ1jdfvwmcpP4Ge0x1w1prPZVAQ==}
|
||||
/tachi-common/0.3.2:
|
||||
resolution: {integrity: sha512-fX1ffleAJlP6WtjnGxVDfLsz7PQDArIFCMcvOjLB0+PwJ5FwhAO/8CX2B8ksYGuzp8PGWLxQGsPahwN9HV7YVQ==}
|
||||
dependencies:
|
||||
monk: 7.3.4
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import useSetSubheader from "components/layout/header/useSetSubheader";
|
||||
import QuickTooltip from "components/layout/misc/QuickTooltip";
|
||||
import Card from "components/layout/page/Card";
|
||||
import LampCell from "components/tables/cells/LampCell";
|
||||
import ScoreCell from "components/tables/cells/ScoreCell";
|
||||
@@ -31,6 +32,7 @@ import { PBDataset } from "types/tables";
|
||||
import { APIFetchV1, UnsuccessfulAPIFetchResponse } from "util/api";
|
||||
import { CreateUserMap } from "util/data";
|
||||
import { SelectRightChart } from "util/misc";
|
||||
import { FormatDate, MillisToSince } from "util/time";
|
||||
|
||||
// This component forms a wrapper around the Real GPT Chart Page
|
||||
// which handles the case where activeChart == null.
|
||||
@@ -319,6 +321,13 @@ function PlayCard({
|
||||
<LampCell score={pb} />
|
||||
</tr>
|
||||
</MiniTable>
|
||||
<div className="text-center">
|
||||
<Muted>
|
||||
{pb.timeAchieved
|
||||
? MillisToSince(pb.timeAchieved) ?? ""
|
||||
: "No Timestamp Info"}
|
||||
</Muted>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import ApiError from "components/util/ApiError";
|
||||
import Divider from "components/util/Divider";
|
||||
import Loading from "components/util/Loading";
|
||||
import Muted from "components/util/Muted";
|
||||
import useApiQuery from "components/util/query/useApiQuery";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, Col, Form } from "react-bootstrap";
|
||||
import { ARCSavedProfileDocument, PublicUserDocument } from "tachi-common";
|
||||
import { SetState } from "types/react";
|
||||
import { APIFetchV1 } from "util/api";
|
||||
|
||||
export default function ARCIntegrationPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
const [iidxID, setIIDXID] = useState("");
|
||||
const [sdvxID, setSDVXID] = useState("");
|
||||
|
||||
const { data, isLoading, error } = useApiQuery<{
|
||||
iidx: ARCSavedProfileDocument | null;
|
||||
sdvx: ARCSavedProfileDocument | null;
|
||||
}>(`/users/${reqUser.id}/integrations/arc`);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setIIDXID(data.iidx?.accountID ?? "");
|
||||
setSDVXID(data.sdvx?.accountID ?? "");
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
if (error) {
|
||||
return <ApiError error={error} />;
|
||||
}
|
||||
|
||||
if (!data || isLoading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Col xs={12}>
|
||||
<h4>ARC Integration</h4>
|
||||
<span>To import scores from ARC, just put your AccountIDs in the tabs below.</span>
|
||||
<br />
|
||||
<Muted>
|
||||
Note: Only the latest versions of IIDX and SDVX are supported for imports.
|
||||
</Muted>
|
||||
<Divider />
|
||||
<h5>How to get your AccountID</h5>
|
||||
<ol className="text-left">
|
||||
<li>Open the ARC website.</li>
|
||||
<li>Go to the game you care about, and select My Bests.</li>
|
||||
<li>
|
||||
In the URL, after <code>/profiles</code>, there'll be a string that looks
|
||||
like <code>H4JxPV3vQH_</code>. Copy that into the text fields below!
|
||||
</li>
|
||||
<li>To unset an integration, remove the account ID and hit save.</li>
|
||||
</ol>
|
||||
</Col>
|
||||
<Col xs={12} className="mt-4">
|
||||
<IntegrationStatus name="IIDX" value={iidxID} setValue={setIIDXID} />
|
||||
{iidxID && iidxID.length !== 11 && (
|
||||
<span className="text-danger">
|
||||
Invalid IIDX ID, it should be 11 characters long.
|
||||
</span>
|
||||
)}
|
||||
|
||||
<IntegrationStatus name="SDVX" value={sdvxID} setValue={setSDVXID} />
|
||||
{sdvxID && sdvxID.length !== 11 && (
|
||||
<span className="text-danger">
|
||||
Invalid SDVX ID, it should be 11 characters long.
|
||||
</span>
|
||||
)}
|
||||
|
||||
<Divider />
|
||||
|
||||
<Button
|
||||
disabled={
|
||||
!!(iidxID && iidxID.length !== 11) || !!(sdvxID && sdvxID.length !== 11)
|
||||
}
|
||||
onClick={() => {
|
||||
APIFetchV1(
|
||||
`/users/${reqUser.id}/integrations/arc`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
iidx: iidxID || null,
|
||||
sdvx: sdvxID || null,
|
||||
}),
|
||||
},
|
||||
true,
|
||||
true
|
||||
);
|
||||
}}
|
||||
>
|
||||
Submit Settings
|
||||
</Button>
|
||||
</Col>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function IntegrationStatus({
|
||||
name,
|
||||
value,
|
||||
setValue,
|
||||
}: {
|
||||
name: string;
|
||||
value: string;
|
||||
setValue: SetState<string>;
|
||||
}) {
|
||||
return (
|
||||
<Form.Group className="mt-4">
|
||||
<Form.Label>{`${name} Account ID`}</Form.Label>
|
||||
<Form.Control
|
||||
type="text"
|
||||
value={value}
|
||||
placeholder="H4JxPV3vQH_"
|
||||
onChange={e => setValue(e.target.value)}
|
||||
/>
|
||||
</Form.Group>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import useSetSubheader from "components/layout/header/useSetSubheader";
|
||||
import Card from "components/layout/page/Card";
|
||||
import ApiError from "components/util/ApiError";
|
||||
import DebugContent from "components/util/DebugContent";
|
||||
import Divider from "components/util/Divider";
|
||||
import ExternalLink from "components/util/ExternalLink";
|
||||
import FormInput from "components/util/FormInput";
|
||||
@@ -16,12 +15,13 @@ import { Alert, Button, Col, Form, Modal, Row } from "react-bootstrap";
|
||||
import {
|
||||
APIPermissions,
|
||||
APITokenDocument,
|
||||
TachiAPIClientDocument,
|
||||
PublicUserDocument,
|
||||
TachiAPIClientDocument,
|
||||
} from "tachi-common";
|
||||
import { SetState } from "types/react";
|
||||
import { APIFetchV1 } from "util/api";
|
||||
import { allPermissions, DelayedPageReload } from "util/misc";
|
||||
import ARCIntegrationPage from "./ARCIntegrationPage";
|
||||
import FervidexIntegrationPage from "./FervidexIntegrationPage";
|
||||
|
||||
export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
@@ -41,7 +41,7 @@ export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserD
|
||||
{mode !== "btchi" && (
|
||||
<SelectButton value={page} setValue={setPage} id="services">
|
||||
<Icon type="network-wired" />
|
||||
Integrations
|
||||
Service Configuration
|
||||
</SelectButton>
|
||||
)}
|
||||
<SelectButton value={page} setValue={setPage} id="api-keys">
|
||||
@@ -57,7 +57,7 @@ export default function UserIntegrationsPage({ reqUser }: { reqUser: PublicUserD
|
||||
</Col>
|
||||
<Col xs={12}>
|
||||
{page === "services" ? (
|
||||
<IntegrationsPage reqUser={reqUser} />
|
||||
<ServicesPage reqUser={reqUser} />
|
||||
) : page === "api-keys" ? (
|
||||
<APIKeysPage reqUser={reqUser} />
|
||||
) : (
|
||||
@@ -605,7 +605,7 @@ function EditClientModal({
|
||||
);
|
||||
}
|
||||
|
||||
function IntegrationsPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
function ServicesPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
if (mode === "btchi") {
|
||||
return (
|
||||
<Row className="text-center">
|
||||
@@ -619,7 +619,7 @@ function IntegrationsPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
return (
|
||||
<Row className="text-center justify-content-center">
|
||||
<Col xs={12}>
|
||||
<h3>Services</h3>
|
||||
<h3>Service Configuration</h3>
|
||||
<Muted>
|
||||
Some services have had their names truncated to their first three characters for
|
||||
privacy reasons.
|
||||
@@ -637,7 +637,11 @@ function IntegrationsPage({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
</div>
|
||||
<Divider />
|
||||
</Col>
|
||||
{page === "fervidex" ? <FervidexIntegrationPage reqUser={reqUser} /> : <></>}
|
||||
{page === "fervidex" ? (
|
||||
<FervidexIntegrationPage reqUser={reqUser} />
|
||||
) : (
|
||||
<ARCIntegrationPage reqUser={reqUser} />
|
||||
)}
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ function PreferencesForm({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
developerMode: settings?.preferences.developerMode ?? false,
|
||||
invisible: settings?.preferences.invisible ?? false,
|
||||
contentiousContent: settings?.preferences.contentiousContent ?? false,
|
||||
advancedMode: settings?.preferences.advancedMode ?? false,
|
||||
},
|
||||
onSubmit: async values => {
|
||||
const res = await APIFetchV1<UserSettings>(
|
||||
@@ -107,6 +108,18 @@ function PreferencesForm({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
<Form.Text>Enable debug information and other useful debugging buttons.</Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group>
|
||||
<Form.Check
|
||||
type="checkbox"
|
||||
id="advancedMode"
|
||||
checked={formik.values.developerMode}
|
||||
onChange={formik.handleChange}
|
||||
label="Advanced Mode"
|
||||
/>
|
||||
<Form.Text>
|
||||
Enable advanced stuff, like being able to copy a tables contents into a CSV.
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
{/* <Form.Group>
|
||||
<Form.Check
|
||||
type="checkbox"
|
||||
id="invisible"
|
||||
@@ -115,7 +128,7 @@ function PreferencesForm({ reqUser }: { reqUser: PublicUserDocument }) {
|
||||
label="Invisible Mode"
|
||||
/>
|
||||
<Form.Text>Hide your last seen status.</Form.Text>
|
||||
</Form.Group>
|
||||
</Form.Group> */}
|
||||
<Form.Group>
|
||||
<Form.Check
|
||||
type="checkbox"
|
||||
@@ -320,7 +333,7 @@ function FileUploadController({
|
||||
DelayedPageReload();
|
||||
}
|
||||
}}
|
||||
disabled={!reqUser.customPfp}
|
||||
disabled={!reqUser.customPfpLocation}
|
||||
className="mr-auto"
|
||||
variant="secondary"
|
||||
>
|
||||
|
||||
@@ -12,6 +12,7 @@ import MerJSONPage from "app/pages/dashboard/import/MerJSONPage";
|
||||
import SSSXMLPage from "app/pages/dashboard/import/SSSXMLPage";
|
||||
import USCDBPage from "app/pages/dashboard/import/USCDBPage";
|
||||
import USCIRPage from "app/pages/dashboard/import/USCIRPage";
|
||||
import ARCImportPage from "components/imports/ARCImportPage";
|
||||
import KAIIntegrationPage from "components/imports/KAIIntegrationPage";
|
||||
import Divider from "components/util/Divider";
|
||||
import { UserContext } from "context/UserContext";
|
||||
@@ -98,6 +99,14 @@ export default function ImportRoutes() {
|
||||
<ChunitachiPage />
|
||||
</Route>
|
||||
|
||||
<Route exact path="/dashboard/import/iidx-arc">
|
||||
<ARCImportPage game="iidx" />
|
||||
</Route>
|
||||
|
||||
<Route exact path="/dashboard/import/sdvx-arc">
|
||||
<ARCImportPage game="sdvx" />
|
||||
</Route>
|
||||
|
||||
<Route exact path="/dashboard/import/iidx-flo">
|
||||
<KAIIntegrationPage
|
||||
hash="6f64b82107cea90aa4c51a33705cd57c1883c8cdc22a634730ca461a431744b3"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ErrorPage } from "app/pages/ErrorPage";
|
||||
import { UserContext } from "context/UserContext";
|
||||
import React, { useContext } from "react";
|
||||
import { useHistory, useParams, generatePath } from "react-router-dom";
|
||||
import { generatePath, useHistory, useParams } from "react-router-dom";
|
||||
import { JustChildren } from "types/react";
|
||||
|
||||
export default function RequireAuthAsUserParam({ children }: JustChildren) {
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
import useSetSubheader from "components/layout/header/useSetSubheader";
|
||||
import ApiError from "components/util/ApiError";
|
||||
import Divider from "components/util/Divider";
|
||||
import Loading from "components/util/Loading";
|
||||
import useApiQuery from "components/util/query/useApiQuery";
|
||||
import UpdateUserGameStats from "components/util/UpdateUserGameStats";
|
||||
import { UserContext } from "context/UserContext";
|
||||
import { UserGameStatsContext } from "context/UserGameStatsContext";
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Alert, Button } from "react-bootstrap";
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
APIImportTypes,
|
||||
ARCSavedProfileDocument,
|
||||
GetGameConfig,
|
||||
ImportDocument,
|
||||
} from "tachi-common";
|
||||
import { ImportStates, NotStartedState } from "types/import";
|
||||
import { APIFetchV1 } from "util/api";
|
||||
import ImportStateRenderer from "./ImportStateRenderer";
|
||||
|
||||
export default function ARCImportPage({ game }: { game: "sdvx" | "iidx" }) {
|
||||
const importType: APIImportTypes = game === "iidx" ? "api/arc-iidx" : "api/arc-sdvx";
|
||||
const { setUGS } = useContext(UserGameStatsContext);
|
||||
const { user } = useContext(UserContext);
|
||||
|
||||
useSetSubheader(["Imports", `ARC ${GetGameConfig(game).name} Synchronisation`]);
|
||||
|
||||
if (!user) {
|
||||
return <>No user? How did you get here!</>;
|
||||
}
|
||||
|
||||
const [importState, setImportState] = useState<ImportStates>(NotStartedState);
|
||||
|
||||
const { data, isLoading, error } = useApiQuery<{
|
||||
iidx: ARCSavedProfileDocument | null;
|
||||
sdvx: ARCSavedProfileDocument | null;
|
||||
}>(`/users/${user.id}/integrations/arc`);
|
||||
|
||||
if (error) {
|
||||
return <ApiError error={error} />;
|
||||
}
|
||||
|
||||
if (!data || isLoading) {
|
||||
return <Loading />;
|
||||
}
|
||||
|
||||
if (!data[game]) {
|
||||
return (
|
||||
<div>
|
||||
<h2>You are not authenticated for ARC {GetGameConfig(game).name}.</h2>
|
||||
<br />
|
||||
<h4>
|
||||
Please go to the{" "}
|
||||
<Link to={`/users/${user.id}/integrations`}>Service Settings for ARC</Link>, and
|
||||
link your account.
|
||||
</h4>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className="text-center mb-4">Authenticated with ARC!</h2>
|
||||
<Divider />
|
||||
<div className="d-flex w-100 justify-content-center">
|
||||
<Button
|
||||
className="mx-auto"
|
||||
variant="primary"
|
||||
onClick={async () => {
|
||||
setImportState({ state: "waiting" });
|
||||
|
||||
const res = await APIFetchV1<ImportDocument>(
|
||||
"/import/from-api",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
importType,
|
||||
}),
|
||||
},
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
if (res.success) {
|
||||
setImportState({ state: "done", import: res.body });
|
||||
UpdateUserGameStats(setUGS);
|
||||
} else {
|
||||
setImportState({ state: "failed", error: res.description });
|
||||
}
|
||||
}}
|
||||
disabled={importState.state === "waiting"}
|
||||
>
|
||||
{importState.state === "waiting" ? "Syncing..." : "Click to Sync!"}
|
||||
</Button>
|
||||
</div>
|
||||
<Divider />
|
||||
<Alert variant="warning">
|
||||
Play on ARC a lot? Please consider setting up{" "}
|
||||
{game === "iidx" ? (
|
||||
<Link style={{ color: "purple" }} to="/dashboard/import/fervidex">
|
||||
Fervidex
|
||||
</Link>
|
||||
) : (
|
||||
<Link style={{ color: "purple" }} to="/dashboard/import/barbatos">
|
||||
Barbatos
|
||||
</Link>
|
||||
)}{" "}
|
||||
instead.
|
||||
<br />
|
||||
ARC exports poor quality data, and can only save one score on a chart at a time.
|
||||
<br />
|
||||
In an ideal world, you should only have to use this sync once, and then should
|
||||
switch to an import method that exports scores better!
|
||||
</Alert>
|
||||
<Divider />
|
||||
<ImportStateRenderer state={importState} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import { Button, Form, InputGroup } from "react-bootstrap";
|
||||
import { APIImportTypes, GetGameConfig, ImportDocument } from "tachi-common";
|
||||
import { ImportStates, NotStartedState } from "types/import";
|
||||
import { APIFetchV1 } from "util/api";
|
||||
import ImportInfo from "./ImportInfo";
|
||||
import ImportStateRenderer from "./ImportStateRenderer";
|
||||
|
||||
interface Props {
|
||||
|
||||
@@ -165,27 +165,29 @@ export default function TachiTable<D>({
|
||||
<div className="row">
|
||||
<div className="col-lg-4 align-self-center">{displayStr}</div>
|
||||
<div className="d-none d-lg-flex col-lg-4 justify-content-center align-items-center">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
let data = dataset;
|
||||
if (search !== "") {
|
||||
data = filteredDataset;
|
||||
}
|
||||
{settings?.preferences.advancedMode && (
|
||||
<Button
|
||||
onClick={async () => {
|
||||
let data = dataset;
|
||||
if (search !== "") {
|
||||
data = filteredDataset;
|
||||
}
|
||||
|
||||
CopyToClipboard(
|
||||
// Faulty types with json2csv.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await json2csvAsync(data as any, {
|
||||
sortHeader: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
variant="outline-info"
|
||||
className="w-50"
|
||||
>
|
||||
<Icon type="table" />
|
||||
Export {search !== "" ? "Filtered Data" : "Table"} (CSV)
|
||||
</Button>
|
||||
CopyToClipboard(
|
||||
// Faulty types with json2csv.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
await json2csvAsync(data as any, {
|
||||
sortHeader: true,
|
||||
})
|
||||
);
|
||||
}}
|
||||
variant="outline-info"
|
||||
className="w-50"
|
||||
>
|
||||
<Icon type="table" />
|
||||
Export {search !== "" ? "Filtered Data" : "Table"} (CSV)
|
||||
</Button>
|
||||
)}
|
||||
{settings?.preferences.developerMode && (
|
||||
<Button
|
||||
className="ml-4 w-50"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import { Button } from "react-bootstrap";
|
||||
import { ButtonVariant } from "react-bootstrap/esm/types";
|
||||
import { JustChildren, SetState } from "types/react";
|
||||
import { JustChildren } from "types/react";
|
||||
import { DoesMatchRoute } from "util/routing";
|
||||
import LinkButton from "./LinkButton";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { createContext, useState } from "react";
|
||||
import { PublicUserDocument, UGPTSettings } from "tachi-common";
|
||||
import { UGPTSettings } from "tachi-common";
|
||||
import { JustChildren, SetState } from "types/react";
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
* Create React App entry point. This and `public/index.html` files can not be
|
||||
* changed or moved.
|
||||
*/
|
||||
import "@fortawesome/fontawesome-free/css/all.min.css";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import "socicon/css/socicon.css";
|
||||
import App from "./app/App";
|
||||
import "./index.scss";
|
||||
import "./_metronic/_assets/plugins/keenthemes-icons/font/ki.css";
|
||||
import "socicon/css/socicon.css";
|
||||
import "@fortawesome/fontawesome-free/css/all.min.css";
|
||||
import "./_metronic/_assets/plugins/flaticon/flaticon.css";
|
||||
import "./_metronic/_assets/plugins/flaticon2/flaticon.css";
|
||||
import "./_metronic/_assets/plugins/keenthemes-icons/font/ki.css";
|
||||
|
||||
const { PUBLIC_URL } = process.env;
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ export const loggedInSplashes = [
|
||||
"You wish you know who the hibble gibble gobbler was.",
|
||||
`The current day is ${FormatDate(Date.now())}, probably.`,
|
||||
"I have always thought of myself as an ambassador for the dance game community.",
|
||||
"When lava pours out near the sea surface, tremendous volcanic explosions sometimes occur.",
|
||||
];
|
||||
|
||||
// Stuff that's bad for the kids, you know?
|
||||
|
||||
Reference in New Issue
Block a user