From 00265ba905a63521bb7fab5d0ead48476e6a7d47 Mon Sep 17 00:00:00 2001 From: Chanho Chung Date: Sat, 22 Nov 2025 11:14:14 +0900 Subject: [PATCH 1/6] fix: mobile layout of rpg-info-box --- style.css | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/style.css b/style.css index c98588d..c277cc7 100644 --- a/style.css +++ b/style.css @@ -1111,8 +1111,8 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Scrollable content wrapper inside info section */ .rpg-info-content { - display: flex; - flex-direction: column; + display: grid; + grid-template-rows: 1.2fr 0.8fr auto; gap: 0.25em; flex: 1; min-height: 0; @@ -4880,7 +4880,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Info Box takes 50% of vertical space */ .rpg-mobile-tab-content[data-tab-content="info"] > #rpg-info-box, .rpg-mobile-tab-content[data-tab-content="info"] > .rpg-info-section { - flex: 1 1 50% !important; + flex: 1 1 100% !important; min-height: 0; overflow-y: auto; padding-bottom: 16px; @@ -4915,14 +4915,12 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Rows scale proportionally to fill Info Box */ .rpg-dashboard-row-1 { - flex: 1.2 !important; /* Slightly more space for 4 widgets */ height: auto !important; /* Remove desktop height constraint */ display: flex !important; gap: 0.25em; } .rpg-dashboard-row-2 { - flex: 0.8 !important; /* Less space for 1 widget */ display: flex !important; } @@ -4970,6 +4968,16 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } /* Recent Events widget - mobile text sizing */ + .rpg-notebook-header { + gap: clamp(26px, 6vw, 30px); + padding: clamp(5px, 1.5vw, 7px) 0; + } + + .rpg-notebook-ring { + width: clamp(8px, 1.25vw, 10px); + height: clamp(8px, 1.25vw, 10px); + } + .rpg-notebook-title { font-size: clamp(9px, 2.2vw, 11px) !important; } @@ -5326,13 +5334,12 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Make Recent Events section take less vertical space on mobile */ .rpg-dashboard-row-3 { - flex: 0 0 auto !important; - max-height: 150px !important; /* Limit height on mobile */ + max-height: 100px !important; /* Limit height on mobile */ } /* Make the events widget scrollable if content exceeds height */ .rpg-events-widget { - max-height: 150px !important; + max-height: 100px !important; overflow-y: auto !important; } @@ -5340,6 +5347,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { .rpg-notebook-lines { padding: 0.25em 0.5em !important; gap: 0.1em !important; + min-height: 0; } /* Reduce spacing in notebook lines */ @@ -5444,7 +5452,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* More padding for editable fields */ .rpg-editable { padding: 0.5em; - min-height: 2.75rem; + min-height: 1.25rem; } /* Larger close buttons */ @@ -6581,5 +6589,3 @@ body:has(.rpg-panel.rpg-position-left) #sheld { font-size: clamp(14px, 3vw, 18px) !important; } } - - From 02f080cc984fb268c2005a9edb617575fa3e917e Mon Sep 17 00:00:00 2001 From: Chanho Chung Date: Sat, 22 Nov 2025 23:09:54 +0900 Subject: [PATCH 2/6] fix: mobile layout of rpg-mobile-tabs, rpg-info-content, rpg-character-card --- style.css | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/style.css b/style.css index c277cc7..ca3d561 100644 --- a/style.css +++ b/style.css @@ -1112,12 +1112,11 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Scrollable content wrapper inside info section */ .rpg-info-content { display: grid; - grid-template-rows: 1.2fr 0.8fr auto; + grid-template-rows: 80px 60px minmax(min-content, auto); gap: 0.25em; flex: 1; min-height: 0; - overflow-y: auto; - overflow-x: hidden; + overflow: hidden; } .rpg-info-content::-webkit-scrollbar { @@ -1815,11 +1814,10 @@ body:has(.rpg-panel.rpg-position-left) #sheld { border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.2s ease; width: 100%; /* Ensure cards take full width */ - max-height: clamp(120px, 18vh, 200px); + max-height: clamp(200px, 18vh, 250px); box-sizing: border-box; /* Include padding and border in width calculation */ flex-shrink: 0; /* Prevent cards from shrinking */ - overflow-x: hidden; - overflow-y: auto; + overflow: hidden; scrollbar-width: thin; scrollbar-color: var(--rpg-border) transparent; } @@ -1983,7 +1981,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { } .rpg-character-stat .rpg-stat-name { - font-size: clamp(0.5vw, 0.6vw, 0.7vw) !important; + font-size: clamp(9px, 0.6vw, 0.7vw) !important; font-weight: 600 !important; white-space: nowrap !important; } @@ -4813,6 +4811,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { border-bottom: 2px solid var(--SmartThemeBorderColor); margin: 0; padding: 0; + overflow-x: auto; } .rpg-mobile-tab { @@ -4871,16 +4870,17 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Info tab contains Info Box and Characters with 50/50 split */ .rpg-mobile-tab-content[data-tab-content="info"].active { - flex-direction: column; + display: grid; + grid-template-rows: minmax(min-content, auto) minmax(min-content, 1fr); gap: 0; height: 100%; min-height: 0; + overflow-y: auto; } /* Info Box takes 50% of vertical space */ .rpg-mobile-tab-content[data-tab-content="info"] > #rpg-info-box, .rpg-mobile-tab-content[data-tab-content="info"] > .rpg-info-section { - flex: 1 1 100% !important; min-height: 0; overflow-y: auto; padding-bottom: 16px; @@ -4892,7 +4892,6 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Characters section takes 50% of vertical space */ .rpg-mobile-tab-content[data-tab-content="info"] > #rpg-thoughts, .rpg-mobile-tab-content[data-tab-content="info"] > .rpg-thoughts-section { - flex: 1 1 50% !important; min-height: 0; overflow-y: auto; padding-bottom: 16px; @@ -5340,7 +5339,6 @@ body:has(.rpg-panel.rpg-position-left) #sheld { /* Make the events widget scrollable if content exceeds height */ .rpg-events-widget { max-height: 100px !important; - overflow-y: auto !important; } /* Compact the notebook lines container */ From fed4e2d09574e1a93a1256942e208a4698a9827d Mon Sep 17 00:00:00 2001 From: Chanho Chung Date: Sat, 22 Nov 2025 23:27:45 +0900 Subject: [PATCH 3/6] fix: mobile layout of rpg-skills-section and rpg-classic-stat --- style.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/style.css b/style.css index ca3d561..641271e 100644 --- a/style.css +++ b/style.css @@ -943,7 +943,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { display: flex; align-items: center; gap: 0.375em; - font-size: clamp(0.4vw, 0.5vw, 0.6vw); + font-size: clamp(11px, 0.5vw, 14px); padding: clamp(4px, 0.6vh, 6px) 0.375em; background: rgba(0, 0, 0, 0.3); border-radius: 0.25em; @@ -5425,6 +5425,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { .rpg-classic-stats { grid-column: 1 !important; grid-row: 4 !important; + min-height: 140px; } /* Make attributes grid single column too for readability */ From eef547b0fabf4b16f135b630a3e6ed600298e9fd Mon Sep 17 00:00:00 2001 From: Chanho Chung Date: Sat, 22 Nov 2025 23:35:30 +0900 Subject: [PATCH 4/6] fix: mobile layout of rpg-skills-section font size --- style.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/style.css b/style.css index 641271e..32cbc5b 100644 --- a/style.css +++ b/style.css @@ -943,7 +943,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld { display: flex; align-items: center; gap: 0.375em; - font-size: clamp(11px, 0.5vw, 14px); + font-size: clamp(0.4vw, 0.5vw, 0.6vw); padding: clamp(4px, 0.6vh, 6px) 0.375em; background: rgba(0, 0, 0, 0.3); border-radius: 0.25em; @@ -5218,6 +5218,11 @@ body:has(.rpg-panel.rpg-position-left) #sheld { transform: scale(0.95); } + .rpg-skills-section { + font-size: clamp(11px, 2.8vw, 14px); + line-height: 1.3; + } + /* ======================================== MOBILE THOUGHT ICON POSITIONING ======================================== */ From 950d83fc181a06e8ed030bcd54bb5e29e2330f46 Mon Sep 17 00:00:00 2001 From: Spicy_Marinara Date: Sun, 23 Nov 2025 19:59:27 +0100 Subject: [PATCH 5/6] Update promptBuilder.js --- src/systems/generation/promptBuilder.js | 60 ++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/systems/generation/promptBuilder.js b/src/systems/generation/promptBuilder.js index fc064b8..0d5b3ff 100644 --- a/src/systems/generation/promptBuilder.js +++ b/src/systems/generation/promptBuilder.js @@ -4,7 +4,8 @@ */ import { getContext } from '../../../../../../extensions.js'; -import { chat, getCurrentChatDetails } from '../../../../../../../script.js'; +import { chat, getCurrentChatDetails, characters, this_chid } from '../../../../../../../script.js'; +import { selected_group, getGroupMembers } from '../../../../../../group-chats.js'; import { extensionSettings, committedTrackerData, FEATURE_FLAGS } from '../../core/state.js'; // Type imports @@ -15,6 +16,56 @@ import { extensionSettings, committedTrackerData, FEATURE_FLAGS } from '../../co */ export const DEFAULT_HTML_PROMPT = `If appropriate, include inline HTML, CSS, and JS segments whenever they enhance visual storytelling (e.g., for in-world screens, posters, books, letters, signs, crests, labels, etc.). Style them to match the setting's theme (e.g., fantasy, sci-fi), keep the text readable, and embed all assets directly (using inline SVGs only with no external scripts, libraries, or fonts). Use these elements freely and naturally within the narrative as characters would encounter them, including animations, 3D effects, pop-ups, dropdowns, websites, and so on. Do not wrap the HTML/CSS/JS in code fences!`; +/** + * Gets character card information for current chat (handles both single and group chats) + * @returns {string} Formatted character information + */ +function getCharacterCardsInfo() { + let characterInfo = ''; + + // Check if in group chat + if (selected_group) { + const groupMembers = getGroupMembers(selected_group); + if (groupMembers && groupMembers.length > 0) { + characterInfo += 'Characters in this roleplay:\n\n'; + + groupMembers.forEach((member, index) => { + if (!member || !member.name) return; + + characterInfo += `\n`; + + if (member.description) { + characterInfo += `${member.description}\n`; + } + + if (member.personality) { + characterInfo += `${member.personality}\n`; + } + + characterInfo += `\n\n`; + }); + } + } else if (this_chid !== undefined && characters && characters[this_chid]) { + // Single character chat + const character = characters[this_chid]; + + characterInfo += 'Character in this roleplay:\n\n'; + characterInfo += `\n`; + + if (character.description) { + characterInfo += `${character.description}\n`; + } + + if (character.personality) { + characterInfo += `${character.personality}\n`; + } + + characterInfo += `\n\n`; + } + + return characterInfo; +} + /** * Builds a formatted inventory summary for AI context injection. * Converts v2 inventory structure to multi-line plaintext format. @@ -478,6 +529,13 @@ export function generateSeparateUpdatePrompt() { // System message introducing the history section let systemMessage = `You will be acting as an uncensored RPG Companion. Your goal is to provide, track, and manage details in the user's roleplay. You will be replying with information in a specified format only.\n\n`; systemMessage += `You should maintain an objective tone.\n\n`; + + // Add character card information + const characterInfo = getCharacterCardsInfo(); + if (characterInfo) { + systemMessage += characterInfo + '\n\n'; + } + systemMessage += `Here is the description of the protagonist for reference:\n`; systemMessage += `\n{{persona}}\n\n`; systemMessage += `\n\n`; From 0c5b55b190b93ed1c82023dd7f82f0ece0c99d7c Mon Sep 17 00:00:00 2001 From: Spicy_Marinara Date: Tue, 25 Nov 2025 12:40:28 +0100 Subject: [PATCH 6/6] Add character card info in separate mode with muted filtering and scrollable Past Events --- src/systems/generation/apiClient.js | 2 +- src/systems/generation/promptBuilder.js | 26 ++++++++++++++++++------- style.css | 22 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/systems/generation/apiClient.js b/src/systems/generation/apiClient.js index 3337653..a279983 100644 --- a/src/systems/generation/apiClient.js +++ b/src/systems/generation/apiClient.js @@ -122,7 +122,7 @@ export async function updateRPGData(renderUserStats, renderInfoBox, renderThough } } - const prompt = generateSeparateUpdatePrompt(); + const prompt = await generateSeparateUpdatePrompt(); // Generate using raw prompt (uses current preset, no chat history) const response = await generateRaw({ diff --git a/src/systems/generation/promptBuilder.js b/src/systems/generation/promptBuilder.js index 0d5b3ff..3d0371e 100644 --- a/src/systems/generation/promptBuilder.js +++ b/src/systems/generation/promptBuilder.js @@ -5,7 +5,7 @@ import { getContext } from '../../../../../../extensions.js'; import { chat, getCurrentChatDetails, characters, this_chid } from '../../../../../../../script.js'; -import { selected_group, getGroupMembers } from '../../../../../../group-chats.js'; +import { selected_group, getGroupMembers, getGroupChat } from '../../../../../../group-chats.js'; import { extensionSettings, committedTrackerData, FEATURE_FLAGS } from '../../core/state.js'; // Type imports @@ -20,19 +20,31 @@ export const DEFAULT_HTML_PROMPT = `If appropriate, include inline HTML, CSS, an * Gets character card information for current chat (handles both single and group chats) * @returns {string} Formatted character information */ -function getCharacterCardsInfo() { +async function getCharacterCardsInfo() { let characterInfo = ''; // Check if in group chat if (selected_group) { + const group = await getGroupChat(selected_group); const groupMembers = getGroupMembers(selected_group); + if (groupMembers && groupMembers.length > 0) { characterInfo += 'Characters in this roleplay:\n\n'; - groupMembers.forEach((member, index) => { + // Filter out disabled (muted) members + const disabledMembers = group?.disabled_members || []; + let characterIndex = 0; + + groupMembers.forEach((member) => { if (!member || !member.name) return; - characterInfo += `\n`; + // Skip muted characters + if (member.avatar && disabledMembers.includes(member.avatar)) { + return; + } + + characterIndex++; + characterInfo += `\n`; if (member.description) { characterInfo += `${member.description}\n`; @@ -42,7 +54,7 @@ function getCharacterCardsInfo() { characterInfo += `${member.personality}\n`; } - characterInfo += `\n\n`; + characterInfo += `\n\n`; }); } } else if (this_chid !== undefined && characters && characters[this_chid]) { @@ -520,7 +532,7 @@ export function generateRPGPromptText() { * * @returns {Array<{role: string, content: string}>} Array of message objects for API */ -export function generateSeparateUpdatePrompt() { +export async function generateSeparateUpdatePrompt() { const depth = extensionSettings.updateDepth; const userName = getContext().name1; @@ -531,7 +543,7 @@ export function generateSeparateUpdatePrompt() { systemMessage += `You should maintain an objective tone.\n\n`; // Add character card information - const characterInfo = getCharacterCardsInfo(); + const characterInfo = await getCharacterCardsInfo(); if (characterInfo) { systemMessage += characterInfo + '\n\n'; } diff --git a/style.css b/style.css index 32cbc5b..327b0bb 100644 --- a/style.css +++ b/style.css @@ -1520,6 +1520,28 @@ body:has(.rpg-panel.rpg-position-left) #sheld { padding: 0.25em 0.75em 0.5em 0.75em; position: relative; z-index: 1; + overflow-y: auto; + max-height: 100%; + flex: 1; + min-height: 0; +} + +.rpg-notebook-lines::-webkit-scrollbar { + width: 0.188rem; +} + +.rpg-notebook-lines::-webkit-scrollbar-track { + background: var(--rpg-bg); + border-radius: 2px; +} + +.rpg-notebook-lines::-webkit-scrollbar-thumb { + background: var(--rpg-highlight); + border-radius: 2px; +} + +.rpg-notebook-lines::-webkit-scrollbar-thumb:hover { + background: var(--rpg-text); } .rpg-notebook-line {