Story 4.1: Tasks 3-6 Complete - Director's Board Integration & Settings Menu

- Task 3: Extended FoundryAdapter with user flag access methods
  - Added getFlag(userId, scope, key) method
  - Added setFlag(userId, scope, key, value) method
  - Added getFlagModule(userId, key) convenience method
  - Added setFlagModule(userId, key, value) convenience method

- Task 4: Integrated Privacy Settings with Director's Board
  - Updated participant-card.hbs to show Reaction Cam badge
  - Modified boardUtils.js to pass playerPrivacyManager through context
  - Updated DirectorsBoard to accept and pass playerPrivacyManager
  - Added CSS styles for Reaction Cam badge (SP accent color)

- Task 5: Registered PlayerPrivacyPanel in module settings
  - Added settings menu registration in module.js Hooks.once('ready')
  - Available to all users (restricted: false)
  - Uses localized labels and hints

- Task 6: Added all localization strings
  - Added SCRYING_POOL.PrivacyPanel.* strings for panel UI
  - Added SCRYING_POOL.Settings.* strings for settings menu

- Updated story file with task completion status

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
2026-05-23 21:29:58 +02:00
parent 61f362004e
commit fd0a7868f3
13 changed files with 1049 additions and 47 deletions
+50
View File
@@ -102,6 +102,56 @@ export class FoundryAdapter {
},
/** @returns {object|null} */
current: () => g.user ?? null,
/**
* Gets a user flag for a specific user.
* @param {string} userId - The user ID to get the flag for.
* @param {string} scope - The flag scope/namespace.
* @param {string} key - The flag key.
* @returns {unknown|null} The flag value, or null if not found.
*/
getFlag: (userId, scope, key) => {
const user = g.users?.get(userId);
if (user && typeof user.getFlag === 'function') {
return user.getFlag(scope, key) ?? null;
}
return null;
},
/**
* Sets a user flag for a specific user.
* Note: In FoundryVTT, users can only set their own flags. GM can set flags for any user.
* This method wraps the native user.setFlag() which returns a Promise.
* @param {string} userId - The user ID to set the flag for.
* @param {string} scope - The flag scope/namespace.
* @param {string} key - The flag key.
* @param {unknown} value - The flag value to set.
* @returns {Promise<unknown>|null} The promise from user.setFlag(), or null if user not found.
*/
setFlag: (userId, scope, key, value) => {
const user = g.users?.get(userId);
if (user && typeof user.setFlag === 'function') {
return /** @type {Promise<unknown>} */ (user.setFlag(scope, key, value));
}
return null;
},
/**
* Convenience method to get a module-scoped flag.
* @param {string} userId - The user ID to get the flag for.
* @param {string} key - The flag key (will be scoped to 'video-view-manager').
* @returns {unknown|null} The flag value, or null if not found.
*/
getFlagModule: (userId, key) => {
return this.getFlag(userId, 'video-view-manager', key);
},
/**
* Convenience method to set a module-scoped flag.
* @param {string} userId - The user ID to set the flag for.
* @param {string} key - The flag key (will be scoped to 'video-view-manager').
* @param {unknown} value - The flag value to set.
* @returns {Promise<unknown>|null} The promise from user.setFlag(), or null if user not found.
*/
setFlagModule: (userId, key, value) => {
return this.setFlag(userId, 'video-view-manager', key, value);
},
};
/** Scenes surface — wraps game.scenes. */