Feat: User Relationships and Session Members.

This commit is contained in:
2026-02-28 19:53:50 +00:00
parent c7db290aaf
commit e8e9a02e7b
73 changed files with 3818 additions and 571 deletions

View File

@@ -81,6 +81,13 @@ export default class API {
}
// MTG Game API methods
static async getIsGameDataOutdated(game) {
const url = `/mtg/api/game/${game[attrGameId]}/is-outdated`;
let dataRequest = {};
dataRequest[flagGame] = game;
return await API.request(url, 'POST', dataRequest);
}
static async saveGame(game, formFilters, comment) {
let dataRequest = {};
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);

View File

@@ -4,6 +4,7 @@ import API from "../../api.js";
import TableBasePage from "../base_table.js";
import DOM from "../../dom.js";
import Events from "../../lib/events.js";
import OverlayConfirm from "../../components/common/temporary/overlay_confirm.js";
export default class PageMtgGame extends TableBasePage {
static hash = hashPageMtgGame;
@@ -21,6 +22,9 @@ export default class PageMtgGame extends TableBasePage {
hookupFilters() {
// this.sharedHookupFilters();
}
callFilterTableContent() {
window.location.reload();
}
loadRowTable(rowJson) {
return;
}
@@ -64,6 +68,8 @@ export default class PageMtgGame extends TableBasePage {
this.hookupPlayerLifeIncrementButtons();
this.hookupCommanderDamageIncrementButtons();
*/
PageMtgGame.hookupOverlayGameOutdated();
PageMtgGame.hookupGameUpdateCheck();
}
static hookupResetButton() {
const resetGameButton = document.querySelector('header.game-header .header-right .btn-tcg.btn-tcg-secondary');
@@ -117,6 +123,55 @@ export default class PageMtgGame extends TableBasePage {
}
}
*/
static hookupGameUpdateCheck() {
const intervalId = setInterval(async () => {
const isGameDataOutdated = await PageMtgGame.checkLastGameUpdate();
if (isGameDataOutdated) {
clearInterval(intervalId);
}
}, 30000);
}
static async checkLastGameUpdate() {
try {
// Fetch players, rounds, and damage records from API
const isGameDataOutdatedResponse = await API.getIsGameDataOutdated(game);
const isGameDataOutdated = isGameDataOutdatedResponse[flagData];
console.log({ isGameDataOutdatedResponse, isGameDataOutdated });
if (isGameDataOutdated) {
// const gameDataOutdatedLabel = document.querySelector(gameDataOutdatedLabelId);
// gameDataOutdatedLabel.classList.remove(flagIsCollapsed);
const pageTitleElement = document.querySelector('.topnav .tcg-title');
pageTitleElement.classList.add(flagDirty);
PageMtgGame.showOverlayGameOutdated();
}
return isGameDataOutdated;
} catch (error) {
console.error('Error checking for game update from server:', error);
}
}
static hookupOverlayGameOutdated() {
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {
buttonCancel.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
});
});
Events.initialiseEventHandler(idOverlayGameOutdated + ' button.' + flagSubmit, flagInitialised, (buttonConfirm) => {
buttonConfirm.addEventListener('click', () => {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.style.visibility = 'hidden';
window.location.reload();
});
});
}
static showOverlayGameOutdated() {
let overlay = document.querySelector(idOverlayGameOutdated);
overlay.classList.remove(flagIsCollapsed);
overlay.style.visibility = 'visible';
}
async loadGameFromServer() {
console.log("loading game from server");
@@ -244,7 +299,7 @@ export default class PageMtgGame extends TableBasePage {
))
.map(damage => damage[flagLifeLoss] - damage[flagLifeGain])
.reduce((a, b) => a + b, 0);
let life = startingLife - totalDamage;
let life = game[flagStartingLife] - totalDamage;
let isEliminatedByForce = damageRecords.filter(damage => (
damage[attrPlayerId] == playerId
@@ -482,7 +537,7 @@ export default class PageMtgGame extends TableBasePage {
, [flagActive]: true
};
}
hookupPlayerCardEvents() {
hookupPlayerCardEvents() {
// Life gain buttons
let lifeGainButtonSelector = '.life-gain-btn';
Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => {
@@ -609,7 +664,7 @@ export default class PageMtgGame extends TableBasePage {
let isLifeGainNotLoss = false;
this.changeLife(
playerId // playerId
, -amount // amount
, amount // amount
, isLifeGainNotLoss // isLifeGainNotLoss
, false // updateDamage
, damageIndex // damageIndex
@@ -757,7 +812,7 @@ export default class PageMtgGame extends TableBasePage {
return (
hasDamageWithIsEliminated
|| maxDamageFromOtherCommander >= 21
|| totalDamageTaken >= startingLife
|| totalDamageTaken >= game[flagStartingLife]
);
}
@@ -936,6 +991,19 @@ export default class PageMtgGame extends TableBasePage {
}
}
updateAndToggleShowButtonsSaveCancel() {
// let pageBody = document.querySelector(idPageBody);
let isDirty = DOM.hasDirtyChildrenContainer(pageBody);
let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;
let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);
let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed);
console.log({ pageBody, isDirty, areVisibleSaveCancelButtons });
this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons);
}
leave() {
super.leave();
}