Revamp chat UI and add V2 encrypted messaging support

Major update to chat page with new conversation list, message thread view, and support for V2 end-to-end encrypted messaging using DIDs. Adds chat lock state, message sending, conversation deletion, and improved polling. Updates user API and types to include DID and chatPublicKey. Fixes race conditions in feed loading, adds message button to user profile, and improves crypto and identity hooks for better locked/unlocked state detection.
This commit is contained in:
Christopher
2026-01-27 18:33:56 -08:00
parent 9ee0cbbb9a
commit f59625c83f
8 changed files with 626 additions and 216 deletions
+16 -2
View File
@@ -50,6 +50,12 @@ export default function Home() {
}
}, [user, router]);
const feedTypeRef = useRef(feedType);
useEffect(() => {
feedTypeRef.current = feedType;
}, [feedType]);
const loadFeed = async (type: 'following' | 'curated', cursor?: string | null) => {
if (cursor) {
setLoadingMore(true);
@@ -60,9 +66,13 @@ export default function Home() {
const endpoint = type === 'curated'
? `/api/posts?type=curated${cursor ? `&cursor=${cursor}` : ''}`
: `/api/posts?type=home${cursor ? `&cursor=${cursor}` : ''}`;
const res = await fetch(endpoint);
const data = await res.json();
// Race condition check: ignore if user switched tabs
if (type !== feedTypeRef.current) return;
if (cursor) {
setPosts(prev => [...prev, ...(data.posts || [])]);
} else {
@@ -71,14 +81,18 @@ export default function Home() {
setFeedMeta(data.meta || null);
setNextCursor(data.nextCursor || null);
} catch {
if (type !== feedTypeRef.current) return;
if (!cursor) {
setPosts([]);
}
setFeedMeta(null);
setNextCursor(null);
} finally {
setLoading(false);
setLoadingMore(false);
if (type === feedTypeRef.current) {
setLoading(false);
setLoadingMore(false);
}
}
};