fix profile
This commit is contained in:
@ -1,6 +1,36 @@
|
|||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
|
|
||||||
|
// Helper function to get correct web URL based on avatar URL
|
||||||
|
function getCorrectWebUrl(avatarUrl) {
|
||||||
|
if (!avatarUrl) return 'https://bsky.app'
|
||||||
|
|
||||||
|
// If avatar is from bsky.app (main Bluesky), use bsky.app
|
||||||
|
if (avatarUrl.includes('cdn.bsky.app') || avatarUrl.includes('bsky.app')) {
|
||||||
|
return 'https://bsky.app'
|
||||||
|
}
|
||||||
|
|
||||||
|
// If avatar is from syu.is, use web.syu.is
|
||||||
|
if (avatarUrl.includes('bsky.syu.is') || avatarUrl.includes('syu.is')) {
|
||||||
|
return 'https://syu.is'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to bsky.app
|
||||||
|
return 'https://bsky.app'
|
||||||
|
}
|
||||||
|
|
||||||
export default function ChatRecordList({ chatPairs, apiConfig, user = null, agent = null, onRecordDeleted = null }) {
|
export default function ChatRecordList({ chatPairs, apiConfig, user = null, agent = null, onRecordDeleted = null }) {
|
||||||
|
const [expandedRecords, setExpandedRecords] = useState(new Set())
|
||||||
|
|
||||||
|
const toggleJsonView = (key) => {
|
||||||
|
const newExpanded = new Set(expandedRecords)
|
||||||
|
if (newExpanded.has(key)) {
|
||||||
|
newExpanded.delete(key)
|
||||||
|
} else {
|
||||||
|
newExpanded.add(key)
|
||||||
|
}
|
||||||
|
setExpandedRecords(newExpanded)
|
||||||
|
}
|
||||||
|
|
||||||
if (!chatPairs || chatPairs.length === 0) {
|
if (!chatPairs || chatPairs.length === 0) {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
@ -68,10 +98,30 @@ export default function ChatRecordList({ chatPairs, apiConfig, user = null, agen
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="user-info">
|
<div className="user-info">
|
||||||
<div className="display-name">{chatPair.question.value.author?.displayName || chatPair.question.value.author?.handle}</div>
|
<div className="display-name">
|
||||||
|
{chatPair.question.value.author?.displayName || chatPair.question.value.author?.handle}
|
||||||
|
{chatPair.question.value.author?.handle === 'syui' && <span className="admin-badge"> Admin</span>}
|
||||||
|
</div>
|
||||||
|
<div className="handle">
|
||||||
|
<a
|
||||||
|
href={`${getCorrectWebUrl(chatPair.question.value.author?.avatar)}/profile/${chatPair.question.value.author?.did}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="handle-link"
|
||||||
|
>
|
||||||
|
@{chatPair.question.value.author?.handle}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{canDelete(chatPair) && (
|
<div className="record-actions">
|
||||||
<div className="record-actions">
|
<button
|
||||||
|
onClick={() => toggleJsonView(`${chatPair.rkey}-question`)}
|
||||||
|
className={`btn btn-sm ${expandedRecords.has(`${chatPair.rkey}-question`) ? 'btn-outline' : 'btn-primary'}`}
|
||||||
|
title="Show/Hide JSON"
|
||||||
|
>
|
||||||
|
{expandedRecords.has(`${chatPair.rkey}-question`) ? 'hide' : 'json'}
|
||||||
|
</button>
|
||||||
|
{canDelete(chatPair) && (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(chatPair)}
|
onClick={() => handleDelete(chatPair)}
|
||||||
className="btn btn-danger btn-sm"
|
className="btn btn-danger btn-sm"
|
||||||
@ -79,9 +129,16 @@ export default function ChatRecordList({ chatPairs, apiConfig, user = null, agen
|
|||||||
>
|
>
|
||||||
delete
|
delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{expandedRecords.has(`${chatPair.rkey}-question`) && (
|
||||||
|
<div className="json-display">
|
||||||
|
<pre className="json-content">
|
||||||
|
{JSON.stringify(chatPair.question, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="message-content">{chatPair.question.value.text}</div>
|
<div className="message-content">{chatPair.question.value.text}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -102,9 +159,37 @@ export default function ChatRecordList({ chatPairs, apiConfig, user = null, agen
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="user-info">
|
<div className="user-info">
|
||||||
<div className="display-name">{chatPair.answer.value.author?.displayName || chatPair.answer.value.author?.handle}</div>
|
<div className="display-name">
|
||||||
|
{chatPair.answer.value.author?.displayName || chatPair.answer.value.author?.handle}
|
||||||
|
</div>
|
||||||
|
<div className="handle">
|
||||||
|
<a
|
||||||
|
href={`${getCorrectWebUrl(chatPair.answer.value.author?.avatar)}/profile/${chatPair.answer.value.author?.did}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="handle-link"
|
||||||
|
>
|
||||||
|
@{chatPair.answer.value.author?.handle}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="record-actions">
|
||||||
|
<button
|
||||||
|
onClick={() => toggleJsonView(`${chatPair.rkey}-answer`)}
|
||||||
|
className={`btn btn-sm ${expandedRecords.has(`${chatPair.rkey}-answer`) ? 'btn-outline' : 'btn-primary'}`}
|
||||||
|
title="Show/Hide JSON"
|
||||||
|
>
|
||||||
|
{expandedRecords.has(`${chatPair.rkey}-answer`) ? 'hide' : 'json'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{expandedRecords.has(`${chatPair.rkey}-answer`) && (
|
||||||
|
<div className="json-display">
|
||||||
|
<pre className="json-content">
|
||||||
|
{JSON.stringify(chatPair.answer, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="message-content">{chatPair.answer.value.text}</div>
|
<div className="message-content">{chatPair.answer.value.text}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,6 +1,35 @@
|
|||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
|
|
||||||
|
// Helper function to get correct web URL based on avatar URL
|
||||||
|
function getCorrectWebUrl(avatarUrl) {
|
||||||
|
if (!avatarUrl) return 'https://bsky.app'
|
||||||
|
|
||||||
|
// If avatar is from bsky.app (main Bluesky), use bsky.app
|
||||||
|
if (avatarUrl.includes('cdn.bsky.app') || avatarUrl.includes('bsky.app')) {
|
||||||
|
return 'https://bsky.app'
|
||||||
|
}
|
||||||
|
|
||||||
|
// If avatar is from syu.is, use web.syu.is
|
||||||
|
if (avatarUrl.includes('bsky.syu.is') || avatarUrl.includes('syu.is')) {
|
||||||
|
return 'https://syu.is'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to bsky.app
|
||||||
|
return 'https://bsky.app'
|
||||||
|
}
|
||||||
|
|
||||||
export default function ProfileRecordList({ profileRecords, apiConfig, user = null, agent = null, onRecordDeleted = null }) {
|
export default function ProfileRecordList({ profileRecords, apiConfig, user = null, agent = null, onRecordDeleted = null }) {
|
||||||
|
const [expandedRecords, setExpandedRecords] = useState(new Set())
|
||||||
|
|
||||||
|
const toggleJsonView = (uri) => {
|
||||||
|
const newExpanded = new Set(expandedRecords)
|
||||||
|
if (newExpanded.has(uri)) {
|
||||||
|
newExpanded.delete(uri)
|
||||||
|
} else {
|
||||||
|
newExpanded.add(uri)
|
||||||
|
}
|
||||||
|
setExpandedRecords(newExpanded)
|
||||||
|
}
|
||||||
if (!profileRecords || profileRecords.length === 0) {
|
if (!profileRecords || profileRecords.length === 0) {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
@ -62,9 +91,26 @@ export default function ProfileRecordList({ profileRecords, apiConfig, user = nu
|
|||||||
<span className="admin-badge"> Admin</span>
|
<span className="admin-badge"> Admin</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="handle">
|
||||||
|
<a
|
||||||
|
href={`${getCorrectWebUrl(profile.value.author?.avatar)}/profile/${profile.value.author?.did}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="handle-link"
|
||||||
|
>
|
||||||
|
@{profile.value.author?.handle}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{canDelete(profile) && (
|
<div className="record-actions">
|
||||||
<div className="record-actions">
|
<button
|
||||||
|
onClick={() => toggleJsonView(profile.uri)}
|
||||||
|
className={`btn btn-sm ${expandedRecords.has(profile.uri) ? 'btn-outline' : 'btn-primary'}`}
|
||||||
|
title="Show/Hide JSON"
|
||||||
|
>
|
||||||
|
{expandedRecords.has(profile.uri) ? 'hide' : 'json'}
|
||||||
|
</button>
|
||||||
|
{canDelete(profile) && (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(profile)}
|
onClick={() => handleDelete(profile)}
|
||||||
className="btn btn-danger btn-sm"
|
className="btn btn-danger btn-sm"
|
||||||
@ -72,9 +118,16 @@ export default function ProfileRecordList({ profileRecords, apiConfig, user = nu
|
|||||||
>
|
>
|
||||||
delete
|
delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{expandedRecords.has(profile.uri) && (
|
||||||
|
<div className="json-display">
|
||||||
|
<pre className="json-content">
|
||||||
|
{JSON.stringify(profile, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<div className="message-content">{profile.value.text}</div>
|
<div className="message-content">{profile.value.text}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
@ -11,13 +11,18 @@ export default function RecordTabs({ langRecords, commentRecords, userComments,
|
|||||||
logger.log('RecordTabs: activeTab is', activeTab)
|
logger.log('RecordTabs: activeTab is', activeTab)
|
||||||
|
|
||||||
// Filter records based on page context
|
// Filter records based on page context
|
||||||
const filterRecords = (records) => {
|
const filterRecords = (records, isProfile = false) => {
|
||||||
if (pageContext.isTopPage) {
|
if (pageContext.isTopPage) {
|
||||||
// Top page: show latest 3 records
|
// Top page: show latest 3 records
|
||||||
return records.slice(0, 3)
|
return records.slice(0, 3)
|
||||||
} else {
|
} else {
|
||||||
// Individual page: show records matching the URL
|
// Individual page: show records matching the URL
|
||||||
return records.filter(record => {
|
return records.filter(record => {
|
||||||
|
// Profile records should always be shown
|
||||||
|
if (isProfile || record.value?.type === 'profile') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const recordUrl = record.value?.post?.url
|
const recordUrl = record.value?.post?.url
|
||||||
if (!recordUrl) return false
|
if (!recordUrl) return false
|
||||||
|
|
||||||
@ -44,7 +49,7 @@ export default function RecordTabs({ langRecords, commentRecords, userComments,
|
|||||||
if (a.value.profileType !== 'admin' && b.value.profileType === 'admin') return 1
|
if (a.value.profileType !== 'admin' && b.value.profileType === 'admin') return 1
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
const filteredProfileRecords = filterRecords(sortedProfileRecords)
|
const filteredProfileRecords = filterRecords(sortedProfileRecords, true)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="record-tabs">
|
<div className="record-tabs">
|
||||||
|
Reference in New Issue
Block a user