diff --git a/packages/i18n/strings/en.json b/packages/i18n/strings/en.json
index fe4ed47b1..04125f138 100644
--- a/packages/i18n/strings/en.json
+++ b/packages/i18n/strings/en.json
@@ -215,6 +215,7 @@
"title": "Settings",
"description": "Change BlitzKit settings",
"dev_mode": "Development mode",
+ "auto_load_models": "Auto-load models",
"language": "Language"
},
@@ -458,6 +459,8 @@
},
"sandbox": {
+ "load_model": "Load model",
+
"poses": {
"hull_down": "Hull down",
"face_hug": "Face hug",
diff --git a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx
index 93d7a5e1a..f28050abc 100644
--- a/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx
+++ b/packages/website/src/components/Tankopedia/CharacteristicsSection/components/Characteristics/components/GunFlexibilityVisualizer/index.tsx
@@ -13,6 +13,7 @@ import { modelTransformEvent } from "../../../../../../../core/blitzkit/modelTra
import { Var } from "../../../../../../../core/radix/var";
import { useLocale } from "../../../../../../../hooks/useLocale";
import { Duel } from "../../../../../../../stores/duel";
+import { Tankopedia } from "../../../../../../../stores/tankopedia";
import type { MaybeSkeletonComponentProps } from "../../../../../../../types/maybeSkeletonComponentProps";
import { VisualizerCard } from "../VisualizerCard";
import { VisualizerCornerStat } from "../VisualizerCornerStat";
@@ -43,6 +44,7 @@ export function GunFlexibilityVisualizer({
const tank = Duel.use((state) => state.protagonist.tank);
const turret = Duel.use((state) => state.protagonist.turret);
const gun = Duel.use((state) => state.protagonist.gun);
+ const modelRequested = Tankopedia.use((state) => state.modelRequested);
const tankModel = modelDefinition.models[tank.id];
const turretModel = tankModel.turrets[turret.id];
@@ -193,7 +195,7 @@ export function GunFlexibilityVisualizer({
top="0"
left="0"
>
- {!skeleton && }
+ {!skeleton && modelRequested && }
state.revealed);
const disturbed = Tankopedia.use((state) => state.disturbed);
const highGraphics = TankopediaPersistent.use((state) => state.highGraphics);
+ const modelRequested = Tankopedia.use((state) => state.modelRequested);
const equalize = Duel.use((state) => state.equalize);
const equalizer = Duel.use((state) => state.antagonist.tank.equalizer);
@@ -283,7 +284,7 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
- {!skeleton && (
+ {!skeleton && modelRequested && (
diff --git a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/Title/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/Title/index.tsx
index 694d24f12..d31db7a1f 100644
--- a/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/Title/index.tsx
+++ b/packages/website/src/components/Tankopedia/HeroSection/components/TankSandbox/Title/index.tsx
@@ -1,11 +1,14 @@
-import { Flex, Heading } from "@radix-ui/themes";
+import { UpdateIcon } from "@radix-ui/react-icons";
+import { Button, Flex, Heading } from "@radix-ui/themes";
import { useLocale } from "../../../../../../hooks/useLocale";
import { Duel } from "../../../../../../stores/duel";
import { Tankopedia } from "../../../../../../stores/tankopedia";
+import type { MaybeSkeletonComponentProps } from "../../../../../../types/maybeSkeletonComponentProps";
import { Tracker } from "./components/Tracker";
-export function Title() {
- const { unwrap } = useLocale();
+export function Title({ skeleton }: MaybeSkeletonComponentProps) {
+ const { unwrap, strings } = useLocale();
+ const modelRequested = Tankopedia.use((state) => state.modelRequested);
const protagonist = Duel.use((state) => state.protagonist.tank);
const revealed = Tankopedia.use((state) => state.revealed);
const disturbed = Tankopedia.use((state) => state.disturbed);
@@ -21,6 +24,8 @@ export function Title() {
onPointerDown={(event) => {
event.preventDefault();
+ if (!modelRequested) return;
+
Tankopedia.mutate((draft) => {
draft.revealed = true;
});
@@ -60,7 +65,36 @@ export function Title() {
{name}
- {!revealed && }
+ {!skeleton && !revealed && modelRequested && (
+
+ )}
+
+ {!skeleton && !modelRequested && (
+
+
+
+ )}
);
}
diff --git a/packages/website/src/components/Tankopedia/HeroSection/index.tsx b/packages/website/src/components/Tankopedia/HeroSection/index.tsx
index 11f13d58e..51205fb49 100644
--- a/packages/website/src/components/Tankopedia/HeroSection/index.tsx
+++ b/packages/website/src/components/Tankopedia/HeroSection/index.tsx
@@ -1,6 +1,6 @@
import { Box, Flex } from "@radix-ui/themes";
import { times } from "lodash-es";
-import { useEffect, useMemo, useRef } from "react";
+import { Suspense, useEffect, useMemo, useRef } from "react";
import { api } from "../../../core/blitzkit/api";
import { defaultEqualizer } from "../../../core/blitzkit/tankToDuelMember";
import { useFullScreen } from "../../../hooks/useFullScreen";
@@ -20,6 +20,7 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
const canvas = useRef(null!);
const isFullScreen = useFullScreen();
const protagonist = Duel.use((state) => state.protagonist.tank);
+ const modelRequested = Tankopedia.use((state) => state.modelRequested);
const thicknessRange = useMemo(() => {
const entries = Object.values(tankDefinitions.tanks);
const filtered = entries.filter(
@@ -131,13 +132,15 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
top="0"
left="0"
>
- {!skeleton && (
-
+ {!skeleton && modelRequested && (
+
+
+
)}
-
+
state.developerMode, false);
+ const autoLoadModels = App.useDeferred(
+ (state) => state.autoLoadModels,
+ true,
+ );
const { strings } = useLocale();
return (
@@ -36,6 +40,19 @@ function Content({ locale }: LocaleAcceptorProps) {
/>
+
+ {strings.website.settings.auto_load_models}
+
+ App.mutate((draft) => {
+ draft.autoLoadModels = checked;
+ })
+ }
+ />
+
+
{strings.website.settings.language}
diff --git a/packages/website/src/stores/app/index.ts b/packages/website/src/stores/app/index.ts
index 6b15394f2..ba975056c 100644
--- a/packages/website/src/stores/app/index.ts
+++ b/packages/website/src/stores/app/index.ts
@@ -8,6 +8,7 @@ export interface WargamingLogin {
export interface App {
developerMode: boolean;
+ autoLoadModels: boolean;
policiesAgreementIndex: number;
logins: {
wargaming?: WargamingLogin;
@@ -17,6 +18,7 @@ export interface App {
export const App = new Varuna(
{
developerMode: false,
+ autoLoadModels: true,
policiesAgreementIndex: -1,
logins: {},
},
diff --git a/packages/website/src/stores/tankopedia.ts b/packages/website/src/stores/tankopedia.ts
index d2eb8a066..023ab0e87 100644
--- a/packages/website/src/stores/tankopedia.ts
+++ b/packages/website/src/stores/tankopedia.ts
@@ -9,6 +9,7 @@ import type { ArmorType } from "../components/Armor/components/SpacedArmorScene"
import type { ExternalModuleVariant } from "../components/Armor/components/SpacedArmorSceneComponent";
import type { XP_MULTIPLIERS } from "../components/Tankopedia/TechTreeSection";
import { api } from "../core/blitzkit/api";
+import { App } from "./app";
import { TankopediaDisplay } from "./tankopediaPersistent/constants";
export interface ShotLayerBase {
@@ -79,6 +80,7 @@ export enum TankopediaRelativeAgainst {
interface Tankopedia {
disturbed: boolean;
revealed: boolean;
+ modelRequested: boolean;
shot?: Shot;
skills: Record;
relativeAgainst: TankopediaRelativeAgainst;
@@ -110,6 +112,7 @@ const skillDefinitions = await api.skillDefinitions();
export const Tankopedia = new Varuna((model) => ({
disturbed: false,
revealed: false,
+ modelRequested: App.state.autoLoadModels,
relativeAgainst: TankopediaRelativeAgainst.Class,
editStatic: false,
skills: createDefaultSkills(skillDefinitions),