mirror of
https://github.com/tobspr/shapez.io.git
synced 2026-03-02 03:39:21 +00:00
Prepare standalone build
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
// background: #aaacb4 center center / cover !important;
|
||||
background: #bbc2cf center center / cover !important;
|
||||
|
||||
.settingsButton {
|
||||
.settingsButton,
|
||||
.exitAppButton {
|
||||
position: absolute;
|
||||
@include S(top, 30px);
|
||||
@include S(right, 30px);
|
||||
@@ -22,6 +23,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.exitAppButton {
|
||||
@include S(right, 100px);
|
||||
background-image: resolve("icons/main_menu_exit.png");
|
||||
}
|
||||
|
||||
.fullscreenBackgroundVideo {
|
||||
// display: none !important;
|
||||
z-index: -1;
|
||||
|
||||
23
src/html/index.standalone.html
Normal file
23
src/html/index.standalone.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>shapez.io Standalone</title>
|
||||
|
||||
<!-- mobile stuff -->
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="msapplication-tap-highlight" content="no" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no, viewport-fit=cover"
|
||||
/>
|
||||
<meta name="HandheldFriendly" content="true" />
|
||||
<meta name="MobileOptimized" content="320" />
|
||||
<meta name="theme-color" content="#393747" />
|
||||
|
||||
<!-- misc -->
|
||||
<meta http-equiv="Cache-Control" content="private, max-age=0, no-store, no-cache, must-revalidate" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body oncontextmenu="return false" style="background: #393747;"></body>
|
||||
</html>
|
||||
@@ -34,6 +34,8 @@ import { StorageImplBrowserIndexedDB } from "./platform/browser/storage_indexed_
|
||||
import { SettingsState } from "./states/settings";
|
||||
import { KeybindingsState } from "./states/keybindings";
|
||||
import { AboutState } from "./states/about";
|
||||
import { PlatformWrapperImplElectron } from "./platform/electron/wrapper";
|
||||
import { StorageImplElectron } from "./platform/electron/storage";
|
||||
|
||||
const logger = createLogger("application");
|
||||
|
||||
@@ -124,13 +126,22 @@ export class Application {
|
||||
// Start with empty ad provider
|
||||
this.adProvider = new NoAdProvider(this);
|
||||
|
||||
if (window.indexedDB) {
|
||||
this.storage = new StorageImplBrowserIndexedDB(this);
|
||||
if (G_IS_STANDALONE) {
|
||||
this.storage = new StorageImplElectron(this);
|
||||
} else {
|
||||
this.storage = new StorageImplBrowser(this);
|
||||
if (window.indexedDB) {
|
||||
this.storage = new StorageImplBrowserIndexedDB(this);
|
||||
} else {
|
||||
this.storage = new StorageImplBrowser(this);
|
||||
}
|
||||
}
|
||||
this.sound = new SoundImplBrowser(this);
|
||||
this.platformWrapper = new PlatformWrapperImplBrowser(this);
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
this.platformWrapper = new PlatformWrapperImplElectron(this);
|
||||
} else {
|
||||
this.platformWrapper = new PlatformWrapperImplBrowser(this);
|
||||
}
|
||||
this.analytics = new GoogleAnalyticsImpl(this);
|
||||
|
||||
if (queryParamOptions.betaMode) {
|
||||
|
||||
@@ -83,8 +83,8 @@ export const globalConfig = {
|
||||
|
||||
debug: {
|
||||
/* dev:start */
|
||||
fastGameEnter: true,
|
||||
noArtificialDelays: true,
|
||||
// fastGameEnter: true,
|
||||
// noArtificialDelays: true,
|
||||
// disableSavegameWrite: true,
|
||||
// showEntityBounds: true,
|
||||
// showAcceptorEjectors: true,
|
||||
|
||||
83
src/js/platform/electron/storage.js
Normal file
83
src/js/platform/electron/storage.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import { StorageInterface } from "../storage";
|
||||
import { getIPCRenderer } from "../../core/utils";
|
||||
import { createLogger } from "../../core/logging";
|
||||
|
||||
const logger = createLogger("electron-storage");
|
||||
|
||||
export class StorageImplElectron extends StorageInterface {
|
||||
constructor(app) {
|
||||
super(app);
|
||||
|
||||
/** @type {Object.<number, {resolve:Function, reject: Function}>} */
|
||||
this.jobs = {};
|
||||
this.jobId = 0;
|
||||
|
||||
getIPCRenderer().on("fs-response", (event, arg) => {
|
||||
const id = arg.id;
|
||||
if (!this.jobs[id]) {
|
||||
logger.warn("Got unhandled FS response, job not known:", id);
|
||||
return;
|
||||
}
|
||||
const { resolve, reject } = this.jobs[id];
|
||||
if (arg.result.success) {
|
||||
resolve(arg.result.data);
|
||||
} else {
|
||||
reject(arg.result.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initialize() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
writeFileAsync(filename, contents) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// ipcMain
|
||||
const jobId = ++this.jobId;
|
||||
this.jobs[jobId] = { resolve, reject };
|
||||
|
||||
getIPCRenderer().send("fs-job", {
|
||||
type: "write",
|
||||
filename,
|
||||
contents,
|
||||
id: jobId,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
writeFileSyncIfSupported(filename, contents) {
|
||||
return getIPCRenderer().sendSync("fs-sync-job", {
|
||||
type: "write",
|
||||
filename,
|
||||
contents,
|
||||
});
|
||||
}
|
||||
|
||||
readFileAsync(filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// ipcMain
|
||||
const jobId = ++this.jobId;
|
||||
this.jobs[jobId] = { resolve, reject };
|
||||
|
||||
getIPCRenderer().send("fs-job", {
|
||||
type: "read",
|
||||
filename,
|
||||
id: jobId,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
deleteFileAsync(filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// ipcMain
|
||||
const jobId = ++this.jobId;
|
||||
this.jobs[jobId] = { resolve, reject };
|
||||
getIPCRenderer().send("fs-job", {
|
||||
type: "delete",
|
||||
filename,
|
||||
id: jobId,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
50
src/js/platform/electron/wrapper.js
Normal file
50
src/js/platform/electron/wrapper.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import { PlatformWrapperImplBrowser } from "../browser/wrapper";
|
||||
import { getIPCRenderer } from "../../core/utils";
|
||||
import { createLogger } from "../../core/logging";
|
||||
|
||||
const logger = createLogger("electron-wrapper");
|
||||
|
||||
export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
||||
getId() {
|
||||
return "electron";
|
||||
}
|
||||
|
||||
getSupportsRestart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
openExternalLink(url) {
|
||||
logger.log(this, "Opening external:", url);
|
||||
window.open(url, "about:blank");
|
||||
}
|
||||
|
||||
getSupportsAds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
performRestart() {
|
||||
logger.log(this, "Performing restart");
|
||||
window.location.reload(true);
|
||||
}
|
||||
|
||||
initializeAdProvider() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
getSupportsFullscreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
setFullscreen(flag) {
|
||||
getIPCRenderer().send("set-fullscreen", flag);
|
||||
}
|
||||
|
||||
getSupportsAppExit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
exitApp() {
|
||||
logger.log(this, "Sending app exit signal");
|
||||
getIPCRenderer().send("exit-app");
|
||||
}
|
||||
}
|
||||
@@ -33,10 +33,22 @@ export class MainMenuState extends GameState {
|
||||
return `
|
||||
|
||||
<button class="settingsButton"></button>
|
||||
|
||||
${
|
||||
G_IS_STANDALONE
|
||||
? `
|
||||
<button class="exitAppButton"></button>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
<video autoplay muted loop class="fullscreenBackgroundVideo">
|
||||
${
|
||||
G_IS_STANDALONE
|
||||
? ""
|
||||
: `<video autoplay muted loop class="fullscreenBackgroundVideo">
|
||||
<source src="${cachebust("res/bg_render.webm")}" type="video/webm">
|
||||
</video>
|
||||
</video>`
|
||||
}
|
||||
|
||||
|
||||
<div class="logo">
|
||||
@@ -184,6 +196,11 @@ export class MainMenuState extends GameState {
|
||||
}
|
||||
|
||||
this.trackClicks(qs(".settingsButton"), this.onSettingsButtonClicked);
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
this.trackClicks(qs(".exitAppButton"), this.onExitAppButtonClicked);
|
||||
}
|
||||
|
||||
this.renderSavegames();
|
||||
|
||||
const steamLinks = this.htmlElement.querySelectorAll(".steamLink");
|
||||
@@ -199,6 +216,10 @@ export class MainMenuState extends GameState {
|
||||
return false;
|
||||
}
|
||||
|
||||
onExitAppButtonClicked() {
|
||||
this.app.platformWrapper.exitApp();
|
||||
}
|
||||
|
||||
renderSavegames() {
|
||||
const oldContainer = this.htmlElement.querySelector(".mainContainer .savegames");
|
||||
if (oldContainer) {
|
||||
|
||||
@@ -100,6 +100,13 @@ export class PreloadState extends GameState {
|
||||
return this.app.settings.initialize();
|
||||
})
|
||||
|
||||
.then(() => {
|
||||
// Initialize fullscreen
|
||||
if (this.app.platformWrapper.getSupportsFullscreen()) {
|
||||
this.app.platformWrapper.setFullscreen(this.app.settings.getIsFullScreen());
|
||||
}
|
||||
})
|
||||
|
||||
.then(() => this.setStatus("Initializing sounds"))
|
||||
.then(() => {
|
||||
// Notice: We don't await the sounds loading itself
|
||||
|
||||
Reference in New Issue
Block a user