fix ask-ai put

This commit is contained in:
2025-06-19 19:52:31 +09:00
parent 5ce0e0fd7a
commit 004081337c
5 changed files with 359 additions and 31 deletions

View File

@ -0,0 +1,133 @@
import React from 'react'
export default function ChatRecordList({ chatPairs, apiConfig, user = null, agent = null, onRecordDeleted = null }) {
if (!chatPairs || chatPairs.length === 0) {
return (
<section>
<p>チャット履歴がありません</p>
</section>
)
}
const handleDelete = async (chatPair) => {
if (!user || !agent || !chatPair.question?.uri) return
const confirmed = window.confirm('この会話を削除しますか?')
if (!confirmed) return
try {
// Delete question record
if (chatPair.question?.uri) {
const questionUriParts = chatPair.question.uri.split('/')
await agent.api.com.atproto.repo.deleteRecord({
repo: questionUriParts[2],
collection: questionUriParts[3],
rkey: questionUriParts[4]
})
}
// Delete answer record if exists
if (chatPair.answer?.uri) {
const answerUriParts = chatPair.answer.uri.split('/')
await agent.api.com.atproto.repo.deleteRecord({
repo: answerUriParts[2],
collection: answerUriParts[3],
rkey: answerUriParts[4]
})
}
if (onRecordDeleted) {
onRecordDeleted()
}
} catch (error) {
alert(`削除に失敗しました: ${error.message}`)
}
}
const canDelete = (chatPair) => {
return user && agent && chatPair.question?.uri && chatPair.question.value.author?.did === user.did
}
return (
<section>
{chatPairs.map((chatPair, i) => (
<div key={chatPair.rkey} className="chat-conversation">
{/* Question */}
{chatPair.question && (
<div className="chat-message user-message comment-style">
<div className="message-header">
{chatPair.question.value.author?.avatar ? (
<img
src={chatPair.question.value.author.avatar}
alt={`${chatPair.question.value.author.displayName || chatPair.question.value.author.handle} avatar`}
className="avatar"
/>
) : (
<div className="avatar">
{(chatPair.question.value.author?.displayName || chatPair.question.value.author?.handle || '?').charAt(0).toUpperCase()}
</div>
)}
<div className="user-info">
<div className="display-name">{chatPair.question.value.author?.displayName || chatPair.question.value.author?.handle}</div>
<div className="handle">@{chatPair.question.value.author?.handle}</div>
<div className="timestamp">{new Date(chatPair.question.value.createdAt).toLocaleString()}</div>
</div>
{canDelete(chatPair) && (
<div className="record-actions">
<button
onClick={() => handleDelete(chatPair)}
className="btn btn-danger btn-sm"
title="Delete Conversation"
>
delete
</button>
</div>
)}
</div>
<div className="message-content">{chatPair.question.value.text}</div>
</div>
)}
{/* Answer */}
{chatPair.answer && (
<div className="chat-message ai-message comment-style">
<div className="message-header">
{chatPair.answer.value.author?.avatar ? (
<img
src={chatPair.answer.value.author.avatar}
alt={`${chatPair.answer.value.author.displayName || chatPair.answer.value.author.handle} avatar`}
className="avatar"
/>
) : (
<div className="avatar">
{(chatPair.answer.value.author?.displayName || chatPair.answer.value.author?.handle || 'AI').charAt(0).toUpperCase()}
</div>
)}
<div className="user-info">
<div className="display-name">{chatPair.answer.value.author?.displayName || chatPair.answer.value.author?.handle}</div>
<div className="handle">@{chatPair.answer.value.author?.handle}</div>
<div className="timestamp">{new Date(chatPair.answer.value.createdAt).toLocaleString()}</div>
</div>
</div>
<div className="message-content">{chatPair.answer.value.text}</div>
</div>
)}
{/* Post metadata */}
{chatPair.question?.value.post?.url && (
<div className="record-meta">
<a
href={chatPair.question.value.post.url}
target="_blank"
rel="noopener noreferrer"
className="record-url"
>
{chatPair.question.value.post.url}
</a>
</div>
)}
</div>
))}
</section>
)
}

View File

@ -1,8 +1,9 @@
import React, { useState } from 'react'
import RecordList from './RecordList.jsx'
import ChatRecordList from './ChatRecordList.jsx'
import LoadingSkeleton from './LoadingSkeleton.jsx'
export default function RecordTabs({ langRecords, commentRecords, userComments, chatRecords, baseRecords, apiConfig, pageContext, user = null, agent = null, onRecordDeleted = null }) {
export default function RecordTabs({ langRecords, commentRecords, userComments, chatRecords, userChatRecords, userChatLoading, baseRecords, apiConfig, pageContext, user = null, agent = null, onRecordDeleted = null }) {
const [activeTab, setActiveTab] = useState('lang')
// Filter records based on page context
@ -51,7 +52,7 @@ export default function RecordTabs({ langRecords, commentRecords, userComments,
className={`tab-btn ${activeTab === 'collection' ? 'active' : ''}`}
onClick={() => setActiveTab('collection')}
>
Posts ({filteredBaseRecords.length})
Posts ({userChatRecords?.length || 0})
</button>
<button
className={`tab-btn ${activeTab === 'users' ? 'active' : ''}`}
@ -93,17 +94,15 @@ export default function RecordTabs({ langRecords, commentRecords, userComments,
)
)}
{activeTab === 'collection' && (
!baseRecords ? (
userChatLoading ? (
<LoadingSkeleton count={2} showTitle={true} />
) : (
<RecordList
title=""
records={filteredBaseRecords}
<ChatRecordList
chatPairs={userChatRecords}
apiConfig={apiConfig}
user={user}
agent={agent}
onRecordDeleted={onRecordDeleted}
showTitle={false}
/>
)
)}