Skip to content

fix: docs, preferences, mobile nav#43

Merged
scanash00 merged 8 commits into
paddinglabs:mainfrom
hacdias:misc-fixes
Feb 16, 2026
Merged

fix: docs, preferences, mobile nav#43
scanash00 merged 8 commits into
paddinglabs:mainfrom
hacdias:misc-fixes

Conversation

@hacdias
Copy link
Copy Markdown
Contributor

@hacdias hacdias commented Feb 15, 2026

Summary by CodeRabbit

  • New Features

    • Preference to disable external link warnings.
    • Unread notification count, Annotations menu, and a dedicated Search tab in mobile navigation.
  • Improvements

    • Unified, more reliable feed/profile tab loading with explicit fetched counts and consistent pagination.
    • Mobile and feed UX stability improvements (clearer loading behavior, fewer fallbacks).
  • Documentation

    • Development setup commands updated to use Bun.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Frontend: feed typing/pagination tightened, Profile tab state consolidated, MobileNav adds unread counts and an Annotations item, getFeed return shape changed; README scripts switched from npm to bun. Backend: Firehose ingester persists a new optional Preferences field DisableExternalLinkWarning.

Changes

Cohort / File(s) Summary
Docs
README.md
Switched development commands from npm to bun in Web and Browser Extension setup examples.
Backend — Preferences
backend/internal/firehose/ingester.go
Added optional DisableExternalLinkWarning to parsed Preferences and persisted it into db.Preferences.
Mobile Navigation
web/src/components/navigation/MobileNav.tsx
Added unread notification count state/effect, introduced Annotations menu item, adjusted bottom-nav route to /url, and updated auth-aware rendering and icons.
API client / Types
web/src/api/client.ts, web/src/types.ts
Removed cursor from FeedResponse and getFeed return; promoted hasMore and fetchedCount to required fields; getFeed maps normalizedItems as AnnotationItem[]; added LabelerInfo import.
Feed UI
web/src/components/feed/MasonryFeed.tsx, web/src/views/core/Feed.tsx
Feed consumers now use data.items and required data.hasMore/data.fetchedCount; simplified initial fetch and loadMore logic; import adjustments (useStore, Loader2).
Profile view refactor
web/src/views/profile/Profile.tsx
Consolidated per-tab arrays into a single items object, added motivationMap for tab-specific queries, unified pagination/reset/loadMore logic across tabs.
Minor formatting
web/src/lib/og.ts, web/src/pages/og-image.ts
Non-semantic formatting changes only (line reflows).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I swapped npm for bun with cheer,
Tabs now hum and feeds appear,
A tiny flag tucked in the stream,
Annotations hop into the team,
Carrots coded, bright and near 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title addresses three distinct areas of the codebase (docs, preferences, mobile nav) but lacks specificity about the primary change; it reads as a shorthand list rather than highlighting the main objective. Consider a more descriptive title that emphasizes the primary change, such as 'Update docs to use bun, add mobile Annotations link' or focus on the most significant change if one exists.
✅ Passed checks (2 passed)
Check name Status Explanation
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/components/navigation/MobileNav.tsx (1)

36-42: ⚠️ Potential issue | 🟠 Major

Add cleanup guard to prevent state updates after unmount or auth change.

The effect can resolve after unmount or when isAuthenticated flips, causing a stale setUnreadCount. Use a cleanup guard to check if the component is still active before updating state (established pattern in MasonryFeed.tsx):

♻️ Suggested fix
 useEffect(() => {
+  let active = true;
   if (isAuthenticated) {
     getUnreadNotificationCount()
       .then((count) => {
+        if (active) setUnreadCount(count || 0);
-        setUnreadCount(count || 0);
       })
       .catch(() => {});
   }
+  return () => {
+    active = false;
+  };
 }, [isAuthenticated]);

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/views/profile/Profile.tsx (1)

266-309: ⚠️ Potential issue | 🟠 Major

Early return leaves loadingMore stuck at true.

When capturedTab === "collections", the function returns on line 278 after setLoadingMore(true) was called on line 275. The finally block that resets setLoadingMore(false) is never executed, leaving the loading state permanently true for subsequent renders.

Suggested fix: Move early return before setting loading state
 const loadMore = useCallback(async () => {
   const isHandle = !did.startsWith("did:");
   const resolvedDid = isHandle ? profile?.did : did;
   if (!resolvedDid) return;

   const tabPagination = pagination[activeTab];
   if (!tabPagination) return;

   const capturedTab = activeTab;
+
+  if (capturedTab === "collections") return;
+
   setLoadingMore(true);
   setLoadMoreError(null);
-
-  if (capturedTab === "collections") return;
-
   try {
🧹 Nitpick comments (2)
web/src/components/feed/MasonryFeed.tsx (1)

1-1: Remove redundant import alias.

useStore is imported twice—once as useNanoStore and once directly. Since both reference the same function, pick one and use it consistently throughout the component (lines 125-126 currently mix both).

Suggested fix
-import { useStore as useNanoStore, useStore } from "@nanostores/react";
+import { useStore } from "@nanostores/react";

Then update line 126:

-  const layout = useNanoStore($feedLayout);
+  const layout = useStore($feedLayout);
web/src/views/core/Feed.tsx (1)

73-96: Inconsistent null-safety handling in loadMore.

Lines 83 and 85 use optional chaining (data?.items, data?.hasMore) defensively, but line 90 directly accesses data.fetchedCount. Since getFeed guarantees a complete FeedResponse in all paths, the optional chaining is unnecessary. Consider aligning the approach for consistency.

Option A: Trust the types (recommended)
     const data = await getFeed({
       type,
       motivation,
       tag,
       limit: LIMIT,
       offset,
     });
-    const fetched = data?.items || [];
+    const fetched = data.items;
     setItems((prev) => [...prev, ...fetched]);
-    if (data?.hasMore !== undefined) {
-      setHasMore(data.hasMore);
-    } else {
-      setHasMore(fetched.length >= LIMIT);
-    }
+    setHasMore(data.hasMore);
     setOffset((prev) => prev + data.fetchedCount);
Option B: Be consistently defensive
     setOffset((prev) => prev + data.fetchedCount);
+    setOffset((prev) => prev + (data?.fetchedCount ?? fetched.length));

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@web/src/views/profile/Profile.tsx`:
- Around line 275-278: The early-return for the collections tab leaks state
because setLoadingMore(true) and setLoadMoreError(null) run before returning;
modify the loadMore handler (the function containing setLoadingMore and
setLoadMoreError and the capturedTab/activeTab check) so the capturedTab ===
"collections" check runs before any state updates, or alternatively ensure
loadingMore is reset in the finally path; update references to setLoadingMore,
setLoadMoreError, and the capturedTab/activeTab check accordingly to prevent
leaving loadingMore stuck true.
🧹 Nitpick comments (1)
web/src/views/profile/Profile.tsx (1)

434-435: Variable shadowing: local items shadows component state.

The local variable items shadows the component-level items state. While functionally correct due to different scopes, this can cause confusion during maintenance.

♻️ Suggested rename
                   <MoreMenu
                     items={(() => {
-                      const items: MoreMenuItem[] = [];
-                      items.push({
+                      const menuItems: MoreMenuItem[] = [];
+                      menuItems.push({

Apply the same rename to all subsequent items.push(...) calls within this callback.

Comment thread web/src/views/profile/Profile.tsx Outdated
@scanash00 scanash00 merged commit de7bd9d into paddinglabs:main Feb 16, 2026
1 check passed
@hacdias hacdias deleted the misc-fixes branch February 16, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants