Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-07-29 10:29:54 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-07-29 10:29:54 -0700
commit63fb4139d5ac5207b057bce46c4288df982bbeb1 (patch)
tree80b2b0c839d94e3af04cc9f2df6c45c169f600d2 /src
parente746cfb216836e26a6c060558278d724bd3ed5d5 (diff)
Add ability to deactivate/reactivate soldier records; make hex clearing work with right-click and add a confirmation modal dialog
Diffstat (limited to 'src')
-rw-r--r--src/index.js8
-rw-r--r--src/modules/gameboard.js103
-rw-r--r--src/modules/record_sheet.js49
3 files changed, 74 insertions, 86 deletions
diff --git a/src/index.js b/src/index.js
index 2cd2db6..2e2e306 100644
--- a/src/index.js
+++ b/src/index.js
@@ -145,7 +145,7 @@ async function load() {
document.querySelectorAll('.end-turn').forEach(el =>
el.addEventListener('click', ({ target: { dataset: { allegiance: opponent }}}) => {
const dataSelector = `[data-allegiance="${opponent}"]`,
- opponentRecords = Array.from(document.querySelectorAll(`.soldier-record${dataSelector}`)),
+ opponentRecords = Array.from(document.querySelectorAll(`.soldier-record${dataSelector}:not(.inactive)`)),
firstOpponentRecord = opponentRecords.sort((el1, el2) => el1.dataset.number > el2.dataset.number).at(0);
el.setAttribute('disabled', '');
@@ -154,7 +154,11 @@ document.querySelectorAll('.end-turn').forEach(el =>
clearMoveEndedIndicators(opponentRecords);
gameboard.clearFiringArcs(opponent);
- Observable.notify('select', firstOpponentRecord);
+
+ if (firstOpponentRecord) {
+ Observable.notify('select', firstOpponentRecord);
+ firstOpponentRecord.scrollIntoView({ behavior: 'smooth' });
+ }
})
);
diff --git a/src/modules/gameboard.js b/src/modules/gameboard.js
index 7c22dce..02b9c0f 100644
--- a/src/modules/gameboard.js
+++ b/src/modules/gameboard.js
@@ -205,6 +205,14 @@ function endMove() {
}
}
+// Work around webkit bug https://bugs.webkit.org/show_bug.cgi?id=233432
+function workaroundForWebKitBug233432(listener) {
+ return e => {
+ const elUnderCursor = svg.parentNode.elementFromPoint(e.clientX, e.clientY);
+ if (!e.target.contains(elUnderCursor)) listener(e);
+ };
+}
+
export function start(el) {
svg = el;
const gridTop = svg.querySelector('.grid-top');
@@ -221,20 +229,20 @@ export function start(el) {
}
});
- gridTop.addEventListener('pointerleave', e => {
- // Work around webkit bug https://bugs.webkit.org/show_bug.cgi?id=233432
- const elUnderCursor = svg.parentNode.elementFromPoint(e.clientX, e.clientY);
- if (!e.target.contains(elUnderCursor)) {
- console.log(['pointerleave', gridTop]);
- [...top.container.children].forEach(child => {
- top.collection.get(child).parent.append(child);
- top.collection.delete(child);
- });
-
- top.cell = null;
- }
+ clearHexDialog.querySelector('button[value="confirm"]').addEventListener('click', function(e) {
+ e.preventDefault();
+ clearHexDialog.close(this.value);
});
+ gridTop.addEventListener('pointerleave', workaroundForWebKitBug233432(e => {
+ [...top.container.children].forEach(child => {
+ top.collection.get(child).parent.append(child);
+ top.collection.delete(child);
+ });
+
+ top.cell = null;
+ }));
+
topHex.addEventListener('click', clickHandler);
topHex.addEventListener('contextmenu', e => {
@@ -246,8 +254,6 @@ export function start(el) {
startingLocations && getUnits(startingLocations).forEach(unit => unit.addEventListener('click', selectOffBoard));
function clickHandler(e) {
- console.log('top hex click event');
- //const occupant = getCellOccupant(this);
const occupant = svg.querySelector('.grid-top .container .counter')
let toPlace = placing.pop();
@@ -257,10 +263,8 @@ export function start(el) {
if (isCounter(toPlace)) arrangeCounters(top.container);
removeEventListener("keydown", handleMechTemplateRotation);
} else if (toPlace && !occupant) {
- //soldier.place(svg, toPlace, this);
top.collection.set(toPlace, { parent: top.cell });
top.container.prepend(toPlace);
- //toPlace.removeEventListener('click', selectOffBoard);
placing.push(toPlace);
getLockedSightLine(svg) ? updateSightLine(top.cell) : clearSightLine();
} else if (toPlace && occupant) {
@@ -271,79 +275,14 @@ export function start(el) {
}
} else if (!toPlace && occupant) {
Observable.notify('select', occupant);
- } else {
- console.log(['removing this contents', this]);
- getCellContents(this).forEach(el => el.remove());
}
const selected = getSelected();
}
getCells(svg).forEach(cell => {
- cell.addEventListener('click', e => {
- console.log('cell clickevent');
- const occupant = getCellOccupant(cell);
- let toPlace = placing.pop();
-
- if (isCounter(toPlace) || isMechTemplate(toPlace)) {
- //getHex(cell).after(toPlace);
- top.collection.set(toPlace, { parent: cell });
- top.container.append(toPlace);
- //if (isCounter(toPlace)) arrangeCounters(cell);
- if (isCounter(toPlace)) arrangeCounters(top.container);
- removeEventListener("keydown", handleMechTemplateRotation);
- } else if (toPlace && !occupant) {
- soldier.place(svg, toPlace, cell);
- toPlace.removeEventListener('click', selectOffBoard);
- placing.push(toPlace);
- getLockedSightLine(svg) ? updateSightLine(cell) : clearSightLine();
- } else if (toPlace && occupant) {
- if (toPlace === occupant) {
- if (hasPreviousMoveInHistory(toPlace)) {
- toPlace = moveBackOneStepInHistory(toPlace);
- placing.push(toPlace);
- getLockedSightLine(svg) ? updateSightLine(toPlace.parentElement) : drawSightLine(toPlace.parentElement, cell);
- } else {
- Observable.notify('select');
- }
- } else if (!occupant.classList.contains('clone')) {
- Observable.notify('select', occupant);
- } else {
- if (isClone(occupant).of(toPlace)) {
- if (hasPreviousMoveInHistory(occupant)) {
- deleteClone(occupant, toPlace, cell);
- } else {
- toPlace = clearMoveHistory(occupant, toPlace);
- getLockedSightLine(svg) ? updateSightLine(cell) : clearSightLine();
- }
- }
- placing.push(toPlace);
- }
- } else if (!toPlace && occupant) {
- Observable.notify('select', occupant);
- } else {
- console.log('removing cell contents', cell);
- getCellContents(cell).forEach(el => el.remove());
- }
-
- const selected = getSelected();
- });
-
- //cell.addEventListener('dblclick', e => {
- // const toPlace = placing.pop(),
- // occupant = getCellOccupant(cell);
- //
- // if (toPlace && occupant && toPlace === occupant) {
- // const { number, allegiance } = toPlace.dataset,
- // selector = `[data-allegiance="${allegiance}"][data-number="${number}"]`;
- //
- // svg.querySelectorAll(selector).forEach(el => el.remove());
- // Observable.notify('select');
- // }
- //});
-
cell.addEventListener('pointerover', () => {
- console.log(['pointerenter', cell]);
+ //console.log(['pointerenter', cell]);
top.cell = cell;
diff --git a/src/modules/record_sheet.js b/src/modules/record_sheet.js
index 584bcf7..931177f 100644
--- a/src/modules/record_sheet.js
+++ b/src/modules/record_sheet.js
@@ -99,6 +99,45 @@ function createRecord(unit) {
spans.forEach(el => div.appendChild(el));
+ function makeInactiveDivider(parent) {
+ const div = document.createElement('div');
+ div.classList.add('inactive-divider');
+ div.textContent = 'Inactive';
+ parent.append(div);
+ return div;
+ }
+
+ div.addEventListener('contextmenu', e => {
+ e.preventDefault();
+
+ if (!div.classList.contains('inactive')) {
+ const inactiveDivider = div.parentElement.querySelector('.inactive-divider') || makeInactiveDivider(div.parentElement);
+
+ div.addEventListener('transitionend', e => {
+ inactiveDivider.after(div);
+ inactiveDivider.scrollIntoView({ behavior: 'smooth' });
+ });
+
+ div.classList.add('inactive');
+ div.setAttributeNS(null, 'style', 'transform: scale(0.9);');
+ } else {
+ const squadRecords = div.parentElement.querySelectorAll(`.soldier-record:not(.inactive)[data-squad="${div.dataset.squad}"]`);
+ const sorted = [...squadRecords, div].sort(({dataset: { number: a }}, {dataset: { number: b }}) => +a > +b);
+ const index = sorted.findIndex(record => record === div);
+
+ if (index === 0)
+ div.parentElement.prepend(div);
+ else if (index === sorted.length - 1)
+ sorted[sorted.length - 2].after(div)
+ else
+ sorted[index - 1].after(div)
+
+ div.classList.remove('inactive');
+ div.removeAttributeNS(null, 'style');
+ div.scrollIntoView({ behavior: 'smooth' });
+ }
+ });
+
return div;
}
@@ -144,6 +183,7 @@ function select(data) {
if (isSelected || !data) return;
record.classList.add('selected');
+ record.scrollIntoView({ behavior: 'smooth' });
}
function endMove() {
@@ -151,9 +191,14 @@ function endMove() {
if (selected) {
selected.classList.toggle('movement-ended');
- }
+ const next = selected.parentElement.querySelector(`.soldier-record[data-squad="${selected.dataset.squad}"]:not(.movement-ended, .inactive)`);
+ deselect();
- deselect();
+ if (next) {
+ Observable.notify('select', next);
+ next.scrollIntoView({ behavior: 'smooth' });
+ }
+ }
}
export function extractWeaponFromRecord(recordEl) {