feat(inventory): wire up v2 system to main panel with full interactivity

- Add inventory section to template.html between Thoughts and bottom controls
- Wire up renderInventory() to all event handlers (message received, character changed, swipes)
- Initialize inventory container reference and event listeners in index.js
- Add showInventory toggle checkbox to settings with visibility control
- Update layout.js to handle inventory section and divider visibility
- Add renderInventory parameter to updateRPGData for separate mode support
- Update state.js and config.js with inventory container and showInventory setting

Inventory is now fully integrated as a visible, interactive panel section that persists across all user interactions.
This commit is contained in:
Lucas 'Paperboy' Rose-Winters
2025-10-17 15:36:15 +11:00
parent 60e4a6c2cc
commit 1f948cd5d8
7 changed files with 64 additions and 10 deletions
+18 -2
View File
@@ -18,6 +18,7 @@ import {
$userStatsContainer, $userStatsContainer,
$infoBoxContainer, $infoBoxContainer,
$thoughtsContainer, $thoughtsContainer,
$inventoryContainer,
setExtensionSettings, setExtensionSettings,
updateExtensionSettings, updateExtensionSettings,
setLastGeneratedData, setLastGeneratedData,
@@ -31,7 +32,8 @@ import {
setPanelContainer, setPanelContainer,
setUserStatsContainer, setUserStatsContainer,
setInfoBoxContainer, setInfoBoxContainer,
setThoughtsContainer setThoughtsContainer,
setInventoryContainer
} from './src/core/state.js'; } from './src/core/state.js';
import { loadSettings, saveSettings, saveChatData, loadChatData, updateMessageSwipeData } from './src/core/persistence.js'; import { loadSettings, saveSettings, saveChatData, loadChatData, updateMessageSwipeData } from './src/core/persistence.js';
import { registerAllEvents } from './src/core/events.js'; import { registerAllEvents } from './src/core/events.js';
@@ -58,6 +60,10 @@ import {
updateChatThoughts, updateChatThoughts,
createThoughtPanel createThoughtPanel
} from './src/systems/rendering/thoughts.js'; } from './src/systems/rendering/thoughts.js';
import { renderInventory } from './src/systems/rendering/inventory.js';
// Interaction modules
import { initInventoryEventListeners } from './src/systems/interaction/inventoryActions.js';
// UI Systems modules // UI Systems modules
import { import {
@@ -180,6 +186,7 @@ async function initUI() {
setUserStatsContainer($('#rpg-user-stats')); setUserStatsContainer($('#rpg-user-stats'));
setInfoBoxContainer($('#rpg-info-box')); setInfoBoxContainer($('#rpg-info-box'));
setThoughtsContainer($('#rpg-thoughts')); setThoughtsContainer($('#rpg-thoughts'));
setInventoryContainer($('#rpg-inventory'));
// Set up event listeners (enable/disable is handled in Extensions tab) // Set up event listeners (enable/disable is handled in Extensions tab)
$('#rpg-toggle-auto-update').on('change', function() { $('#rpg-toggle-auto-update').on('change', function() {
@@ -225,6 +232,12 @@ async function initUI() {
updateSectionVisibility(); updateSectionVisibility();
}); });
$('#rpg-toggle-inventory').on('change', function() {
extensionSettings.showInventory = $(this).prop('checked');
saveSettings();
updateSectionVisibility();
});
$('#rpg-toggle-thoughts-in-chat').on('change', function() { $('#rpg-toggle-thoughts-in-chat').on('change', function() {
extensionSettings.showThoughtsInChat = $(this).prop('checked'); extensionSettings.showThoughtsInChat = $(this).prop('checked');
// console.log('[RPG Companion] Toggle showThoughtsInChat changed to:', extensionSettings.showThoughtsInChat); // console.log('[RPG Companion] Toggle showThoughtsInChat changed to:', extensionSettings.showThoughtsInChat);
@@ -256,7 +269,7 @@ async function initUI() {
// console.log('[RPG Companion] Extension is disabled. Please enable it in the Extensions tab.'); // console.log('[RPG Companion] Extension is disabled. Please enable it in the Extensions tab.');
return; return;
} }
await updateRPGData(renderUserStats, renderInfoBox, renderThoughts); await updateRPGData(renderUserStats, renderInfoBox, renderThoughts, renderInventory);
}); });
$('#rpg-stat-bar-color-low').on('change', function() { $('#rpg-stat-bar-color-low').on('change', function() {
@@ -330,6 +343,7 @@ async function initUI() {
$('#rpg-toggle-user-stats').prop('checked', extensionSettings.showUserStats); $('#rpg-toggle-user-stats').prop('checked', extensionSettings.showUserStats);
$('#rpg-toggle-info-box').prop('checked', extensionSettings.showInfoBox); $('#rpg-toggle-info-box').prop('checked', extensionSettings.showInfoBox);
$('#rpg-toggle-thoughts').prop('checked', extensionSettings.showCharacterThoughts); $('#rpg-toggle-thoughts').prop('checked', extensionSettings.showCharacterThoughts);
$('#rpg-toggle-inventory').prop('checked', extensionSettings.showInventory);
$('#rpg-toggle-thoughts-in-chat').prop('checked', extensionSettings.showThoughtsInChat); $('#rpg-toggle-thoughts-in-chat').prop('checked', extensionSettings.showThoughtsInChat);
$('#rpg-toggle-html-prompt').prop('checked', extensionSettings.enableHtmlPrompt); $('#rpg-toggle-html-prompt').prop('checked', extensionSettings.enableHtmlPrompt);
$('#rpg-toggle-plot-buttons').prop('checked', extensionSettings.enablePlotButtons); $('#rpg-toggle-plot-buttons').prop('checked', extensionSettings.enablePlotButtons);
@@ -361,6 +375,7 @@ async function initUI() {
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
updateDiceDisplay(); updateDiceDisplay();
setupDiceRoller(); setupDiceRoller();
setupClassicStatsButtons(); setupClassicStatsButtons();
@@ -369,6 +384,7 @@ async function initUI() {
setupPlotButtons(sendPlotProgression); setupPlotButtons(sendPlotProgression);
setupMobileKeyboardHandling(); setupMobileKeyboardHandling();
setupContentEditableScrolling(); setupContentEditableScrolling();
initInventoryEventListeners();
} }
+3 -1
View File
@@ -29,6 +29,7 @@ export const defaultSettings = {
showUserStats: true, showUserStats: true,
showInfoBox: true, showInfoBox: true,
showCharacterThoughts: true, showCharacterThoughts: true,
showInventory: true, // Show inventory section (v2 system)
showThoughtsInChat: true, // Show thoughts overlay in chat showThoughtsInChat: true, // Show thoughts overlay in chat
enableHtmlPrompt: false, // Enable immersive HTML prompt injection enableHtmlPrompt: false, // Enable immersive HTML prompt injection
enablePlotButtons: true, // Show plot progression buttons above chat input enablePlotButtons: true, // Show plot progression buttons above chat input
@@ -71,5 +72,6 @@ export const defaultSettings = {
wis: 10, wis: 10,
cha: 10 cha: 10
}, },
lastDiceRoll: null // Store last dice roll result lastDiceRoll: null, // Store last dice roll result
collapsedInventoryLocations: [] // Array of collapsed storage location names
}; };
+8 -1
View File
@@ -17,6 +17,7 @@ export let extensionSettings = {
showUserStats: true, showUserStats: true,
showInfoBox: true, showInfoBox: true,
showCharacterThoughts: true, showCharacterThoughts: true,
showInventory: true, // Show inventory section (v2 system)
showThoughtsInChat: true, // Show thoughts overlay in chat showThoughtsInChat: true, // Show thoughts overlay in chat
enableHtmlPrompt: false, // Enable immersive HTML prompt injection enableHtmlPrompt: false, // Enable immersive HTML prompt injection
enablePlotButtons: true, // Show plot progression buttons above chat input enablePlotButtons: true, // Show plot progression buttons above chat input
@@ -59,7 +60,8 @@ export let extensionSettings = {
wis: 10, wis: 10,
cha: 10 cha: 10
}, },
lastDiceRoll: null // Store last dice roll result lastDiceRoll: null, // Store last dice roll result
collapsedInventoryLocations: [] // Array of collapsed storage location names
}; };
/** /**
@@ -123,6 +125,7 @@ export let $panelContainer = null;
export let $userStatsContainer = null; export let $userStatsContainer = null;
export let $infoBoxContainer = null; export let $infoBoxContainer = null;
export let $thoughtsContainer = null; export let $thoughtsContainer = null;
export let $inventoryContainer = null;
/** /**
* State setters - provide controlled mutation of state variables * State setters - provide controlled mutation of state variables
@@ -186,3 +189,7 @@ export function setInfoBoxContainer($element) {
export function setThoughtsContainer($element) { export function setThoughtsContainer($element) {
$thoughtsContainer = $element; $thoughtsContainer = $element;
} }
export function setInventoryContainer($element) {
$inventoryContainer = $element;
}
+4 -1
View File
@@ -25,8 +25,9 @@ import { parseResponse, parseUserStats } from './parser.js';
* @param {Function} renderUserStats - UI function to render user stats * @param {Function} renderUserStats - UI function to render user stats
* @param {Function} renderInfoBox - UI function to render info box * @param {Function} renderInfoBox - UI function to render info box
* @param {Function} renderThoughts - UI function to render character thoughts * @param {Function} renderThoughts - UI function to render character thoughts
* @param {Function} renderInventory - UI function to render inventory
*/ */
export async function updateRPGData(renderUserStats, renderInfoBox, renderThoughts) { export async function updateRPGData(renderUserStats, renderInfoBox, renderThoughts, renderInventory) {
if (isGenerating) { if (isGenerating) {
// console.log('[RPG Companion] Already generating, skipping...'); // console.log('[RPG Companion] Already generating, skipping...');
return; return;
@@ -123,6 +124,7 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
} else { } else {
// No assistant message to attach to - just update display // No assistant message to attach to - just update display
if (parsedData.userStats) { if (parsedData.userStats) {
@@ -131,6 +133,7 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
} }
// Save to chat metadata // Save to chat metadata
+5 -1
View File
@@ -28,6 +28,7 @@ import { updateRPGData } from '../generation/apiClient.js';
import { renderUserStats } from '../rendering/userStats.js'; import { renderUserStats } from '../rendering/userStats.js';
import { renderInfoBox } from '../rendering/infoBox.js'; import { renderInfoBox } from '../rendering/infoBox.js';
import { renderThoughts, updateChatThoughts } from '../rendering/thoughts.js'; import { renderThoughts, updateChatThoughts } from '../rendering/thoughts.js';
import { renderInventory } from '../rendering/inventory.js';
// Utils // Utils
import { getSafeThumbnailUrl } from '../../utils/avatars.js'; import { getSafeThumbnailUrl } from '../../utils/avatars.js';
@@ -162,6 +163,7 @@ export async function onMessageReceived(data) {
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
// Save to chat metadata // Save to chat metadata
saveChatData(); saveChatData();
@@ -169,7 +171,7 @@ export async function onMessageReceived(data) {
} else if (extensionSettings.generationMode === 'separate' && extensionSettings.autoUpdate) { } else if (extensionSettings.generationMode === 'separate' && extensionSettings.autoUpdate) {
// In separate mode with auto-update, trigger update after message // In separate mode with auto-update, trigger update after message
setTimeout(async () => { setTimeout(async () => {
await updateRPGData(renderUserStats, renderInfoBox, renderThoughts); await updateRPGData(renderUserStats, renderInfoBox, renderThoughts, renderInventory);
}, 500); }, 500);
} }
@@ -210,6 +212,7 @@ export function onCharacterChanged() {
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
// Update chat thought overlays // Update chat thought overlays
updateChatThoughts(); updateChatThoughts();
@@ -280,6 +283,7 @@ export function onMessageSwiped(messageIndex) {
renderUserStats(); renderUserStats();
renderInfoBox(); renderInfoBox();
renderThoughts(); renderThoughts();
renderInventory();
// Update chat thought overlays // Update chat thought overlays
updateChatThoughts(); updateChatThoughts();
+13 -4
View File
@@ -8,7 +8,8 @@ import {
$panelContainer, $panelContainer,
$userStatsContainer, $userStatsContainer,
$infoBoxContainer, $infoBoxContainer,
$thoughtsContainer $thoughtsContainer,
$inventoryContainer
} from '../../core/state.js'; } from '../../core/state.js';
/** /**
@@ -217,17 +218,25 @@ export function updateSectionVisibility() {
$userStatsContainer.toggle(extensionSettings.showUserStats); $userStatsContainer.toggle(extensionSettings.showUserStats);
$infoBoxContainer.toggle(extensionSettings.showInfoBox); $infoBoxContainer.toggle(extensionSettings.showInfoBox);
$thoughtsContainer.toggle(extensionSettings.showCharacterThoughts); $thoughtsContainer.toggle(extensionSettings.showCharacterThoughts);
if ($inventoryContainer) {
$inventoryContainer.toggle(extensionSettings.showInventory);
}
// Show/hide dividers intelligently // Show/hide dividers intelligently
// Divider after User Stats: shown if User Stats is visible AND at least one section after it is visible // Divider after User Stats: shown if User Stats is visible AND at least one section after it is visible
const showDividerAfterStats = extensionSettings.showUserStats && const showDividerAfterStats = extensionSettings.showUserStats &&
(extensionSettings.showInfoBox || extensionSettings.showCharacterThoughts); (extensionSettings.showInfoBox || extensionSettings.showCharacterThoughts || extensionSettings.showInventory);
$('#rpg-divider-stats').toggle(showDividerAfterStats); $('#rpg-divider-stats').toggle(showDividerAfterStats);
// Divider after Info Box: shown if Info Box is visible AND Mind Reading is visible // Divider after Info Box: shown if Info Box is visible AND at least one section after it is visible
const showDividerAfterInfo = extensionSettings.showInfoBox && const showDividerAfterInfo = extensionSettings.showInfoBox &&
extensionSettings.showCharacterThoughts; (extensionSettings.showCharacterThoughts || extensionSettings.showInventory);
$('#rpg-divider-info').toggle(showDividerAfterInfo); $('#rpg-divider-info').toggle(showDividerAfterInfo);
// Divider after Thoughts: shown if Thoughts is visible AND Inventory is visible
const showDividerAfterThoughts = extensionSettings.showCharacterThoughts &&
extensionSettings.showInventory;
$('#rpg-divider-thoughts').toggle(showDividerAfterThoughts);
} }
/** /**
+13
View File
@@ -44,6 +44,14 @@
<div id="rpg-thoughts" class="rpg-section rpg-thoughts-section"> <div id="rpg-thoughts" class="rpg-section rpg-thoughts-section">
<!-- Content will be populated by JavaScript --> <!-- Content will be populated by JavaScript -->
</div> </div>
<!-- Divider after Thoughts -->
<div id="rpg-divider-thoughts" class="rpg-divider"></div>
<!-- Inventory Section -->
<div id="rpg-inventory" class="rpg-section rpg-inventory-section">
<!-- Content will be populated by JavaScript -->
</div>
</div> </div>
<!-- HTML Prompt Toggle --> <!-- HTML Prompt Toggle -->
@@ -159,6 +167,11 @@
<span>Show Present Characters</span> <span>Show Present Characters</span>
</label> </label>
<label class="checkbox_label">
<input type="checkbox" id="rpg-toggle-inventory" />
<span>Show Inventory</span>
</label>
<label class="checkbox_label"> <label class="checkbox_label">
<input type="checkbox" id="rpg-toggle-thoughts-in-chat" /> <input type="checkbox" id="rpg-toggle-thoughts-in-chat" />
<span>Show Thoughts in Chat</span> <span>Show Thoughts in Chat</span>