Allow downloading savegames

pull/33/head
tobspr 4 years ago
parent 2c9867c837
commit a2b1342f55

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

@ -85,21 +85,22 @@
.savegames {
@include S(max-height, 92px);
overflow-y: auto;
@include S(width, 200px);
@include S(width, 250px);
pointer-events: all;
@include S(padding-right, 5px);
display: grid;
grid-auto-flow: row;
@include S(grid-gap, 5px);
@include S(margin-top, 10px);
.savegame {
background: #eee;
@include BorderRadius(4px);
@include S(padding, 5px);
display: grid;
grid-template-columns: 1fr auto;
grid-template-columns: 1fr auto auto;
grid-template-rows: auto auto;
@include S(grid-column-gap, 15px);
@include S(grid-column-gap, 5px);
.internalId {
grid-column: 1 / 2;
@ -114,8 +115,9 @@
@include PlainText;
}
button.resumeGame {
grid-column: 2 / 3;
button.resumeGame,
button.downloadGame {
grid-column: 3 / 4;
grid-row: 1 / 3;
@include S(width, 30px);
@include S(height, 30px);
@ -123,6 +125,15 @@
align-self: center;
background: #44484a uiResource("icons/play.png") center center / 40% no-repeat;
}
button.downloadGame {
grid-column: 2 / 3;
background-image: uiResource("icons/download.png");
@include S(width, 15px);
@include S(height, 15px);
align-self: end;
background-size: 60%;
}
}
}
}

@ -79,6 +79,16 @@ export class ReadWriteProxy {
return this.currentData;
}
/**
*
* @param {object} obj
*/
static serializeObject(obj) {
const jsonString = JSON_stringify(compressObject(obj));
const checksum = sha1(jsonString + salt);
return compressionPrefix + compressX64(checksum + jsonString);
}
/**
* Writes the data asychronously, fails if verify() fails
* @returns {Promise<string>}

@ -859,3 +859,20 @@ export function formatSecondsToTimeAgo(secs) {
return days + " days ago";
}
}
/**
* Generates a file download
* @param {string} filename
* @param {string} text
*/
export function generateFileDownload(filename, text) {
var element = document.createElement("a");
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}

@ -1,7 +1,8 @@
import { GameState } from "../core/game_state";
import { cachebust } from "../core/cachebust";
import { globalConfig } from "../core/config";
import { makeDiv, formatSecondsToTimeAgo } from "../core/utils";
import { makeDiv, formatSecondsToTimeAgo, generateFileDownload } from "../core/utils";
import { ReadWriteProxy } from "../core/read_write_proxy";
export class MainMenuState extends GameState {
constructor() {
@ -90,10 +91,15 @@ export class MainMenuState extends GameState {
formatSecondsToTimeAgo((new Date().getTime() - games[i].lastUpdate) / 1000.0)
);
const downloadButton = document.createElement("button");
downloadButton.classList.add("styledButton", "downloadGame");
elem.appendChild(downloadButton);
const resumeBtn = document.createElement("button");
resumeBtn.classList.add("styledButton", "resumeGame");
elem.appendChild(resumeBtn);
this.trackClicks(downloadButton, () => this.downloadGame(games[i]));
this.trackClicks(resumeBtn, () => this.resumeGame(games[i]));
}
}
@ -111,6 +117,17 @@ export class MainMenuState extends GameState {
});
}
/**
* @param {object} game
*/
downloadGame(game) {
const savegame = this.app.savegameMgr.getSavegameById(game.internalId);
savegame.readAsync().then(() => {
const data = ReadWriteProxy.serializeObject(savegame.currentData);
generateFileDownload(savegame.filename, data);
});
}
onPlayButtonClicked() {
const savegame = this.app.savegameMgr.createNewSavegame();

Loading…
Cancel
Save