1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Add ability to import savegames, add game menu, multiple smaller improvements

This commit is contained in:
tobspr
2020-05-16 17:57:25 +02:00
parent c1d720ca52
commit 224bc6c7e5
31 changed files with 1422 additions and 47 deletions

View File

@@ -20,6 +20,7 @@ export class StorageImplBrowser extends StorageInterface {
}
initialize() {
logger.error("Using localStorage, please update to a newer browser");
return new Promise((resolve, reject) => {
// Check for local storage availability in general
if (!window.localStorage) {

View File

@@ -0,0 +1,155 @@
import { FILE_NOT_FOUND, StorageInterface } from "../storage";
import { createLogger } from "../../core/logging";
const logger = createLogger("storage/browserIDB");
const LOCAL_STORAGE_UNAVAILABLE = "local-storage-unavailable";
const LOCAL_STORAGE_NO_WRITE_PERMISSION = "local-storage-no-write-permission";
let randomDelay = () => 0;
if (G_IS_DEV) {
// Random delay for testing
// randomDelay = () => 500;
}
export class StorageImplBrowserIndexedDB extends StorageInterface {
constructor(app) {
super(app);
this.currentBusyFilename = false;
/** @type {IDBDatabase} */
this.database = null;
}
initialize() {
logger.log("Using indexed DB storage");
return new Promise((resolve, reject) => {
const request = window.indexedDB.open("app_storage", 10);
request.onerror = event => {
logger.error("IDB error:", event);
reject("Indexed DB access error");
};
request.onsuccess = event => resolve(event.target.result);
request.onupgradeneeded = /** @type {IDBVersionChangeEvent} */ event => {
/** @type {IDBDatabase} */
const database = event.target.result;
const objectStore = database.createObjectStore("files", {
keyPath: "filename",
});
objectStore.createIndex("filename", "filename", { unique: true });
objectStore.transaction.onerror = event => {
logger.error("IDB transaction error:", event);
reject("Indexed DB transaction error during migration, check console output.");
};
objectStore.transaction.oncomplete = event => {
logger.log("Object store completely initialized");
resolve(database);
};
};
}).then(database => {
this.database = database;
});
}
writeFileAsync(filename, contents) {
if (this.currentBusyFilename === filename) {
logger.warn("Attempt to write", filename, "while write process is not finished!");
}
if (!this.database) {
return Promise.reject("Storage not ready");
}
this.currentBusyFilename = filename;
const transaction = this.database.transaction(["files"], "readwrite");
return new Promise((resolve, reject) => {
transaction.oncomplete = () => {
this.currentBusyFilename = null;
resolve();
};
transaction.onerror = error => {
this.currentBusyFilename = null;
logger.error("Error while writing", filename, ":", error);
reject(error);
};
const store = transaction.objectStore("files");
store.put({
filename,
contents,
});
});
}
writeFileSyncIfSupported(filename, contents) {
// Not supported
this.writeFileAsync(filename, contents);
return true;
}
readFileAsync(filename) {
if (!this.database) {
return Promise.reject("Storage not ready");
}
this.currentBusyFilename = filename;
const transaction = this.database.transaction(["files"], "readonly");
return new Promise((resolve, reject) => {
const store = transaction.objectStore("files");
const request = store.get(filename);
request.onsuccess = event => {
this.currentBusyFilename = null;
if (!request.result) {
reject(FILE_NOT_FOUND);
return;
}
resolve(request.result.contents);
};
request.onerror = error => {
this.currentBusyFilename = null;
logger.error("Error while reading", filename, ":", error);
reject(error);
};
});
}
deleteFileAsync(filename) {
if (this.currentBusyFilename === filename) {
logger.warn("Attempt to delete", filename, "while write progres on it is ongoing!");
}
if (!this.database) {
return Promise.reject("Storage not ready");
}
this.currentBusyFilename = filename;
const transaction = this.database.transaction(["files"], "readwrite");
return new Promise((resolve, reject) => {
transaction.oncomplete = () => {
this.currentBusyFilename = null;
resolve();
};
transaction.onerror = error => {
this.currentBusyFilename = null;
logger.error("Error while deleting", filename, ":", error);
reject(error);
};
const store = transaction.objectStore("files");
store.delete(filename);
});
}
}