feat(app): honor Archipelago D-14 embed defaults via query params

Archipelago's Chat tab (neode-ui) embeds AIUI in an iframe and now
passes two presentation-only query params on the embed URL:

- ?chatExpanded — chat starts in the full message list rather than
  the collapsed prompt-index. chatCollapsed's initial ref now checks
  for this param before falling back to the existing localStorage
  default; never written back to localStorage, so the standalone
  app's own persisted preference is untouched.
- ?mobileChat — on mobile, ChatPage opens on the chat tab rather than
  whatever tab survived from a prior mount of the module-singleton
  content-panel state. mobileTab already defaulted to 'chat'; this
  just re-asserts it once on mount when the param is present, so it
  doesn't interfere with the hasDetailOpen/panelOpen watchers driving
  normal tab switching in response to user taps afterward.

Both params are read directly from window.location.search and are
no-ops when absent, so the standalone (non-embedded) app and its
existing desktop layout are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-07-30 18:17:32 -04:00
co-authored by Claude Fable 5
parent 91763246c3
commit 900c0b9060
2 changed files with 24 additions and 1 deletions
+14
View File
@@ -477,9 +477,23 @@ function onKeydown(e: KeyboardEvent) {
}
}
// D-14b (Archipelago phase 02-ui-performance): when the host explicitly asks
// for a chat-first mobile start via ?mobileChat, force the initial mobile tab
// to 'chat' on mount. mobileTab already defaults to 'chat', but ChatPage can
// remount while content/detail selection state (module-singleton refs in
// useContentPanel) survives from a previous mount within the same AIUI
// session — this guarantees the documented default regardless of that carry-
// over. It only runs once, at mount, so it never interferes with the
// hasDetailOpen/panelOpen watchers below responding to real user taps after
// the initial paint.
const startOnMobileChat = new URLSearchParams(window.location.search).has('mobileChat')
onMounted(() => {
window.addEventListener('resize', onResize)
window.addEventListener('keydown', onKeydown)
if (startOnMobileChat && isMobile.value) {
mobileTab.value = 'chat'
}
})
onUnmounted(() => {
window.removeEventListener('resize', onResize)
+10 -1
View File
@@ -129,7 +129,16 @@ export const useChatStore = defineStore('chat', () => {
const panelSide = ref<'left' | 'right'>(savedSide ?? 'left')
const webSearchEnabled = ref(localStorage.getItem('aiui-web-search') !== 'false')
const chatCollapsed = ref(localStorage.getItem('aiui-chat-collapsed') !== 'false')
// D-14a (Archipelago phase 02-ui-performance): when the host explicitly asks
// for an expanded start via ?chatExpanded, open in the full message list
// rather than the collapsed prompt-index — this is a presentation-only,
// one-time initial-state override and is never written back to
// localStorage, so it can never change the standalone (non-embedded) app's
// own persisted default. A user who manually collapses while embedded still
// gets that choice persisted for next time, same as before this change.
const _startExpanded = new URLSearchParams(window.location.search).has('chatExpanded')
const chatCollapsed = ref(_startExpanded ? false : localStorage.getItem('aiui-chat-collapsed') !== 'false')
const showHistory = ref(false)
// Load chats: try IndexedDB first, fall back to dev-chats middleware