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,27 +642,76 @@ 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 button + * 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 makeButton(parent, classes = [], 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 + * @param {Array=} classes + * @param {string=} innerHTML + */ +export function makeButton(parent, classes = [], 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!