Skip to content
Closed
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
2 changes: 2 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_DOMAIN=api.openfront.io
VITE_WS_HOST=openfront.io
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ TODO.txt
resources/images/.DS_Store
resources/.DS_Store
.env*
!.env.production
.DS_Store
.clinic/
NOTES.md
Expand Down
6 changes: 6 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@
inline
class="hidden w-full h-full page-content relative z-50"
></help-modal>
<onboarding-modal
id="page-onboarding"
inline
class="hidden w-full h-full page-content relative z-50"
></onboarding-modal>
<tour-overlay id="tour-overlay"></tour-overlay>
<language-modal
id="page-language"
inline
Expand Down
7 changes: 7 additions & 0 deletions src/client/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ export async function createCheckoutSession(
}

export function getApiBase() {
const viteApiDomain = (
import.meta as unknown as { env?: Record<string, string> }
).env?.VITE_API_DOMAIN;
if (viteApiDomain) {
return `https://${viteApiDomain}`;
}
Comment on lines +173 to +178
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Hardcoded https:// may break local development.

When VITE_API_DOMAIN is set to a localhost address (e.g., localhost:8787), the code returns https://localhost:8787. Local dev servers typically run on http://, so this would fail to connect. The existing localStorage fallback at line 187 can include the protocol in the stored value (http://localhost:8787), but this new override cannot.

Consider allowing the protocol to be specified or defaulting to http:// when the domain starts with localhost:

🔧 Suggested fix to support http for localhost
 export function getApiBase() {
   const viteApiDomain = (
     import.meta as unknown as { env?: Record<string, string> }
   ).env?.VITE_API_DOMAIN;
   if (viteApiDomain) {
-    return `https://${viteApiDomain}`;
+    const protocol = viteApiDomain.startsWith('localhost') ? 'http' : 'https';
+    return `${protocol}://${viteApiDomain}`;
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const viteApiDomain = (
import.meta as unknown as { env?: Record<string, string> }
).env?.VITE_API_DOMAIN;
if (viteApiDomain) {
return `https://${viteApiDomain}`;
}
const viteApiDomain = (
import.meta as unknown as { env?: Record<string, string> }
).env?.VITE_API_DOMAIN;
if (viteApiDomain) {
const protocol = viteApiDomain.startsWith('localhost') ? 'http' : 'https';
return `${protocol}://${viteApiDomain}`;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/client/Api.ts` around lines 173 - 178, The code that builds the API base
URL using viteApiDomain (from (import.meta as unknown as { env?:
Record<string,string> }).env?.VITE_API_DOMAIN) always prefixes with "https://"
which breaks local dev; change the logic in Api.ts so that if VITE_API_DOMAIN
already includes a protocol (starts with "http://" or "https://") you return it
as-is, otherwise if the domain looks like localhost (e.g., starts with
"localhost" or contains "localhost:") default to "http://" + viteApiDomain, and
for all other hosts default to "https://" + viteApiDomain; ensure you update the
return branch that currently does return `https://${viteApiDomain}` accordingly.


const domainname = getAudience();

if (domainname === "localhost") {
Expand Down
4 changes: 4 additions & 0 deletions src/client/ClientGameRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ export class ClientGameRunner {
this.eventBus.emit(new SendHashEvent(hu.tick, hu.hash));
});
this.gameView.update(gu);
(window as unknown as Record<string, unknown>).__tourGameView =
this.gameView;
this.renderer.tick();

// Emit tick metrics event for performance overlay
Expand Down Expand Up @@ -611,6 +613,7 @@ export class ClientGameRunner {
!this.gameView.config().isRandomSpawn()
) {
this.eventBus.emit(new SendSpawnIntentEvent(tile));
window.dispatchEvent(new CustomEvent("tour:spawn-clicked"));
return;
}
if (this.gameView.inSpawnPhase()) {
Expand Down Expand Up @@ -850,6 +853,7 @@ export class ClientGameRunner {
this.eventBus.emit(
new SendAllianceRequestIntentEvent(myPlayer, recipient),
);
window.dispatchEvent(new CustomEvent("tour:alliance-sent"));
}
});
}
Expand Down
5 changes: 4 additions & 1 deletion src/client/LobbySocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export class PublicLobbySocket {
}

const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
const wsUrl = `${protocol}//${window.location.host}${this.workerPath}/lobbies`;
const wsHost =
(import.meta as unknown as { env?: Record<string, string> }).env
?.VITE_WS_HOST ?? window.location.host;
const wsUrl = `${protocol}//${wsHost}${this.workerPath}/lobbies`;

this.ws = new WebSocket(wsUrl);
this.wsAttemptCounted = false;
Expand Down
17 changes: 17 additions & 0 deletions src/client/Main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
import { GameStartingModal } from "./GameStartingModal";
import "./GoogleAdElement";
import { HelpModal } from "./HelpModal";
import { hasSeenOnboarding, OnboardingModal } from "./OnboardingModal";

Check failure on line 37 in src/client/Main.ts

View workflow job for this annotation

GitHub Actions / 🔍 ESLint

'OnboardingModal' is defined but never used. (@typescript-eslint/no-unused-vars)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use side-effect-only import for custom element registration.

The OnboardingModal class is imported but never used. The import is only needed to register the onboarding-modal custom element via the @customElement decorator.

♻️ Proposed fix
-import { hasSeenOnboarding, OnboardingModal } from "./OnboardingModal";
+import { hasSeenOnboarding } from "./OnboardingModal";
+import "./OnboardingModal";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { hasSeenOnboarding, OnboardingModal } from "./OnboardingModal";
import { hasSeenOnboarding } from "./OnboardingModal";
import "./OnboardingModal";
🧰 Tools
🪛 ESLint

[error] 37-37: 'OnboardingModal' is defined but never used.

(@typescript-eslint/no-unused-vars)

🪛 GitHub Check: 🔍 ESLint

[failure] 37-37:
'OnboardingModal' is defined but never used. (@typescript-eslint/no-unused-vars)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/client/Main.ts` at line 37, The import currently pulls in OnboardingModal
but never uses it; change the import to a side-effect-only import so the
`@customElement` registration in OnboardingModal still runs. Replace the named
import line that references OnboardingModal (while keeping hasSeenOnboarding if
still needed) with a side-effect import for "./OnboardingModal" and only import
hasSeenOnboarding as a named import when used; this ensures the onboarding-modal
custom element is registered without unused symbols.

import "./TourOverlay";
import { getTourOverlay } from "./TourOverlay";

Check failure on line 39 in src/client/Main.ts

View workflow job for this annotation

GitHub Actions / 🔍 ESLint

'getTourOverlay' is defined but never used. (@typescript-eslint/no-unused-vars)
import "./HomepagePromos";
import { HostLobbyModal as HostPrivateLobbyModal } from "./HostLobbyModal";
import { JoinLobbyModal } from "./JoinLobbyModal";
Expand Down Expand Up @@ -1019,6 +1022,20 @@
new Client().initialize();
initNavigation();

// Auto-open onboarding for first-time visitors
if (!hasSeenOnboarding()) {
setTimeout(() => {
window.showPage?.("page-onboarding");
}, 600);
}

// Wire up the onboarding nav button (desktop + mobile)
document.querySelectorAll("[data-action='open-onboarding']").forEach((btn) => {
btn.addEventListener("click", () => {
window.showPage?.("page-onboarding");
});
});

// Hide elements immediately
hideCrazyGamesElements();

Expand Down
Loading
Loading