feat(chat): add response feedback thumbs up/down (M9.5)
Thumbs up/down buttons on assistant messages (hover action bar). Feedback stored per message, persisted in IDB, included in conversation exports. Toggle to clear feedback. Color-coded: green for up, red for down. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d595996866
commit
210fa7d3c6
@@ -43,6 +43,25 @@
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M5 3a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2V5a2 2 0 00-2-2H5zM5 11a2 2 0 00-2 2v2a2 2 0 002 2h2a2 2 0 002-2v-2a2 2 0 00-2-2H5zM11 5a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V5z" clip-rule="evenodd" /></svg>
|
||||
</button>
|
||||
<!-- Feedback thumbs -->
|
||||
<button
|
||||
v-if="!isUser"
|
||||
class="glass-button-sm !h-7 !min-h-0 !w-7 !min-w-0 !px-0 flex items-center justify-center transition-colors"
|
||||
:class="message.feedback === 'up' ? 'text-green-400' : 'text-white/60 hover:text-green-400/80'"
|
||||
title="Good response"
|
||||
@click.stop="toggleFeedback('up')"
|
||||
>
|
||||
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20"><path d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" /></svg>
|
||||
</button>
|
||||
<button
|
||||
v-if="!isUser"
|
||||
class="glass-button-sm !h-7 !min-h-0 !w-7 !min-w-0 !px-0 flex items-center justify-center transition-colors"
|
||||
:class="message.feedback === 'down' ? 'text-red-400' : 'text-white/60 hover:text-red-400/80'"
|
||||
title="Poor response"
|
||||
@click.stop="toggleFeedback('down')"
|
||||
>
|
||||
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20"><path d="M18 9.5a1.5 1.5 0 11-3 0v-6a1.5 1.5 0 013 0v6zM14 9.667v-5.43a2 2 0 00-1.106-1.79l-.05-.025A4 4 0 0011.057 2H5.64a2 2 0 00-1.962 1.608l-1.2 6A2 2 0 004.44 12H8v4a2 2 0 002 2 1 1 0 001-1v-.667a4 4 0 01.8-2.4l1.4-1.866a4 4 0 00.8-2.4z" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -305,8 +324,14 @@ const emit = defineEmits<{
|
||||
regenerate: []
|
||||
branch: [messageId: string]
|
||||
reply: [messageId: string, content: string]
|
||||
feedback: [messageId: string, value: 'up' | 'down' | undefined]
|
||||
}>()
|
||||
|
||||
function toggleFeedback(value: 'up' | 'down') {
|
||||
const newValue = props.message.feedback === value ? undefined : value
|
||||
emit('feedback', props.message.id, newValue)
|
||||
}
|
||||
|
||||
// Editing state
|
||||
const isEditing = ref(false)
|
||||
const editContent = ref('')
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
@regenerate="handleRegenerate"
|
||||
@branch="handleBranch"
|
||||
@reply="handleReply"
|
||||
@feedback="handleFeedback"
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
@@ -249,6 +250,12 @@ function handleBranch(messageId: string) {
|
||||
chatStore.branchFromMessage(convId, messageId)
|
||||
}
|
||||
|
||||
function handleFeedback(messageId: string, value: 'up' | 'down' | undefined) {
|
||||
const convId = chatStore.activeConversationId
|
||||
if (!convId) return
|
||||
chatStore.setMessageFeedback(convId, messageId, value)
|
||||
}
|
||||
|
||||
function handleExtract(text: string) {
|
||||
// Run content extraction without sending to AI
|
||||
const convId = chatStore.activeConversationId ?? chatStore.createConversation()
|
||||
|
||||
@@ -222,6 +222,16 @@ export const useChatStore = defineStore('chat', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function setMessageFeedback(conversationId: string, messageId: string, feedback: 'up' | 'down' | undefined) {
|
||||
const conv = conversations.value.get(conversationId)
|
||||
if (!conv) return
|
||||
const msg = conv.messages.find((m: { id: string }) => m.id === messageId)
|
||||
if (msg) {
|
||||
msg.feedback = feedback
|
||||
debouncedIDBSave(conv)
|
||||
}
|
||||
}
|
||||
|
||||
function switchSide() {
|
||||
panelSide.value = panelSide.value === 'right' ? 'left' : 'right'
|
||||
}
|
||||
@@ -348,6 +358,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
addMessage,
|
||||
appendToLastMessage,
|
||||
setMessageWebResults,
|
||||
setMessageFeedback,
|
||||
switchSide,
|
||||
toggleChatCollapse,
|
||||
setActiveConversation,
|
||||
|
||||
@@ -32,6 +32,8 @@ export interface Message {
|
||||
editedAt?: number
|
||||
/** Attached images (base64, max 4) for vision-capable models */
|
||||
images?: ImageAttachment[]
|
||||
/** User feedback: 'up' = thumbs up, 'down' = thumbs down */
|
||||
feedback?: 'up' | 'down'
|
||||
}
|
||||
|
||||
export interface Reaction {
|
||||
|
||||
Reference in New Issue
Block a user