Add commenter avatars & category colors to comments (v0.0.89)
- Fetch profile avatars for commenters - Apply post category gradient to comment avatars - Add events, friends, market to CATEGORY_CONFIG - Fix first comment race condition with setTimeout Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
0119174969
commit
d051a9337c
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "sociowire-frontend",
|
||||
"private": true,
|
||||
"version": "0.0.88",
|
||||
"version": "0.0.89",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 0.0.0.0",
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ const CATEGORY_CONFIG = {
|
|||
traffic: { icon: "fa-car", gradient: "from-yellow-500 to-amber-500", color: "#fbbf24" },
|
||||
live: { icon: "fa-broadcast-tower", gradient: "from-red-500 to-rose-500", color: "#ef4444" },
|
||||
camera: { icon: "fa-video", gradient: "from-red-500 to-rose-500", color: "#ef4444" },
|
||||
events: { icon: "fa-calendar", gradient: "from-yellow-500 to-orange-500", color: "#eab308" },
|
||||
event: { icon: "fa-calendar", gradient: "from-yellow-500 to-orange-500", color: "#eab308" },
|
||||
friends: { icon: "fa-user-group", gradient: "from-green-500 to-emerald-500", color: "#22c55e" },
|
||||
market: { icon: "fa-store", gradient: "from-amber-500 to-orange-500", color: "#f59e0b" },
|
||||
default: { icon: "fa-newspaper", gradient: "from-blue-500 to-cyan-500", color: "#60a5fa" },
|
||||
};
|
||||
|
||||
|
|
@ -486,6 +490,7 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
const [liked, setLiked] = useState(false);
|
||||
const [truth, setTruth] = useState({ score: 50, count: 0 });
|
||||
const [authorAvatar, setAuthorAvatar] = useState("");
|
||||
const [commenterAvatars, setCommenterAvatars] = useState({});
|
||||
const [comments, setComments] = useState([]);
|
||||
const [commentInput, setCommentInput] = useState("");
|
||||
const [commentSending, setCommentSending] = useState(false);
|
||||
|
|
@ -535,6 +540,22 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
});
|
||||
}, [post?.author, post?.username]);
|
||||
|
||||
// Fetch commenter avatars
|
||||
useEffect(() => {
|
||||
if (!comments.length) return;
|
||||
const usernames = [...new Set(comments.map(c => c.username).filter(Boolean))];
|
||||
// Only fetch for usernames we don't already have
|
||||
const toFetch = usernames.filter(u => !commenterAvatars[u]);
|
||||
if (!toFetch.length) return;
|
||||
toFetch.forEach(username => {
|
||||
fetchProfile(username).then(res => {
|
||||
if (res?.avatar_url) {
|
||||
setCommenterAvatars(prev => ({ ...prev, [username]: res.avatar_url }));
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [comments]);
|
||||
|
||||
// Fetch comments
|
||||
const refreshComments = useCallback(async (autoOpen = false) => {
|
||||
if (!postId) return;
|
||||
|
|
@ -592,8 +613,8 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
} else {
|
||||
setComments(prev => prev.map(c => c.id === tempId ? { ...c, _pending: false } : c));
|
||||
}
|
||||
// Refresh comments to get the real list
|
||||
refreshComments();
|
||||
// Delay refresh to let backend commit
|
||||
setTimeout(() => refreshComments(), 500);
|
||||
} else {
|
||||
setComments(prev => prev.map(c => c.id === tempId ? { ...c, _failed: true, _pending: false } : c));
|
||||
}
|
||||
|
|
@ -874,8 +895,12 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
<motion.div key={c.id} className={`p-3 rounded-xl bg-themed-primary border border-themed ${c._pending ? "opacity-50" : ""} ${c._failed ? "border-red-500/30" : ""}`}
|
||||
initial={{ opacity: 0, y: 10 }} animate={{ opacity: c._pending ? 0.5 : 1, y: 0 }}>
|
||||
<div className="flex items-start gap-2">
|
||||
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-accent to-blue-500 flex items-center justify-center text-white text-xs font-bold flex-shrink-0">
|
||||
{(c.username || "?")[0]?.toUpperCase()}
|
||||
<div className={`w-8 h-8 rounded-full bg-gradient-to-br ${config.gradient} flex items-center justify-center text-white text-xs font-bold flex-shrink-0 overflow-hidden`}>
|
||||
{commenterAvatars[c.username] ? (
|
||||
<img src={commenterAvatars[c.username]} alt={c.username} className="w-full h-full object-cover" />
|
||||
) : (
|
||||
(c.username || "?")[0]?.toUpperCase()
|
||||
)}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-0.5">
|
||||
|
|
|
|||
Loading…
Reference in New Issue