Add settings panel with strip reopen button and AV disabled notification
CI / ci (push) Successful in 46s
CI / ci (push) Successful in 46s
Features: - Added ScryingPoolSettings application with reopen/close strip buttons - Registered settings menu in module settings (GM only) - Added template for settings panel with styled buttons - Added translations for settings UI - Added info notification when AV is not available Files: - src/ui/gm/ScryingPoolSettings.js: New settings application - templates/settings.hbs: Settings panel template - lang/en.json: Added translations - module.js: Registered settings menu and AV notification Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
+8
-2
@@ -27,7 +27,8 @@
|
||||
"gmShowed": "GM showed {name}'s camera",
|
||||
"personalHidden": "GM has hidden your camera. Your portrait is shown to other Participants.",
|
||||
"personalShowed": "Your camera is now visible to the table.",
|
||||
"avConfigGMOnly": "A/V settings are managed by the GM."
|
||||
"avConfigGMOnly": "A/V settings are managed by the GM.",
|
||||
"AVDisabled": "Audio/Video is not available in this FoundryVTT instance. Scrying Pool camera control features are disabled."
|
||||
},
|
||||
"settings": {
|
||||
"showGMSelfFeed": {
|
||||
@@ -205,7 +206,12 @@
|
||||
"PlayerPrivacyPanelHint": "Opt in or out of Reaction Cam and other automation features",
|
||||
"GMPlayerPrivacySelector": "View Player Privacy Settings",
|
||||
"GMPlayerPrivacySelectorLabel": "View and manage player privacy consent settings",
|
||||
"GMPlayerPrivacySelectorHint": "Select a player to view their automation opt-in preferences (read-only)"
|
||||
"GMPlayerPrivacySelectorHint": "Select a player to view their automation opt-in preferences (read-only)",
|
||||
"Title": "Scrying Pool Settings",
|
||||
"Hint": "Configure Scrying Pool module behavior",
|
||||
"StripStatus": "Strip Status",
|
||||
"ReopenStrip": "Open Strip",
|
||||
"CloseStrip": "Close Strip"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ 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 { ScryingPoolSettings } from './src/ui/gm/ScryingPoolSettings.js';
|
||||
|
||||
// Factory function to create ScryingPoolSettings with roleRenderer dependency
|
||||
function initScryingPoolSettings(roleRendererRef) {
|
||||
return () => new ScryingPoolSettings(roleRendererRef);
|
||||
}
|
||||
import { SOCKET_EVENTS } from './src/contracts/socket-message.js';
|
||||
|
||||
// Module-level references — constructed in init hook, used across hooks
|
||||
@@ -262,6 +268,10 @@ Hooks.once("ready", () => {
|
||||
} else if (outcome === 'unsupported') {
|
||||
adapter.webrtc = null;
|
||||
console.log('[ScryingPool] WebRTC not available - AV features disabled');
|
||||
// Show info message to GM about AV being disabled
|
||||
if (game.user?.isGM) {
|
||||
ui.notifications?.info(game.i18n.localize('SCRYING_POOL.Notifications.AVDisabled'));
|
||||
}
|
||||
} else {
|
||||
// Legacy: track-disable or css-fallback (deprecated)
|
||||
adapter.webrtc = FoundryAdapter.buildWebRTCSurface(game.webrtc);
|
||||
@@ -403,6 +413,17 @@ Hooks.once("ready", () => {
|
||||
type: PlayerPrivacyPanelMenu,
|
||||
restricted: false,
|
||||
});
|
||||
|
||||
// Story 5.3: Register ScryingPoolSettings in module settings
|
||||
// Provides button to reopen the strip
|
||||
game.settings.registerMenu('scrying-pool', 'stripSettings', {
|
||||
name: 'SCRYING_POOL.Settings.Title',
|
||||
label: 'SCRYING_POOL.Settings.Title',
|
||||
hint: 'SCRYING_POOL.Settings.Hint',
|
||||
icon: 'fa-solid fa-cog',
|
||||
type: initScryingPoolSettings(roleRenderer),
|
||||
restricted: true, // GM only
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('[ScryingPool] Module initialization failed:', err);
|
||||
throw err; // Re-throw to prevent module from loading in broken state
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* Scrying Pool Settings Application
|
||||
* Provides a settings panel with a button to reopen the strip
|
||||
*/
|
||||
export class ScryingPoolSettings extends foundry.applications.api.ApplicationV2 {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'scrying-pool-settings',
|
||||
classes: ['scrying-pool-settings'],
|
||||
window: { title: 'Scrying Pool Settings', resizable: true },
|
||||
position: { width: 400, height: 200 },
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: 'modules/scrying-pool/templates/settings.hbs',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {object} options - Application options
|
||||
* @param {object} roleRenderer - The role renderer instance to access openStrip/closeStrip
|
||||
*/
|
||||
constructor(roleRenderer, options = {}) {
|
||||
super(options);
|
||||
this._roleRenderer = roleRenderer;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _prepareContext(options) {
|
||||
return {
|
||||
hasStrip: this._roleRenderer?._strip?.rendered ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onRender(context, options) {
|
||||
super._onRender(context, options);
|
||||
|
||||
// Add click handler for reopen button
|
||||
const reopenBtn = this.element.querySelector('[data-action="reopen-strip"]');
|
||||
if (reopenBtn) {
|
||||
reopenBtn.addEventListener('click', () => {
|
||||
this._roleRenderer?.openStrip();
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
|
||||
// Add click handler for close button
|
||||
const closeBtn = this.element.querySelector('[data-action="close-strip"]');
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', () => {
|
||||
this._roleRenderer?.closeStrip();
|
||||
this.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the strip open/closed
|
||||
*/
|
||||
_toggleStrip() {
|
||||
if (this._roleRenderer?._strip?.rendered) {
|
||||
this._roleRenderer.closeStrip();
|
||||
} else {
|
||||
this._roleRenderer?.openStrip();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<form class="scrying-pool-settings-form">
|
||||
<div class="form-group">
|
||||
<h2>{{localize "SCRYING_POOL.Settings.Title"}}</h2>
|
||||
<p class="hint">{{localize "SCRYING_POOL.Settings.Hint"}}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>{{localize "SCRYING_POOL.Settings.StripStatus"}}</label>
|
||||
{{#if hasStrip}}
|
||||
<button type="button" data-action="close-strip" class="scrying-pool-btn scrying-pool-btn-close">
|
||||
<i class="fa-solid fa-eye-slash"></i> {{localize "SCRYING_POOL.Settings.CloseStrip"}}
|
||||
</button>
|
||||
{{else}}
|
||||
<button type="button" data-action="reopen-strip" class="scrying-pool-btn scrying-pool-btn-reopen">
|
||||
<i class="fa-solid fa-eye"></i> {{localize "SCRYING_POOL.Settings.ReopenStrip"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.scrying-pool-settings-form {
|
||||
padding: 15px;
|
||||
}
|
||||
.scrying-pool-settings-form .form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.scrying-pool-settings-form .hint {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.scrying-pool-btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.scrying-pool-btn-reopen {
|
||||
background-color: var(--success);
|
||||
color: white;
|
||||
}
|
||||
.scrying-pool-btn-close {
|
||||
background-color: var(--danger);
|
||||
color: white;
|
||||
}
|
||||
.scrying-pool-btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
</form>
|
||||
Reference in New Issue
Block a user