Module cleanup and tests
CI / ci (push) Failing after 7s

This commit is contained in:
2026-05-24 23:13:45 +02:00
parent 63d83e999a
commit 5dc9b3b8d4
72 changed files with 2545 additions and 1220 deletions
+35 -11
View File
@@ -1,7 +1,7 @@
// @ts-nocheck — Module entry point with FoundryVTT globals, no exports needed
/* global Handlebars */
/**
* module.js — Entry point and wiring diagram for Video View Manager (Scrying Pool).
* module.js — Entry point and wiring diagram for Scrying Pool.
*
* This file is the wiring diagram ONLY. It imports all modules, constructs them
* with injected dependencies, and holds NO business logic.
@@ -34,6 +34,7 @@ import { DirectorsBoard } from './src/ui/gm/DirectorsBoard.js';
import { ConfirmationBar } from './src/ui/gm/ConfirmationBar.js';
import { PlayerPrivacyPanelMenu, initPlayerPrivacyPanelMenu } from './src/ui/player/PlayerPrivacyPanelMenu.js';
import { initGMPlayerPrivacySelector } from './src/ui/gm/GMPlayerPrivacySelector.js';
import { ScryingPoolCameraViews, initScryingPoolCameraViews } from './src/ui/shared/ScryingPoolCameraViews.js';
import { SOCKET_EVENTS } from './src/contracts/socket-message.js';
// Module-level references — constructed in init hook, used across hooks
@@ -57,6 +58,18 @@ let directorsBoardButtonAdded = false;
Hooks.once("init", () => {
console.log("[ScryingPool] init — module loading");
// Foundry sets body class from URL route. If the URL has a query string
// (e.g. /game?presetName=ALL), the class becomes "game?presetName=ALL"
// instead of "game", breaking body.game { display:flex } and collapsing the UI.
const badClass = Array.from(document.body.classList).find(c => c.startsWith("game") && c !== "game");
if (badClass) {
document.body.classList.remove(badClass);
document.body.classList.add("game");
}
// Take over Foundry's camera dock — must be set before Foundry instantiates ui.webrtc
CONFIG.ui.webrtc = ScryingPoolCameraViews;
// WebRTC mode setting — determines how the module handles AV integration
// Updated for FULL REPLACEMENT architecture (hiding Foundry's dock, showing our own)
game.settings.register("scrying-pool", "webrtcMode", {
@@ -88,6 +101,8 @@ Hooks.once("init", () => {
config: true,
type: Boolean,
default: true,
name: "Show GM Self Feed",
hint: "When enabled, the GM's own camera feed is shown in the Scrying Pool strip.",
});
// Story 2.1: per-user notification verbosity preference (client-scoped)
@@ -95,6 +110,8 @@ Hooks.once("init", () => {
scope: "client",
config: true,
type: String,
name: "Notification Verbosity",
hint: "Controls which camera-state notifications you see. 'All' shows every change; 'GM Only' shows changes only to the GM and affected participant; 'Silent' suppresses all notifications except your own camera changes.",
choices: {
all: "All",
"gm-only": "GM Only",
@@ -109,8 +126,8 @@ Hooks.once("init", () => {
config: true,
type: Boolean,
default: true,
name: "Enable Scene Preset Auto-Apply",
hint: "When enabled, scenes with configured presets will automatically apply them on activation",
name: "Enable Camera Layout Auto-Apply",
hint: "When enabled, scenes with a configured camera layout will automatically apply it on activation",
});
// Construct data layer — constructors are side-effect-free
@@ -129,22 +146,22 @@ Hooks.once("init", () => {
// Story 2.3: Bulk-action keybindings (GM only, migrated to scrying-pool namespace)
game.keybindings.register('scrying-pool', 'showAll', {
name: game.i18n.localize('video-view-manager.keybindings.showAll.name'),
hint: game.i18n.localize('video-view-manager.keybindings.showAll.hint'),
name: game.i18n.localize('scrying-pool.keybindings.showAll.name'),
hint: game.i18n.localize('scrying-pool.keybindings.showAll.hint'),
editable: [{ key: 'KeyS', modifiers: ['Control', 'Shift'] }],
restricted: true,
onDown: () => directorsBoard?.showAll(),
});
game.keybindings.register('scrying-pool', 'hideAll', {
name: game.i18n.localize('video-view-manager.keybindings.hideAll.name'),
hint: game.i18n.localize('video-view-manager.keybindings.hideAll.hint'),
name: game.i18n.localize('scrying-pool.keybindings.hideAll.name'),
hint: game.i18n.localize('scrying-pool.keybindings.hideAll.hint'),
editable: [{ key: 'KeyH', modifiers: ['Control', 'Shift'] }],
restricted: true,
onDown: () => directorsBoard?.hideAll(),
});
game.keybindings.register('scrying-pool', 'spotlightParticipant', {
name: game.i18n.localize('video-view-manager.keybindings.spotlightParticipant.name'),
hint: game.i18n.localize('video-view-manager.keybindings.spotlightParticipant.hint'),
name: game.i18n.localize('scrying-pool.keybindings.spotlightParticipant.name'),
hint: game.i18n.localize('scrying-pool.keybindings.spotlightParticipant.hint'),
editable: [{ key: 'KeyP', modifiers: ['Control', 'Shift'] }],
restricted: true,
onDown: () => directorsBoard?.spotlightFocused(),
@@ -302,13 +319,20 @@ Hooks.once("ready", () => {
window.directorsBoard = directorsBoard;
}
// Inject Scrying Pool deps into our camera views replacement (all clients)
// Directors Board reference is GM-only — players get null so _onConfigure is a no-op
initScryingPoolCameraViews(
adapter.users.isGM() ? directorsBoard : null,
stateStore
);
// Pre-load participant-card as a Handlebars partial for directors-board
// ApplicationV2 requires partials to be registered explicitly
(async () => {
try {
const resp = await fetch('modules/video-view-manager/templates/participant-card.hbs');
const resp = await fetch('modules/scrying-pool/templates/participant-card.hbs');
const source = await resp.text();
Handlebars.registerPartial('modules/video-view-manager/templates/participant-card.hbs', source);
Handlebars.registerPartial('modules/scrying-pool/templates/participant-card.hbs', source);
} catch (err) {
console.warn('[ScryingPool] Failed to register participant-card partial:', err);
}