Replace getChatWidth utility with chatWidthClasses in chat components

This commit is contained in:
Imad Saddik 2026-01-03 09:10:44 +01:00
parent b6536f6589
commit c9b34bc00d
6 changed files with 43 additions and 52 deletions

View File

@ -7,7 +7,6 @@
ChatFormHelperText,
ChatFormTextarea
} from '$lib/components/app';
import { getChatWidth } from '$lib/utils/chat-width';
import { INPUT_CLASSES } from '$lib/constants/input-classes';
import { SETTING_CONFIG_DEFAULT } from '$lib/constants/settings-config';
import { config } from '$lib/stores/settings.svelte';
@ -15,6 +14,7 @@
import { isRouterMode } from '$lib/stores/server.svelte';
import { chatStore } from '$lib/stores/chat.svelte';
import { activeMessages } from '$lib/stores/conversations.svelte';
import { chatWidthClasses } from '$lib/stores/chat.svelte';
import {
FileTypeCategory,
MimeTypeApplication,
@ -74,10 +74,6 @@
let recordingSupported = $state(false);
let textareaRef: ChatFormTextarea | undefined = $state(undefined);
let widthConfig = $derived(
getChatWidth(currentConfig.autoChatWidth, currentConfig.customChatWidth)
);
// Check if model is selected (in ROUTER mode)
let conversationModel = $derived(
chatStore.getConversationModel(activeMessages() as DatabaseMessage[])
@ -358,7 +354,8 @@
<form
onsubmit={handleSubmit}
class="{INPUT_CLASSES} border-radius-bottom-none mx-auto {widthConfig.class} overflow-hidden rounded-3xl backdrop-blur-md {disabled
class="{INPUT_CLASSES} border-radius-bottom-none mx-auto {chatWidthClasses()
.class} overflow-hidden rounded-3xl backdrop-blur-md {disabled
? 'cursor-not-allowed opacity-60'
: ''} {className}"
data-slot="chat-form"

View File

@ -4,7 +4,7 @@
import { conversationsStore, activeConversation } from '$lib/stores/conversations.svelte';
import { config } from '$lib/stores/settings.svelte';
import { getMessageSiblings } from '$lib/utils';
import { getChatWidth } from '$lib/utils/chat-width';
import { chatWidthClasses } from '$lib/stores/chat.svelte';
interface Props {
class?: string;
@ -17,8 +17,6 @@
let allConversationMessages = $state<DatabaseMessage[]>([]);
const currentConfig = config();
let widthConfig = $derived(getChatWidth(config().autoChatWidth, config().customChatWidth));
function refreshAllMessages() {
const conversation = activeConversation();
@ -131,8 +129,8 @@
<div class="flex h-full flex-col space-y-10 pt-16 md:pt-24 {className}" style="height: auto; ">
{#each displayMessages as { message, siblingInfo } (message.id)}
<ChatMessage
class="mx-auto w-full {widthConfig.class}"
style={widthConfig.style}
class="mx-auto w-full {chatWidthClasses().class}"
style={chatWidthClasses().style}
{message}
{siblingInfo}
onDelete={handleDeleteMessage}

View File

@ -12,7 +12,7 @@
} from '$lib/components/app';
import * as Alert from '$lib/components/ui/alert';
import * as AlertDialog from '$lib/components/ui/alert-dialog';
import { getChatWidth } from '$lib/utils/chat-width';
import { chatWidthClasses } from '$lib/stores/chat.svelte';
import {
AUTO_SCROLL_AT_BOTTOM_THRESHOLD,
AUTO_SCROLL_INTERVAL,
@ -82,8 +82,6 @@
let isCurrentConversationLoading = $derived(isLoading());
let widthConfig = $derived(getChatWidth(config().autoChatWidth, config().customChatWidth));
let isRouter = $derived(isRouterMode());
let conversationModel = $derived(
@ -407,8 +405,8 @@
{#if hasPropsError}
<div
class="pointer-events-auto mx-auto mb-4 {widthConfig.class} px-1"
style={widthConfig.style}
class="pointer-events-auto mx-auto mb-4 {chatWidthClasses().class} px-1"
style={chatWidthClasses().style}
in:fly={{ y: 10, duration: 250 }}
>
<Alert.Root variant="destructive">
@ -456,7 +454,7 @@
ondrop={handleDrop}
role="main"
>
<div class="w-full {widthConfig.class} px-4" style={widthConfig.style}>
<div class="w-full {chatWidthClasses().class} px-4" style={chatWidthClasses().style}>
<div class="mb-10 text-center" in:fade={{ duration: 300 }}>
<h1 class="mb-4 text-3xl font-semibold tracking-tight">llama.cpp</h1>

View File

@ -5,7 +5,7 @@
import { chatStore, isLoading, isChatStreaming } from '$lib/stores/chat.svelte';
import { activeMessages, activeConversation } from '$lib/stores/conversations.svelte';
import { config } from '$lib/stores/settings.svelte';
import { getChatWidth } from '$lib/utils/chat-width';
import { chatWidthClasses } from '$lib/stores/chat.svelte';
const processingState = useProcessingState();
@ -24,8 +24,6 @@
untrack(() => chatStore.setActiveProcessingConversation(conversation?.id ?? null));
});
let widthConfig = $derived(getChatWidth(config().autoChatWidth, config().customChatWidth));
$effect(() => {
const keepStatsVisible = config().keepStatsVisible;
const shouldMonitor = keepStatsVisible || isCurrentConversationLoading || isStreaming;
@ -64,7 +62,10 @@
</script>
<div class="chat-processing-info-container pointer-events-none" class:visible={showProcessingInfo}>
<div class="chat-processing-info-content {widthConfig.class}" style={widthConfig.style}>
<div
class="chat-processing-info-content {chatWidthClasses().class}"
style={chatWidthClasses().style}
>
{#each processingDetails as detail (detail)}
<span class="chat-processing-info-detail pointer-events-auto">{detail}</span>
{/each}

View File

@ -15,6 +15,7 @@ import {
} from '$lib/utils';
import { SvelteMap } from 'svelte/reactivity';
import { DEFAULT_CONTEXT } from '$lib/constants/default-context';
import { AUTO_WIDTH_CLASSES, CUSTOM_WIDTH_PRESETS, DEFAULT_WIDTH } from '$lib/constants/chat-width';
/**
* chatStore - Active AI interaction and streaming state management
@ -77,6 +78,32 @@ class ChatStore {
private isEditModeActive = $state(false);
private addFilesHandler: ((files: File[]) => void) | null = $state(null);
get chatWidthClasses(): { class: string; style?: string } {
const currentConfig = config();
const customChatWidth = currentConfig.customChatWidth;
// Custom width takes priority if set
if (customChatWidth) {
let pixelValue: number | null = null;
if (customChatWidth in CUSTOM_WIDTH_PRESETS) {
const preset = customChatWidth as keyof typeof CUSTOM_WIDTH_PRESETS;
pixelValue = CUSTOM_WIDTH_PRESETS[preset];
} else {
// User typed a number directly instead of selecting a preset
const number = Number(customChatWidth);
if (!isNaN(number) && number > 0) {
pixelValue = number;
}
}
if (pixelValue !== null) {
return { class: '', style: `max-width: ${pixelValue}px` };
}
}
return currentConfig.autoChatWidth ? { class: AUTO_WIDTH_CLASSES } : { class: DEFAULT_WIDTH };
}
// ─────────────────────────────────────────────────────────────────────────────
// Loading State
// ─────────────────────────────────────────────────────────────────────────────
@ -1483,3 +1510,4 @@ export const isEditing = () => chatStore.isEditing();
export const isLoading = () => chatStore.isLoading;
export const setEditModeActive = (handler: (files: File[]) => void) =>
chatStore.setEditModeActive(handler);
export const chatWidthClasses = () => chatStore.chatWidthClasses;

View File

@ -1,31 +0,0 @@
import { AUTO_WIDTH_CLASSES, CUSTOM_WIDTH_PRESETS, DEFAULT_WIDTH } from '$lib/constants/chat-width';
export type CustomWidthPreset = keyof typeof CUSTOM_WIDTH_PRESETS;
/**
* Get the appropriate width configuration based on settings
* @param autoChatWidth - Whether automatic responsive width is enabled
* @param customChatWidth - Custom width setting (preset key or pixel value)
*/
export function getChatWidth(
autoChatWidth: boolean,
customChatWidth: string
): { class: string; style?: string } {
if (autoChatWidth) {
return { class: AUTO_WIDTH_CLASSES };
}
if (customChatWidth) {
if (customChatWidth in CUSTOM_WIDTH_PRESETS) {
const pixelValue = CUSTOM_WIDTH_PRESETS[customChatWidth as CustomWidthPreset];
return { class: '', style: `max-width: ${pixelValue}px` };
}
const numValue = Number(customChatWidth);
if (!isNaN(numValue) && numValue > 0) {
return { class: '', style: `max-width: ${numValue}px` };
}
}
return { class: DEFAULT_WIDTH };
}