fix oauth package name
This commit is contained in:
137
oauth/src/components/RecordList.jsx
Normal file
137
oauth/src/components/RecordList.jsx
Normal file
@ -0,0 +1,137 @@
|
||||
import React, { useState } from 'react'
|
||||
import AvatarImage from './AvatarImage.jsx'
|
||||
import Avatar from './Avatar.jsx'
|
||||
|
||||
export default function RecordList({ title, records, apiConfig, showTitle = true, user = null, agent = null, onRecordDeleted = null }) {
|
||||
const [expandedRecords, setExpandedRecords] = useState(new Set())
|
||||
const [deletingRecords, setDeletingRecords] = useState(new Set())
|
||||
|
||||
const toggleJsonView = (index) => {
|
||||
const newExpanded = new Set(expandedRecords)
|
||||
if (newExpanded.has(index)) {
|
||||
newExpanded.delete(index)
|
||||
} else {
|
||||
newExpanded.add(index)
|
||||
}
|
||||
setExpandedRecords(newExpanded)
|
||||
}
|
||||
|
||||
const handleDelete = async (record, index) => {
|
||||
if (!user || !agent || !record.uri) return
|
||||
|
||||
const confirmed = window.confirm('このレコードを削除しますか?')
|
||||
if (!confirmed) return
|
||||
|
||||
setDeletingRecords(prev => new Set([...prev, index]))
|
||||
|
||||
try {
|
||||
// Extract repo, collection, rkey from URI
|
||||
const uriParts = record.uri.split('/')
|
||||
const repo = uriParts[2]
|
||||
const collection = uriParts[3]
|
||||
const rkey = uriParts[4]
|
||||
|
||||
await agent.com.atproto.repo.deleteRecord({
|
||||
repo: repo,
|
||||
collection: collection,
|
||||
rkey: rkey
|
||||
})
|
||||
|
||||
if (onRecordDeleted) {
|
||||
onRecordDeleted()
|
||||
}
|
||||
} catch (error) {
|
||||
alert(`削除に失敗しました: ${error.message}`)
|
||||
} finally {
|
||||
setDeletingRecords(prev => {
|
||||
const newSet = new Set(prev)
|
||||
newSet.delete(index)
|
||||
return newSet
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const canDelete = (record) => {
|
||||
return user && agent && record.uri && record.value.author?.did === user.did
|
||||
}
|
||||
if (!records || records.length === 0) {
|
||||
return (
|
||||
<section>
|
||||
{showTitle && <h3>{title} (0)</h3>}
|
||||
<p>レコードがありません</p>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
{showTitle && <h3>{title} ({records.length})</h3>}
|
||||
{records.map((record, i) => (
|
||||
<div key={i} className="record-item">
|
||||
<div className="record-header">
|
||||
<AvatarImage record={record} size={40} />
|
||||
<div className="user-info">
|
||||
<div className="display-name">{record.value.author?.displayName || record.value.author?.handle}</div>
|
||||
<div className="handle">
|
||||
<a
|
||||
href={`${apiConfig?.web || 'https://bsky.app'}/profile/${record.value.author?.did}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="handle-link"
|
||||
>
|
||||
@{record.value.author?.handle}
|
||||
</a>
|
||||
</div>
|
||||
<div className="timestamp">{new Date(record.value.createdAt).toLocaleString()}</div>
|
||||
</div>
|
||||
|
||||
<div className="record-actions">
|
||||
<button
|
||||
onClick={() => toggleJsonView(i)}
|
||||
className={`btn btn-sm ${expandedRecords.has(i) ? 'btn-outline' : 'btn-primary'}`}
|
||||
title="Show/Hide JSON"
|
||||
>
|
||||
{expandedRecords.has(i) ? 'hide' : 'json'}
|
||||
</button>
|
||||
|
||||
{canDelete(record) && (
|
||||
<button
|
||||
onClick={() => handleDelete(record, i)}
|
||||
disabled={deletingRecords.has(i)}
|
||||
className="btn btn-danger btn-sm"
|
||||
title="Delete Record"
|
||||
>
|
||||
{deletingRecords.has(i) ? 'deleting...' : 'delete'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{expandedRecords.has(i) && (
|
||||
<div className="json-display">
|
||||
<div className="json-header">json data</div>
|
||||
<pre className="json-content">
|
||||
{JSON.stringify(record, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="record-content">{record.value.text || record.value.content}</div>
|
||||
|
||||
<div className="record-meta">
|
||||
{record.value.post?.url && (
|
||||
<a
|
||||
href={record.value.post.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="record-url"
|
||||
>
|
||||
{record.value.post.url}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user