From ef3d492b41a989c7c384a2a3c33e5539641761f8 Mon Sep 17 00:00:00 2001 From: Jaysc Date: Wed, 10 Jun 2020 18:21:24 +0100 Subject: [PATCH 1/2] Added continue button --- src/css/states/main_menu.scss | 16 ++++++++++++++++ src/js/states/main_menu.js | 27 +++++++++++++++++++++++++++ translations/base-en.yaml | 1 + 3 files changed, 44 insertions(+) diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index ff6ee607..a6ba4473 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -244,6 +244,22 @@ } } + .continueButton { + @include SuperHeading; + @include S(min-width, 130px); + @include S(padding, 15px, 20px); + @include S(margin-top, 15px); + letter-spacing: 0.3em !important; + + font-weight: bold; + color: #fff; + background-color: $colorGreenBright; + transition: transform 0.12s ease-in-out; + &:hover { + transform: scale(1.02); + } + } + .importButton { @include S(margin-top, 15px); } diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index 101bbcd6..3f137b5c 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -3,6 +3,7 @@ import { cachebust } from "../core/cachebust"; import { globalConfig, IS_DEBUG, IS_DEMO, THIRDPARTY_URLS } from "../core/config"; import { makeDiv, + makeButton, formatSecondsToTimeAgo, generateFileDownload, waitNextFrame, @@ -330,9 +331,17 @@ export class MainMenuState extends GameState { const oldContainer = this.htmlElement.querySelector(".mainContainer .savegames"); if (oldContainer) { oldContainer.remove(); + this.htmlElement.querySelector(".mainContainer .continueButton").remove(); } const games = this.app.savegameMgr.getSavegamesMetaData(); if (games.length > 0) { + const continueButton = makeButton( + this.htmlElement.querySelector(".mainContainer"), + ["continueButton", "styledButton"], + T.mainMenu.continue + ); + this.trackClicks(continueButton, this.onContinueButtonClicked); + const parent = makeDiv(this.htmlElement.querySelector(".mainContainer"), null, ["savegames"]); for (let i = 0; i < games.length; ++i) { @@ -463,6 +472,24 @@ export class MainMenuState extends GameState { }); } + onContinueButtonClicked() { + let latestLastUpdate = 0; + let latestInternalId; + this.app.savegameMgr.currentData.savegames.forEach(saveGame => { + if (saveGame.lastUpdate > latestLastUpdate) { + latestLastUpdate = saveGame.lastUpdate; + latestInternalId = saveGame.internalId; + } + }); + + const savegame = this.app.savegameMgr.getSavegameById(latestInternalId); + savegame.readAsync().then(() => { + this.moveToState("InGameState", { + savegame, + }); + }); + } + onLeave() { this.dialogs.cleanup(); } diff --git a/translations/base-en.yaml b/translations/base-en.yaml index ab054e32..0a6470b2 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -118,6 +118,7 @@ demoBanners: mainMenu: play: Play + continue: Continue changelog: Changelog importSavegame: Import openSourceHint: This game is open source! From f4d1e5447d59f7c81e9ed4432a2c7c3831366c30 Mon Sep 17 00:00:00 2001 From: Jaysc Date: Thu, 11 Jun 2020 15:17:50 +0100 Subject: [PATCH 2/2] Reordered continue and added new game button --- src/css/states/main_menu.scss | 5 +++ src/js/core/utils.js | 66 +++++++++++++++++++++++++----- src/js/states/main_menu.js | 75 ++++++++++++++++++++++++++--------- translations/base-en.yaml | 1 + 4 files changed, 120 insertions(+), 27 deletions(-) diff --git a/src/css/states/main_menu.scss b/src/css/states/main_menu.scss index a6ba4473..6c7a820f 100644 --- a/src/css/states/main_menu.scss +++ b/src/css/states/main_menu.scss @@ -264,6 +264,11 @@ @include S(margin-top, 15px); } + .newGameButton { + @include S(margin-top, 15px); + @include S(margin-left, 15px); + } + .savegames { @include S(max-height, 105px); overflow-y: auto; diff --git a/src/js/core/utils.js b/src/js/core/utils.js index e50b71c8..3efae622 100644 --- a/src/js/core/utils.js +++ b/src/js/core/utils.js @@ -628,13 +628,12 @@ export function measure(name, target) { } /** - * Helper method to create a new div - * @param {Element} parent + * Helper method to create a new div element * @param {string=} id * @param {Array=} classes * @param {string=} innerHTML */ -export function makeDiv(parent, id = null, classes = [], innerHTML = "") { +export function makeDivElement(id = null, classes = [], innerHTML = "") { const div = document.createElement("div"); if (id) { div.id = id; @@ -643,10 +642,51 @@ export function makeDiv(parent, id = null, classes = [], innerHTML = "") { div.classList.add(classes[i]); } div.innerHTML = innerHTML; + return div; +} + +/** + * Helper method to create a new div + * @param {Element} parent + * @param {string=} id + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeDiv(parent, id = null, classes = [], innerHTML = "") { + const div = makeDivElement(id, classes, innerHTML); parent.appendChild(div); return div; } +/** + * Helper method to create a new div and place before reference Node + * @param {Element} parent + * @param {Element} referenceNode + * @param {string=} id + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeDivBefore(parent, referenceNode, id = null, classes = [], innerHTML = "") { + const div = makeDivElement(id, classes, innerHTML); + parent.insertBefore(div, referenceNode); + return div; +} + +/** + * Helper method to create a new button element + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeButtonElement(classes = [], innerHTML = "") { + const element = document.createElement("button"); + for (let i = 0; i < classes.length; ++i) { + element.classList.add(classes[i]); + } + element.classList.add("styledButton"); + element.innerHTML = innerHTML; + return element; +} + /** * Helper method to create a new button * @param {Element} parent @@ -654,16 +694,24 @@ export function makeDiv(parent, id = null, classes = [], innerHTML = "") { * @param {string=} innerHTML */ export function makeButton(parent, classes = [], innerHTML = "") { - const element = document.createElement("button"); - for (let i = 0; i < classes.length; ++i) { - element.classList.add(classes[i]); - } - element.classList.add("styledButton"); - element.innerHTML = innerHTML; + const element = makeButtonElement(classes, innerHTML); parent.appendChild(element); return element; } +/** + * Helper method to create a new button and place before reference Node + * @param {Element} parent + * @param {Element} referenceNode + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeButtonBefore(parent, referenceNode, classes = [], innerHTML = "") { + const element = makeButtonElement(classes, innerHTML); + parent.insertBefore(element, referenceNode); + return element; +} + /** * Removes all children of the given element * @param {Element} elem diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index 3f137b5c..4b76aac7 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -3,11 +3,12 @@ import { cachebust } from "../core/cachebust"; import { globalConfig, IS_DEBUG, IS_DEMO, THIRDPARTY_URLS } from "../core/config"; import { makeDiv, - makeButton, + makeButtonElement, formatSecondsToTimeAgo, generateFileDownload, waitNextFrame, isSupportedBrowser, + makeButton, } from "../core/utils"; import { ReadWriteProxy } from "../core/read_write_proxy"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; @@ -86,8 +87,6 @@ export class MainMenuState extends GameState { ? "" : `
${T.mainMenu.browserWarning}
` } - - @@ -203,8 +202,6 @@ export class MainMenuState extends GameState { } const qs = this.htmlElement.querySelector.bind(this.htmlElement); - this.trackClicks(qs(".mainContainer .playButton"), this.onPlayButtonClicked); - this.trackClicks(qs(".mainContainer .importButton"), this.requestImportSavegame); if (G_IS_DEV && globalConfig.debug.fastGameEnter) { const games = this.app.savegameMgr.getSavegamesMetaData(); @@ -240,6 +237,7 @@ export class MainMenuState extends GameState { this.trackClicks(qs(".exitAppButton"), this.onExitAppButtonClicked); } + this.renderMainMenu(); this.renderSavegames(); const steamLink = this.htmlElement.querySelector(".steamLink"); @@ -269,6 +267,50 @@ export class MainMenuState extends GameState { ); } + renderMainMenu() { + const importButtonElement = makeButtonElement( + ["importButton", "styledButton"], + T.mainMenu.importSavegame + ); + this.trackClicks(importButtonElement, this.requestImportSavegame); + + if (this.savedGames.length > 0) { + const continueButton = makeButton( + this.htmlElement.querySelector(".mainContainer"), + ["continueButton", "styledButton"], + T.mainMenu.continue + ); + this.trackClicks(continueButton, this.onContinueButtonClicked); + + const outerDiv = makeDiv(this.htmlElement.querySelector(".mainContainer"), null, ["outer"], null); + outerDiv.appendChild(importButtonElement); + const newGameButton = makeButton( + this.htmlElement.querySelector(".mainContainer .outer"), + ["newGameButton", "styledButton"], + T.mainMenu.newGame + ); + this.trackClicks(newGameButton, this.onPlayButtonClicked); + + const oldPlayButton = this.htmlElement.querySelector(".mainContainer .playButton"); + if (oldPlayButton) oldPlayButton.remove(); + } else { + const playBtn = makeButton( + this.htmlElement.querySelector(".mainContainer"), + ["playButton", "styledButton"], + T.mainMenu.play + ); + this.trackClicks(playBtn, this.onPlayButtonClicked); + + this.htmlElement.querySelector(".mainContainer").appendChild(importButtonElement); + + const outerDiv = this.htmlElement.querySelector(".mainContainer .outer"); + if (outerDiv) { + outerDiv.remove(); + this.htmlElement.querySelector(".mainContainer .continueButton").remove(); + } + } + } + onSteamLinkClicked() { this.app.analytics.trackUiClick("main_menu_steam_link_2"); this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.standaloneStorePage); @@ -327,21 +369,17 @@ export class MainMenuState extends GameState { }, this); } + get savedGames() { + return this.app.savegameMgr.getSavegamesMetaData(); + } + renderSavegames() { const oldContainer = this.htmlElement.querySelector(".mainContainer .savegames"); if (oldContainer) { oldContainer.remove(); - this.htmlElement.querySelector(".mainContainer .continueButton").remove(); } - const games = this.app.savegameMgr.getSavegamesMetaData(); + const games = this.savedGames; if (games.length > 0) { - const continueButton = makeButton( - this.htmlElement.querySelector(".mainContainer"), - ["continueButton", "styledButton"], - T.mainMenu.continue - ); - this.trackClicks(continueButton, this.onContinueButtonClicked); - const parent = makeDiv(this.htmlElement.querySelector(".mainContainer"), null, ["savegames"]); for (let i = 0; i < games.length; ++i) { @@ -371,13 +409,13 @@ export class MainMenuState extends GameState { downloadButton.classList.add("styledButton", "downloadGame"); elem.appendChild(downloadButton); - const resumeBtn = document.createElement("button"); - resumeBtn.classList.add("styledButton", "resumeGame"); - elem.appendChild(resumeBtn); + const resumeButton = document.createElement("button"); + resumeButton.classList.add("styledButton", "resumeGame"); + elem.appendChild(resumeButton); this.trackClicks(deleteButton, () => this.deleteGame(games[i])); this.trackClicks(downloadButton, () => this.downloadGame(games[i])); - this.trackClicks(resumeBtn, () => this.resumeGame(games[i])); + this.trackClicks(resumeButton, () => this.resumeGame(games[i])); } } } @@ -415,6 +453,7 @@ export class MainMenuState extends GameState { this.app.savegameMgr.deleteSavegame(game).then( () => { this.renderSavegames(); + if (this.savedGames.length <= 0) this.renderMainMenu(); }, err => { this.dialogs.showWarning( diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 0a6470b2..01a787ea 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -119,6 +119,7 @@ demoBanners: mainMenu: play: Play continue: Continue + newGame: New Game changelog: Changelog importSavegame: Import openSourceHint: This game is open source!