diff --git a/src/system/game-data.ts b/src/system/game-data.ts index fff09f83f..e9411edc9 100644 --- a/src/system/game-data.ts +++ b/src/system/game-data.ts @@ -278,17 +278,22 @@ export class GameData { Utils.apiPost(`savedata/update?datatype=${GameDataType.SYSTEM}`, systemData, undefined, true) .then(response => response.text()) .then(error => { - this.scene.ui.savingIcon.hide(); if (error) { + console.error(error); if (error.startsWith('client version out of date')) { + this.scene.ui.savingIcon.hide(); this.scene.clearPhaseQueue(); this.scene.unshiftPhase(new OutdatedPhase(this.scene)); + return resolve(false); } else if (error.startsWith('session out of date')) { + this.scene.ui.savingIcon.hide(); this.scene.clearPhaseQueue(); this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); + return resolve(false); } - console.error(error); - return resolve(false); + console.log(`Retrying...`); + this.scene.ui.savingIcon.retry(); + return this.saveSystem().then(resolve); } resolve(true); }); @@ -564,12 +569,14 @@ export class GameData { .then(response => response.text()) .then(error => { if (error) { + console.error(error); if (error.startsWith('session out of date')) { this.scene.clearPhaseQueue(); this.scene.unshiftPhase(new ReloadSessionPhase(this.scene)); + return resolve(false); } - console.error(error); - return resolve(false); + console.log(`Retrying...`); + return this.saveSession(this.scene, skipVerification).then(resolve); } console.debug('Session data saved'); resolve(true); diff --git a/src/ui/saving-icon-handler.ts b/src/ui/saving-icon-handler.ts index 71d9a11fb..b2d27f694 100644 --- a/src/ui/saving-icon-handler.ts +++ b/src/ui/saving-icon-handler.ts @@ -13,7 +13,7 @@ export default class SavingIconHandler extends Phaser.GameObjects.Container { setup(): void { this.icon = this.scene.add.sprite(0, 0, 'saving_icon'); - this.icon.setOrigin(1, 1); + this.icon.setOrigin(0.5, 0.5); this.add(this.icon); @@ -50,6 +50,24 @@ export default class SavingIconHandler extends Phaser.GameObjects.Container { this.shown = true; } + retry(): void { + this.setAlpha(1); + this.setVisible(true); + this.shown = true; + + this.animActive = true; + + this.scene.tweens.add({ + targets: this, + rotation: 360, + repeat: Infinity, + duration: Utils.fixedInt(60000), + ease: 'Linear' + }); + + this.setVisible(true); + } + hide(): void { this.shown = false; diff --git a/src/utils.ts b/src/utils.ts index 822f02f05..9019dcee3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -268,9 +268,24 @@ export function apiPost(path: string, data?: any, contentType: string = 'applica if (sId) headers['Authorization'] = sId; } - fetch(`${apiUrl}/${path}`, { method: 'POST', headers: headers, body: data }) - .then(response => resolve(response)) - .catch(err => reject(err)); + + const controller = new AbortController(); + const signal = controller.signal; + + const timeoutId = setTimeout(() => { + controller.abort(); + reject(new Error('Request timed out')); + }, 8000); + + fetch(`${apiUrl}/${path}`, { method: 'POST', headers: headers, body: data, signal }) + .then(response => { + clearTimeout(timeoutId); + resolve(response); + }) + .catch(err => { + clearTimeout(timeoutId); + reject(err); + }); }); }