fix(chat): support shared trips and polish controls

This commit is contained in:
2026-03-09 22:04:53 +00:00
parent d8c8ecf2bd
commit c918c9ce2f
27 changed files with 521 additions and 15 deletions

View File

@@ -78,6 +78,7 @@
let selectedPlaceToAdd: PlaceResult | null = null;
let selectedDate = '';
let settingsOpen = false;
let settingsDropdownRef: HTMLDetailsElement;
const dispatch = createEventDispatcher<{
close: void;
@@ -87,10 +88,44 @@
const MODEL_PREFS_STORAGE_KEY = 'voyage_chat_model_prefs';
$: promptTripContext = collectionName || destination || '';
onMount(async () => {
onMount(() => {
void initializeChat();
const handleOutsideSettings = (event: Event) => {
if (!settingsOpen || !settingsDropdownRef) {
return;
}
const target = event.target as Node | null;
if (target && !settingsDropdownRef.contains(target)) {
settingsOpen = false;
}
};
const handleSettingsEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
settingsOpen = false;
}
};
const outsideEvents: Array<keyof DocumentEventMap> = ['pointerdown', 'mousedown', 'touchstart'];
outsideEvents.forEach((eventName) => {
document.addEventListener(eventName, handleOutsideSettings);
});
document.addEventListener('keydown', handleSettingsEscape);
return () => {
outsideEvents.forEach((eventName) => {
document.removeEventListener(eventName, handleOutsideSettings);
});
document.removeEventListener('keydown', handleSettingsEscape);
};
});
async function initializeChat(): Promise<void> {
await Promise.all([loadConversations(), loadProviderCatalog(), loadUserAISettings()]);
await applyInitialDefaults();
});
}
async function loadUserAISettings(): Promise<void> {
try {
@@ -740,7 +775,9 @@
on:click={() => (sidebarOpen = !sidebarOpen)}
aria-controls="chat-conversations-sidebar"
aria-expanded={sidebarOpen}
aria-label={sidebarOpen ? 'Hide conversations' : 'Show conversations'}
aria-label={sidebarOpen
? $t('chat_a11y.hide_conversations_aria')
: $t('chat_a11y.show_conversations_aria')}
>
{#if sidebarOpen}
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
@@ -765,10 +802,14 @@
</div>
</div>
<div class="ml-auto flex items-center gap-2">
<details class="dropdown dropdown-end" bind:open={settingsOpen}>
<details
class="dropdown dropdown-end"
bind:open={settingsOpen}
bind:this={settingsDropdownRef}
>
<summary
class="btn btn-sm btn-ghost"
aria-label="AI settings"
aria-label={$t('chat_a11y.ai_settings_aria')}
aria-expanded={settingsOpen}
>
⚙️

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "عن",
"attributions": "الصفات",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Über",
"close": "Schließen",

View File

@@ -80,6 +80,11 @@
"why_fits": "Why it's a great fit",
"error": "Failed to get suggestions. Please try again."
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "About",
"license": "Licensed under the GPL-3.0 License.",

View File

@@ -31,6 +31,11 @@
"navigation": "Navegación",
"worldtravel": "Viajes por el mundo"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Acerca de",
"license": "Licenciado bajo la Licencia GPL-3.0.",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "À propos",
"close": "Fermer",

View File

@@ -31,6 +31,11 @@
"navigation": "Navigáció",
"worldtravel": "Világutazás"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Névjegy",
"license": "GPL-3.0 licenc alatt terjesztve.",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Di",
"close": "Chiudi",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "について",
"attributions": "帰属",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "소개",
"close": "닫기",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Over",
"close": "Sluiten",

View File

@@ -31,6 +31,11 @@
"navigation": "Navigasjon",
"worldtravel": "Verdensreise"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Om",
"license": "Lisensiert under GPL-3.0-lisensen.",

View File

@@ -31,6 +31,11 @@
"navigation": "Nawigacja",
"worldtravel": "Światowa podróż"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "O aplikacji",
"license": "Licencjonowane na licencji GPL-3.0.",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Sobre",
"attributions": "Atribuições",

View File

@@ -31,6 +31,11 @@
},
"navigation": "Navigație"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Despre",
"license": "Licențiat sub licența GPL-3.0.",

View File

@@ -31,6 +31,11 @@
"navigation": "Навигация",
"worldtravel": "Путешествие по миру"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "О программе",
"license": "Лицензировано под лицензией GPL-3.0.",

View File

@@ -31,6 +31,11 @@
"navigation": "Navigácia",
"worldtravel": "Svetové cestovanie"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "O aplikácii",
"license": "Licencované pod licenciou GPL-3.0.",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Om",
"close": "Stäng",

View File

@@ -31,6 +31,11 @@
"navigation": "Navigasyon",
"worldtravel": "Dünya Seyahati"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "Hakkında",
"license": "GPL-3.0 Lisansı altında lisanslanmıştır.",

View File

@@ -1,4 +1,9 @@
{
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "про",
"attributions": "Атрибуції",

View File

@@ -31,6 +31,11 @@
"navigation": "导航",
"worldtravel": "环球旅行"
},
"chat_a11y": {
"show_conversations_aria": "Show conversations",
"hide_conversations_aria": "Hide conversations",
"ai_settings_aria": "AI settings"
},
"about": {
"about": "关于",
"license": "根据 GPL-3.0 许可证授权。",