diff --git a/src/js/core/config.js b/src/js/core/config.js index 47030972..000c5dce 100644 --- a/src/js/core/config.js +++ b/src/js/core/config.js @@ -1,3 +1,7 @@ +/* typehints:start */ +import { Application } from "../application"; +/* typehints:end */ + export const IS_DEBUG = G_IS_DEV && typeof window !== "undefined" && @@ -17,7 +21,7 @@ export const THIRDPARTY_URLS = { privacyPolicy: "https://tobspr.io/privacy.html", - stanaloneCampaignLink: "https://get.shapez.io", + standaloneCampaignLink: "https://get.shapez.io/$campaign", puzzleDlcStorePage: "https://store.steampowered.com/app/1625400/shapezio__Puzzle_DLC", levelTutorialVideos: { @@ -29,6 +33,18 @@ export const THIRDPARTY_URLS = { modBrowser: "https://shapez.mod.io/?preview=f55f6304ca4873d9a25f3b575571b948", }; +/** + * @param {Application} app + * @param {string} campaign + */ +export function openStandaloneLink(app, campaign) { + const discount = globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : ""; + const steamSuffix = G_IS_STEAM_DEMO ? "_steamdemo" : ""; + app.platformWrapper.openExternalLink( + THIRDPARTY_URLS.standaloneCampaignLink.replace("$campaign", campaign + discount + steamSuffix) + ); +} + export const globalConfig = { // Size of a single tile in Pixels. // NOTICE: Update webpack.production.config too! diff --git a/src/js/game/hud/parts/modal_dialogs.js b/src/js/game/hud/parts/modal_dialogs.js index 6ca611e9..0492d8c0 100644 --- a/src/js/game/hud/parts/modal_dialogs.js +++ b/src/js/game/hud/parts/modal_dialogs.js @@ -8,7 +8,7 @@ import { BaseHUDPart } from "../base_hud_part"; import { Dialog, DialogLoading, DialogOptionChooser } from "../../../core/modal_dialog_elements"; import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; -import { THIRDPARTY_URLS } from "../../../core/config"; +import { openStandaloneLink } from "../../../core/config"; export class HUDModalDialogs extends BaseHUDPart { constructor(root, app) { @@ -117,19 +117,8 @@ export class HUDModalDialogs extends BaseHUDPart { this.app.sound.playUiSound(SOUNDS.dialogOk); } - this.app.analytics.trackUiClick("demo_dialog_show"); - - dialog.buttonSignals.cancel.add(() => { - this.app.analytics.trackUiClick("demo_dialog_cancel"); - }); - dialog.buttonSignals.getStandalone.add(() => { - this.app.analytics.trackUiClick("demo_dialog_click"); - window.open( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_demo_dialog" + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + openStandaloneLink(this.app, "shapez_demo_dialog"); }); return dialog.buttonSignals; diff --git a/src/js/game/hud/parts/standalone_advantages.js b/src/js/game/hud/parts/standalone_advantages.js index 4ce8d7c6..9b2440a8 100644 --- a/src/js/game/hud/parts/standalone_advantages.js +++ b/src/js/game/hud/parts/standalone_advantages.js @@ -1,4 +1,4 @@ -import { globalConfig, THIRDPARTY_URLS } from "../../../core/config"; +import { globalConfig, openStandaloneLink } from "../../../core/config"; import { InputReceiver } from "../../../core/input_receiver"; import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; @@ -45,20 +45,10 @@ export class HUDStandaloneAdvantages extends BaseHUDPart { ); this.trackClicks(this.contentDiv.querySelector("button.steamLinkButton"), () => { - const discount = - globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : ""; - - this.root.app.analytics.trackUiClick("standalone_advantage_visit_steam"); - this.root.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_std_advg" + - discount + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + openStandaloneLink(this.root.app, "shapez_std_advg"); this.close(); }); this.trackClicks(this.contentDiv.querySelector("button.otherCloseButton"), () => { - this.root.app.analytics.trackUiClick("standalone_advantage_no_thanks"); this.close(); }); } diff --git a/src/js/game/hud/parts/steam_capsule.js b/src/js/game/hud/parts/steam_capsule.js index ab82fcbe..09d70c41 100644 --- a/src/js/game/hud/parts/steam_capsule.js +++ b/src/js/game/hud/parts/steam_capsule.js @@ -1,4 +1,4 @@ -import { globalConfig, THIRDPARTY_URLS } from "../../../core/config"; +import { openStandaloneLink } from "../../../core/config"; import { makeDiv } from "../../../core/utils"; import { BaseHUDPart } from "../base_hud_part"; import { DynamicDomAttach } from "../dynamic_dom_attach"; @@ -11,17 +11,10 @@ export class HUDSteamCapsule extends BaseHUDPart { } initialize() { - const discount = globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : ""; - this.domAttach = new DynamicDomAttach(this.root, this.element); this.trackClicks(this.element, () => { - this.root.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_steamcapsule" + - discount + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + openStandaloneLink(this.root.app, "shapez_steamcapsule"); }); } diff --git a/src/js/game/hud/parts/tutorial_hints.js b/src/js/game/hud/parts/tutorial_hints.js index c9499f85..96f7d3fd 100644 --- a/src/js/game/hud/parts/tutorial_hints.js +++ b/src/js/game/hud/parts/tutorial_hints.js @@ -76,8 +76,6 @@ export class HUDPartTutorialHints extends BaseHUDPart { } show() { - this.root.app.analytics.trackUiClick("tutorial_hint_show"); - this.root.app.analytics.trackUiClick("tutorial_hint_show_lvl_" + this.root.hubGoals.level); this.element.classList.add("enlarged", "noBlur"); this.enlarged = true; this.root.app.inputMgr.makeSureAttachedAndOnTop(this.inputReciever); diff --git a/src/js/game/hud/parts/tutorial_video_offer.js b/src/js/game/hud/parts/tutorial_video_offer.js index 3cd2cb90..ee232a92 100644 --- a/src/js/game/hud/parts/tutorial_video_offer.js +++ b/src/js/game/hud/parts/tutorial_video_offer.js @@ -23,10 +23,8 @@ export class HUDTutorialVideoOffer extends BaseHUDPart { "ok:good", ]); - this.root.app.analytics.trackUiClick("ingame_video_link_show_" + level); ok.add(() => { this.root.app.platformWrapper.openExternalLink(tutorialVideoLink); - this.root.app.analytics.trackUiClick("ingame_video_link_open_" + level); }); } }); diff --git a/src/js/game/hud/parts/watermark.js b/src/js/game/hud/parts/watermark.js index e8f378c4..13f9cd21 100644 --- a/src/js/game/hud/parts/watermark.js +++ b/src/js/game/hud/parts/watermark.js @@ -1,4 +1,4 @@ -import { globalConfig, THIRDPARTY_URLS } from "../../../core/config"; +import { globalConfig, openStandaloneLink } from "../../../core/config"; import { makeDiv } from "../../../core/utils"; import { T } from "../../../translations"; import { BaseHUDPart } from "../base_hud_part"; @@ -34,16 +34,7 @@ export class HUDWatermark extends BaseHUDPart { : "") ); this.trackClicks(this.linkElement, () => { - this.root.app.analytics.trackUiClick("watermark_click_2_direct"); - const discount = - globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : ""; - - this.root.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_watermark" + - discount + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + openStandaloneLink(this.root.app, "shapez_watermark"); }); } diff --git a/src/js/platform/analytics.js b/src/js/platform/analytics.js index cf839aca..ac70ef60 100644 --- a/src/js/platform/analytics.js +++ b/src/js/platform/analytics.js @@ -24,12 +24,6 @@ export class AnalyticsInterface { */ setUserContext(userName) {} - /** - * Tracks a click no an ui element - * @param {string} elementName - */ - trackUiClick(elementName) {} - /** * Tracks when a new state is entered * @param {string} stateId diff --git a/src/js/platform/browser/game_analytics.js b/src/js/platform/browser/game_analytics.js index 2b762f33..4c2a0538 100644 --- a/src/js/platform/browser/game_analytics.js +++ b/src/js/platform/browser/game_analytics.js @@ -19,7 +19,7 @@ const analyticsUrl = G_IS_DEV ? "http://localhost:8001" : "https://analytics.sha const analyticsLocalFile = G_IS_STEAM_DEMO ? "shapez_token_steamdemo.bin" : "shapez_token_123.bin"; const CURRENT_ABT = "abt_spl"; -const CURRENT_ABT_COUNT = 2; +const CURRENT_ABT_COUNT = G_IS_STEAM_DEMO ? 3 : 2; export class ShapezGameAnalytics extends GameAnalyticsInterface { constructor(app) { @@ -79,7 +79,9 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface { ) .then(() => { if (this.abtVariant === "1") { - THIRDPARTY_URLS.stanaloneCampaignLink = "https://get.shapez.io/bundle"; + THIRDPARTY_URLS.standaloneCampaignLink = "https://get.shapez.io/bundle/$campaign"; + } else if (this.abtVariant === "2") { + THIRDPARTY_URLS.standaloneCampaignLink = "steam://advertise/1318690"; } }); } diff --git a/src/js/platform/browser/google_analytics.js b/src/js/platform/browser/google_analytics.js index 782471d2..34b75ce5 100644 --- a/src/js/platform/browser/google_analytics.js +++ b/src/js/platform/browser/google_analytics.js @@ -64,23 +64,6 @@ export class GoogleAnalyticsImpl extends AnalyticsInterface { } } - trackUiClick(elementName) { - const stateKey = this.app.stateMgr.getCurrentState().key; - const fullSelector = stateKey + ">" + elementName; - - try { - if (window.gtag) { - logger.log("📊 Tracking click on:", fullSelector); - window.gtag("event", "click", { - event_category: "ui", - event_label: fullSelector, - }); - } - } catch (ex) { - logger.warn("📊 Failed to track ui click:", ex); - } - } - /** * Tracks an event so GA keeps track of the user */ diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index d3d8ae96..096cef11 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -1,6 +1,6 @@ import { getLogoSprite } from "../core/background_resources_loader"; import { cachebust } from "../core/cachebust"; -import { globalConfig, THIRDPARTY_URLS } from "../core/config"; +import { globalConfig, openStandaloneLink, THIRDPARTY_URLS } from "../core/config"; import { GameState } from "../core/game_state"; import { DialogWithForm } from "../core/modal_dialog_elements"; import { FormElementInput } from "../core/modal_dialog_forms"; @@ -247,7 +247,6 @@ export class MainMenuState extends GameState { this.app.savegameMgr.getSavegamesMetaData().length > 0 && !this.app.restrictionMgr.getHasUnlimitedSavegames() ) { - this.app.analytics.trackUiClick("importgame_slot_limit_show"); this.showSavegameSlotLimit(); return; } @@ -257,7 +256,6 @@ export class MainMenuState extends GameState { if (file) { const closeLoader = this.dialogs.showLoadingDialog(); waitNextFrame().then(() => { - this.app.analytics.trackUiClick("import_savegame"); const reader = new FileReader(); reader.addEventListener("load", event => { const contents = event.target.result; @@ -354,11 +352,9 @@ export class MainMenuState extends GameState { ".exitAppButton": this.onExitAppButtonClicked, ".steamLink": this.onSteamLinkClicked, ".discordLink": () => { - this.app.analytics.trackUiClick("main_menu_link_discord"); this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.discord); }, ".githubLink": () => { - this.app.analytics.trackUiClick("main_menu_link_github"); this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.github); }, ".producerLink": () => this.app.platformWrapper.openExternalLink("https://tobspr.io"), @@ -449,14 +445,9 @@ export class MainMenuState extends GameState { } onSteamLinkClicked() { - this.app.analytics.trackUiClick("main_menu_steam_link"); const discount = globalConfig.currentDiscount > 0 ? "_discount" + globalConfig.currentDiscount : ""; - this.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_mainmenu" + - discount + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + + openStandaloneLink(this.app, "shapez_mainmenu"); return false; } @@ -470,12 +461,10 @@ export class MainMenuState extends GameState { } onRedditClicked() { - this.app.analytics.trackUiClick("main_menu_reddit_link"); this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.reddit); } onLanguageChooseClicked() { - this.app.analytics.trackUiClick("choose_language"); const setting = /** @type {EnumSetting} */ (this.app.settings.getSettingHandleById("language")); const { optionSelected } = this.dialogs.showOptionChooser(T.settings.labels.language.title, { @@ -611,10 +600,7 @@ export class MainMenuState extends GameState { * @param {SavegameMetadata} game */ resumeGame(game) { - this.app.analytics.trackUiClick("resume_game"); - this.app.adProvider.showVideoAd().then(() => { - this.app.analytics.trackUiClick("resume_game_adcomplete"); const savegame = this.app.savegameMgr.getSavegameById(game.internalId); savegame .readAsync() @@ -689,8 +675,6 @@ export class MainMenuState extends GameState { * @param {SavegameMetadata} game */ deleteGame(game) { - this.app.analytics.trackUiClick("delete_game"); - const signals = this.dialogs.showWarning( T.dialogs.confirmSavegameDelete.title, T.dialogs.confirmSavegameDelete.text @@ -719,8 +703,6 @@ export class MainMenuState extends GameState { * @param {SavegameMetadata} game */ downloadGame(game) { - this.app.analytics.trackUiClick("download_game"); - const savegame = this.app.savegameMgr.getSavegameById(game.internalId); savegame.readAsync().then(() => { const data = ReadWriteProxy.serializeObject(savegame.currentData); @@ -739,12 +721,7 @@ export class MainMenuState extends GameState { ["cancel:bad", "getStandalone:good"] ); getStandalone.add(() => { - this.app.analytics.trackUiClick("visit_steampage_from_slot_limit"); - this.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_slotlimit" + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); + openStandaloneLink(this.app, "shapez_slotlimit"); }); } @@ -753,7 +730,6 @@ export class MainMenuState extends GameState { } onTranslationHelpLinkClicked() { - this.app.analytics.trackUiClick("translation_help_link"); this.app.platformWrapper.openExternalLink( "https://github.com/tobspr/shapez.io/blob/master/translations" ); @@ -764,19 +740,16 @@ export class MainMenuState extends GameState { this.app.savegameMgr.getSavegamesMetaData().length > 0 && !this.app.restrictionMgr.getHasUnlimitedSavegames() ) { - this.app.analytics.trackUiClick("startgame_slot_limit_show"); this.showSavegameSlotLimit(); return; } - this.app.analytics.trackUiClick("startgame"); this.app.adProvider.showVideoAd().then(() => { const savegame = this.app.savegameMgr.createNewSavegame(); this.moveToState("InGameState", { savegame, }); - this.app.analytics.trackUiClick("startgame_adcomplete"); }); } diff --git a/src/js/states/mobile_warning.js b/src/js/states/mobile_warning.js index bd0b7ff2..520b155a 100644 --- a/src/js/states/mobile_warning.js +++ b/src/js/states/mobile_warning.js @@ -21,9 +21,7 @@ export class MobileWarningState extends GameState {

If you want to play on your computer, you can also get the game on Steam:

- Get on Steam! + Play on Steam! `; } diff --git a/src/js/states/mods.js b/src/js/states/mods.js index 28433bad..50d42d1a 100644 --- a/src/js/states/mods.js +++ b/src/js/states/mods.js @@ -1,4 +1,4 @@ -import { THIRDPARTY_URLS } from "../core/config"; +import { openStandaloneLink, THIRDPARTY_URLS } from "../core/config"; import { TextualGameState } from "../core/textual_game_state"; import { MODS } from "../mods/modloader"; import { T } from "../translations"; @@ -132,18 +132,11 @@ export class ModsState extends TextualGameState { } openBrowseMods() { - this.app.analytics.trackUiClick("mods_sbrowse_link"); this.app.platformWrapper.openExternalLink(THIRDPARTY_URLS.modBrowser); } onSteamLinkClicked() { - this.app.analytics.trackUiClick("mods_steam_link"); - this.app.platformWrapper.openExternalLink( - THIRDPARTY_URLS.stanaloneCampaignLink + - "/shapez_modsettings" + - (G_IS_STEAM_DEMO ? "_steamdemo" : "") - ); - + openStandaloneLink(this.app, "shapez_modsettings"); return false; }