Repository: ggml-org/llama.cpp
Pull request: Show message actions by default

Close #16155

This PR updates the message UI to always show message actions, where previously we had it shown only on hover.

Changed files:
filename: tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageActions.svelte
patch: @@ -4,7 +4,6 @@
 	import ChatMessageBranchingControls from './ChatMessageBranchingControls.svelte';
 
 	interface Props {
-		message: DatabaseMessage;
 		role: 'user' | 'assistant';
 		justify: 'start' | 'end';
 		actionsPosition: 'left' | 'right';
@@ -29,7 +28,6 @@
 		actionsPosition,
 		deletionInfo,
 		justify,
-		message,
 		onCopy,
 		onEdit,
 		onConfirmDelete,
@@ -49,26 +47,17 @@
 </script>
 
 <div class="relative {justify === 'start' ? 'mt-2' : ''} flex h-6 items-center justify-{justify}">
-	<div
-		class="hidden items-center text-xs text-muted-foreground transition-opacity md:flex md:group-hover:opacity-0"
-	>
-		{new Date(message.timestamp).toLocaleTimeString(undefined, {
-			hour: '2-digit',
-			minute: '2-digit'
-		})}
-	</div>
-
 	<div
 		class="absolute top-0 {actionsPosition === 'left'
 			? 'left-0'
-			: 'right-0'} flex items-center gap-2 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100"
+			: 'right-0'} flex items-center gap-2 opacity-100 transition-opacity"
 	>
 		{#if siblingInfo && siblingInfo.totalSiblings > 1}
 			<ChatMessageBranchingControls {siblingInfo} {onNavigateToSibling} />
 		{/if}
 
 		<div
-			class="pointer-events-auto inset-0 flex items-center gap-1 opacity-100 transition-all duration-150 md:pointer-events-none md:opacity-0 md:group-hover:pointer-events-auto md:group-hover:opacity-100"
+			class="pointer-events-auto inset-0 flex items-center gap-1 opacity-100 transition-all duration-150"
 		>
 			<ActionButton icon={Copy} tooltip="Copy" onclick={onCopy} />
 

filename: tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte
patch: @@ -138,7 +138,6 @@
 
 	{#if message.timestamp && !isEditing}
 		<ChatMessageActions
-			{message}
 			role="assistant"
 			justify="start"
 			actionsPosition="left"

filename: tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageUser.svelte
patch: @@ -135,7 +135,6 @@
 					actionsPosition="right"
 					{deletionInfo}
 					justify="end"
-					{message}
 					{onConfirmDelete}
 					{onCopy}
 					{onDelete}

filename: tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsDialog.svelte
patch: @@ -456,7 +456,6 @@
 								{localConfig}
 								onConfigChange={handleConfigChange}
 								onThemeChange={handleThemeChange}
-								isMobile={false}
 							/>
 						</div>
 					</div>

filename: tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettingsFields.svelte
patch: @@ -5,6 +5,7 @@
 	import * as Select from '$lib/components/ui/select';
 	import { Textarea } from '$lib/components/ui/textarea';
 	import { SETTING_CONFIG_DEFAULT, SETTING_CONFIG_INFO } from '$lib/constants/settings-config';
+	import { IsMobile } from '$lib/hooks/is-mobile.svelte';
 	import { supportsVision } from '$lib/stores/server.svelte';
 	import type { Component } from 'svelte';
 
@@ -13,10 +14,11 @@
 		localConfig: SettingsConfigType;
 		onConfigChange: (key: string, value: string | boolean) => void;
 		onThemeChange?: (theme: string) => void;
-		isMobile?: boolean;
 	}
 
-	let { fields, localConfig, onConfigChange, onThemeChange, isMobile = false }: Props = $props();
+	let { fields, localConfig, onConfigChange, onThemeChange }: Props = $props();
+
+	let isMobile = $state(new IsMobile());
 </script>
 
 {#each fields as field (field.key)}
@@ -109,6 +111,7 @@
 			{/if}
 		{:else if field.type === 'checkbox'}
 			{@const isDisabled = field.key === 'pdfAsImage' && !supportsVision()}
+
 			<div class="flex items-start space-x-3">
 				<Checkbox
 					id={field.key}