summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Peter Christen <mc@yacy.net>2026-03-28 11:19:37 +0100
committerMichael Peter Christen <mc@yacy.net>2026-03-28 11:19:37 +0100
commitb6f8b8850742682fa81f46c3986aaed1b6965992 (patch)
treec82a6fd72d3de0045d224499ac54f37455d6f6be
parent7b14e31949fee99f56055a0368e71d6175e0aa69 (diff)
Fix yacychat P2P mode detection for global search visibility
-rw-r--r--htroot/yacychat.html92
-rw-r--r--source/net/yacy/htroot/yacychat.java4
2 files changed, 77 insertions, 19 deletions
diff --git a/htroot/yacychat.html b/htroot/yacychat.html
index bc0e7f164..cfe815291 100644
--- a/htroot/yacychat.html
+++ b/htroot/yacychat.html
@@ -342,6 +342,16 @@
display: none;
}
+ .search-default-options .global-option,
+ .search-default-options .global-label {
+ display: none;
+ }
+
+ .search-default-options.has-global .global-option,
+ .search-default-options.has-global .global-label {
+ display: flex;
+ }
+
.composer-main {
flex: 1;
display: flex;
@@ -726,15 +736,15 @@
<div class="chat-flow">
<div class="search-default-control">
<span>Default Dialog Augmentation:</span>
- <div class="search-default-options" id="searchDefaultOptions" role="radiogroup" aria-label="Attach search results by default">
- <input type="radio" id="searchDefaultNone" name="searchDefault" value="no"/>
- <label for="searchDefaultNone">no search, allow attachments</label>
- <input type="radio" id="searchDefaultLocal" name="searchDefault" value="local" checked="checked"/>
- <label for="searchDefaultLocal">use local search</label>
- <input type="radio" id="searchDefaultGlobal" name="searchDefault" value="global"/>
- <label for="searchDefaultGlobal">use global search</label>
- <span class="search-default-slider" aria-hidden="true"></span>
- </div>
+<div class="search-default-options" id="searchDefaultOptions" role="radiogroup" aria-label="Attach search results by default">
+ <input type="radio" id="searchDefaultNone" name="searchDefault" value="no"/>
+ <label for="searchDefaultNone">no search, allow attachments</label>
+ <input type="radio" id="searchDefaultLocal" name="searchDefault" value="local" checked="checked"/>
+ <label for="searchDefaultLocal">use local search</label>
+ <input type="radio" id="searchDefaultGlobal" name="searchDefault" value="global" class="global-option"/>
+ <label for="searchDefaultGlobal" class="global-label">use global search</label>
+ <span class="search-default-slider" aria-hidden="true"></span>
+ </div>
</div>
<div class="chat-messages" id="chatMessages" aria-live="polite"></div>
<form id="chatForm">
@@ -788,6 +798,7 @@
<script type="text/javascript">
const SYSTEM_PROMPT = '#[system_prompt]#';
const defaultApiHost = '';
+ const P2P_MODE = #[p2p_mode]# === 1;
const CHAT_VFS_PATH = '/yacy/chat/chat.json';
const SETTINGS_VFS_PATH = '/yacy/chat/settings.json';
@@ -796,6 +807,7 @@
local: 'local',
global: 'global'
};
+ const SEARCH_OPTIONS = P2P_MODE ? SEARCH_DEFAULTS : { none: 'no', local: 'local' };
const state = {
messages: [],
@@ -807,7 +819,7 @@
busy: false,
attachment: null,
searchMode: SEARCH_DEFAULTS.none,
- searchDefault: SEARCH_DEFAULTS.local,
+ searchDefault: P2P_MODE ? SEARCH_DEFAULTS.local : SEARCH_DEFAULTS.local,
assistantSeen: false,
showSystem: false
};
@@ -835,6 +847,15 @@
searchDefaultGlobal: document.getElementById('searchDefaultGlobal')
};
+ // configure search default options based on P2P mode
+ if (dom.searchDefaultOptions) {
+ if (P2P_MODE) {
+ dom.searchDefaultOptions.classList.add('has-global');
+ } else {
+ dom.searchDefaultOptions.classList.remove('has-global');
+ }
+ }
+
const IMAGE_MIME_TYPES = new Set(['image/png', 'image/jpeg']);
const TEXT_MIME_TYPES = new Set(['text/plain', 'text/markdown', 'text/x-tex', 'application/x-tex', 'application/x-latex']);
const IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg']);
@@ -1389,13 +1410,19 @@
function setSearchModeActive(mode) {
let nextMode = mode;
if (mode === true) {
- nextMode = state.searchDefault === SEARCH_DEFAULTS.none ? SEARCH_DEFAULTS.local : state.searchDefault;
+ // validate against available options
+ if (P2P_MODE) {
+ nextMode = state.searchDefault === SEARCH_DEFAULTS.none ? SEARCH_DEFAULTS.local : state.searchDefault;
+ } else {
+ nextMode = state.searchDefault === SEARCH_DEFAULTS.global ? SEARCH_DEFAULTS.local : state.searchDefault;
+ }
}
if (!nextMode || nextMode === false) {
nextMode = SEARCH_DEFAULTS.none;
}
- if (nextMode !== SEARCH_DEFAULTS.local && nextMode !== SEARCH_DEFAULTS.global) {
- nextMode = SEARCH_DEFAULTS.none;
+ // reject global mode when not in P2P
+ if (!P2P_MODE && nextMode === SEARCH_DEFAULTS.global) {
+ nextMode = SEARCH_DEFAULTS.local;
}
state.searchMode = nextMode;
state.attachment = null;
@@ -1415,7 +1442,9 @@
function applySearchDefaultToComposer() {
if (!dom.attachmentRow || state.attachment) return;
if (state.searchDefault !== SEARCH_DEFAULTS.none) {
- setSearchModeActive(state.searchDefault);
+ // validate search default against available options
+ const validDefault = P2P_MODE ? state.searchDefault : state.searchDefault === SEARCH_DEFAULTS.global ? SEARCH_DEFAULTS.local : state.searchDefault;
+ setSearchModeActive(validDefault);
} else {
setSearchModeActive(SEARCH_DEFAULTS.none);
}
@@ -1423,11 +1452,27 @@
function updateSearchDefaultSlider() {
if (!dom.searchDefaultOptions) return;
+ // count only visible inputs (exclude hidden global option)
const inputs = Array.from(dom.searchDefaultOptions.querySelectorAll('input[name="searchDefault"]'));
- const activeIndex = inputs.findIndex(input => input.checked);
- const segments = inputs.length || 2;
+ const visibleInputs = inputs.filter(input => {
+ if (input === dom.searchDefaultGlobal) {
+ return dom.searchDefaultOptions.classList.contains('has-global');
+ }
+ return true;
+ });
+ const activeIndex = visibleInputs.findIndex(input => input.checked);
+ const segments = visibleInputs.length || 2;
dom.searchDefaultOptions.style.setProperty('--segments', segments);
- dom.searchDefaultOptions.style.setProperty('--active', activeIndex < 0 ? 0 : activeIndex);
+ // map checked input to its index among visible inputs
+ let displayIndex = 0;
+ for (const input of inputs) {
+ if (input === dom.searchDefaultGlobal && !dom.searchDefaultOptions.classList.contains('has-global')) {
+ continue;
+ }
+ if (input.checked) break;
+ displayIndex++;
+ }
+ dom.searchDefaultOptions.style.setProperty('--active', displayIndex);
}
async function getVfsClient() {
@@ -1481,13 +1526,22 @@
console.warn('Failed to load search default', err);
}
if (stored === 'none') stored = SEARCH_DEFAULTS.none;
- if (stored && Object.values(SEARCH_DEFAULTS).includes(stored)) {
+ // validate stored default against available options
+ if (!P2P_MODE && stored === SEARCH_DEFAULTS.global) {
+ stored = SEARCH_DEFAULTS.local;
+ }
+ if (stored && Object.values(SEARCH_OPTIONS).includes(stored)) {
state.searchDefault = stored;
}
+ // update radio buttons to reflect stored state
if (dom.searchDefaultNone && state.searchDefault === SEARCH_DEFAULTS.none) {
dom.searchDefaultNone.checked = true;
} else if (dom.searchDefaultLocal && state.searchDefault === SEARCH_DEFAULTS.local) {
dom.searchDefaultLocal.checked = true;
+ } else if (dom.searchDefaultGlobal && !P2P_MODE) {
+ // global not available, fallback to local
+ dom.searchDefaultLocal.checked = true;
+ state.searchDefault = SEARCH_DEFAULTS.local;
} else if (dom.searchDefaultGlobal && state.searchDefault === SEARCH_DEFAULTS.global) {
dom.searchDefaultGlobal.checked = true;
}
@@ -2659,7 +2713,7 @@
const target = event.target;
if (!(target instanceof HTMLInputElement)) return;
if (target.name !== 'searchDefault') return;
- if (!Object.values(SEARCH_DEFAULTS).includes(target.value)) return;
+ if (!Object.values(SEARCH_OPTIONS).includes(target.value)) return;
state.searchDefault = target.value;
updateSearchDefaultSlider();
persistSearchDefault();
diff --git a/source/net/yacy/htroot/yacychat.java b/source/net/yacy/htroot/yacychat.java
index 43b6107b5..5545d2e57 100644
--- a/source/net/yacy/htroot/yacychat.java
+++ b/source/net/yacy/htroot/yacychat.java
@@ -30,6 +30,10 @@ public class yacychat {
final String systemPrompt = sb.getConfig("ai.system-prompt", net.yacy.http.servlets.RAGProxyServlet.LLM_SYSTEM_PROMPT_DEFAULT);
prop.put("system_prompt", systemPrompt);
prop.put("topmenu", sb.getConfigBool("ai.shield.show-chat-link", false) ? (sb.getConfigBool("publicTopmenu", true) ? 1 : 0) : 2);
+ // determine if P2P mode is active (global search available)
+ final boolean indexReceiveGranted = sb.getConfigBool(net.yacy.search.SwitchboardConstants.INDEX_RECEIVE_ALLOW_SEARCH, true) || (sb.isRobinsonMode() && sb.getConfig(net.yacy.search.SwitchboardConstants.CLUSTER_MODE, "").equals(net.yacy.search.SwitchboardConstants.CLUSTER_MODE_PUBLIC_CLUSTER));
+ final boolean p2pmode = indexReceiveGranted;
+ prop.put("p2p_mode", p2pmode ? 1 : 0);
// return rewrite properties
return prop;