diff --git a/package.json b/package.json index 76c4820..91349c7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "beaming", "author": "Kyle Florence", "description": "A browser-based puzzle game that involves directing beams through a hexagonal grid.", - "version": "0.4.2", + "version": "0.4.3", "license": "CC BY-NC 4.0", "main": "src/electron/main.js", "type": "module", diff --git a/src/components/dialog.js b/src/components/dialog.js index ae7a7cf..a733ca7 100644 --- a/src/components/dialog.js +++ b/src/components/dialog.js @@ -13,7 +13,7 @@ document.querySelectorAll('[data-dialog]').forEach((target) => { const close = dialog.querySelector('header button') close.addEventListener('click', async () => { - const element = document.getElementById(dialog.dataset.from) + const element = document.getElementById(dialog.dataset.from) ?? title const direction = element.id === title.id ? 'right' : 'left' delete dialog.dataset.from diff --git a/src/components/editor.js b/src/components/editor.js index 9b3fd31..49efcf0 100644 --- a/src/components/editor.js +++ b/src/components/editor.js @@ -475,7 +475,9 @@ export class Editor { } #updatePlayUrl () { - elements.play.firstElementChild.setAttribute('href', this.#puzzle.getShareUrl(State.ContextKeys.Play)) + elements.play.firstElementChild.setAttribute( + 'href', + this.#puzzle.getShareUrl(State.ContextKeys.Play, true)) } static mark (center, width) { diff --git a/src/components/game.js b/src/components/game.js index 726e506..1a51585 100644 --- a/src/components/game.js +++ b/src/components/game.js @@ -23,8 +23,8 @@ const elements = Object.freeze({ editPuzzles: document.getElementById('edit-puzzles'), play: document.getElementById('title-play'), playLoad: document.getElementById('play-custom-load'), - playProfile: document.getElementById('play-profile'), playPuzzles: document.getElementById('play-puzzles'), + profile: document.querySelectorAll('.current-profile-name'), quit: document.getElementById('title-quit'), screen: document.getElementById('screen'), select: document.getElementById('select'), @@ -38,7 +38,7 @@ export class Game { #eventListeners = new EventListeners({ context: this }) constructor () { - elements.playProfile.textContent = Storage.Profile.get().name + elements.profile.forEach((element) => { element.textContent = Storage.Profile.get().name }) this.puzzle = new Puzzle() this.editor = new Editor(this.puzzle) @@ -180,7 +180,7 @@ export class Game { async #onProfileUpdate (event) { this.#teardown() Storage.Profiles.set(event.detail.id) - elements.playProfile.textContent = Storage.Profile.get().name + elements.profile.forEach((element) => { element.textContent = Storage.Profile.get().name }) Game.updatePuzzles() } diff --git a/src/components/modifier.js b/src/components/modifier.js index 9ec2753..e2ab897 100644 --- a/src/components/modifier.js +++ b/src/components/modifier.js @@ -159,7 +159,7 @@ export class Modifier extends Stateful { this.#down = false } - onTap (event, detail) { + onTap (event, detail = {}) { this.dispatchEvent(Modifier.Events.Invoked, detail) } diff --git a/src/components/modifiers/puzzle.js b/src/components/modifiers/puzzle.js index b1c56d7..cab5da2 100644 --- a/src/components/modifiers/puzzle.js +++ b/src/components/modifiers/puzzle.js @@ -45,6 +45,11 @@ export class PuzzleModifier extends Modifier { await puzzle.select(state.id, { animations: [Puzzle.Animations.SlideLeft] }) } + onTap (event, detail) { + // Invoking this modifier does not result in a move + super.onTap(event, { addMove: false }) + } + static schema () { const imports = Puzzles.imports() return Object.freeze(merge([ diff --git a/src/components/puzzle.js b/src/components/puzzle.js index bafeebc..1153f20 100644 --- a/src/components/puzzle.js +++ b/src/components/puzzle.js @@ -179,15 +179,16 @@ export class Puzzle { return this.#interact.getProjectPoint(point) } - getShareUrl (context = State.getContext()) { + getShareUrl (context = State.getContext(), clone = false) { // Electron runs on localhost but should use the production web URL const shareUrl = new URL(process.env.TARGET === 'electron' ? baseUrl : url) shareUrl.search = '' shareUrl.searchParams.append(context, '') - const state = this.state.getConfig() + const state = clone ? this.state.clone() : this.state + const config = state.getConfig() // Update the imports using data from local cache - State.resolveImports(state, this.state.getCurrent()) - shareUrl.hash = ['', State.getId(), this.state.encode(state)].join('/') + State.resolveImports(config, state.getCurrent()) + shareUrl.hash = ['', State.getId(), state.encode(config)].join('/') return shareUrl.toString() } @@ -663,7 +664,9 @@ export class Puzzle { .sort((beam) => tile.items.some((item) => item === beam) ? -1 : 0) .forEach((beam) => beam.onModifierInvoked(event, this)) - this.state.addMove(event.type, tile, modifier, this.selectedTile) + if (event.detail.addMove !== false) { + this.state.addMove(event.type, tile, modifier, this.selectedTile) + } setTimeout(async () => { this.updateState() @@ -841,6 +844,14 @@ export class Puzzle { Game.updatePuzzles([State.ContextKeys.Play]) document.body.classList.add(Puzzle.Events.Loaded) + + document.querySelectorAll('.group').forEach((element) => { + // Fixes .group:empty not updating properly in Safari + // This bug is marked as resolved but seems to still be manifesting + // https://bugs.webkit.org/show_bug.cgi?id=26570 + element.style.display = 'initial' + element.style.display = '' + }) } async #undo () { diff --git a/src/index.html b/src/index.html index 44ef70d..c93fc08 100644 --- a/src/index.html +++ b/src/index.html @@ -110,7 +110,7 @@