Skip to content

fix: Release 页面空状态图标居中 & 未读筛选标记已读后不立即消失#178

Merged
AmintaCCCP merged 6 commits into
mainfrom
fix/release-page-issues
May 30, 2026
Merged

fix: Release 页面空状态图标居中 & 未读筛选标记已读后不立即消失#178
AmintaCCCP merged 6 commits into
mainfrom
fix/release-page-issues

Conversation

@AmintaCCCP

@AmintaCCCP AmintaCCCP commented May 30, 2026

Copy link
Copy Markdown
Owner

修复内容

1. 空状态图标未居中

图标的 className 中 缺少空格,导致 无法生效,图标贴到了容器左侧。

修复: 补上空格 →

2. 仅未读模式标记已读后列表项立即消失

在未读筛选模式下,点击列表项标记已读后,该项会瞬间从列表中消失,用户无法继续操作。

修复: 引入 快照机制:

  • 切换到仅未读模式时,快照当前未读 release ID
  • 基于快照过滤,而非实时
  • 标记已读后项保持显示,直到刷新页面或重新切换模式时才更新
  • 完成后自动更新快照

Summary by CodeRabbit

  • New Features

    • Persistent release view toggle to switch between "All" and "Unread" releases, restored across sessions.
  • Bug Fixes

    • Stabilized unread filtering so the unread view remains consistent after reads and data refreshes.
    • Fixed empty-state placeholder spacing so the icon displays correctly.

Review Change Stack

…ure removal

1. Fix Package icon not centered in empty state — missing space between
   dark:text-text-secondary and mx-auto caused both classes to be invalid
2. In unread-only filter mode, marking a release as read no longer instantly
   removes it from the list. A snapshot of unread IDs is taken when entering
   unread mode and on refresh; items stay visible until the next page load

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

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

ReleaseTimeline now reads releaseShowMode from the global store and uses a ref snapshot (unreadSnapshotRef) rebuilt from store state to power unread-only filtering; store and types are extended to persist and expose releaseShowMode. A Tailwind spacing typo in the empty-state icon is fixed.

Changes

Unread snapshot filtering & store wiring

Layer / File(s) Summary
Import/useRef and migrate show mode to store
src/components/ReleaseTimeline.tsx
Import useRef; remove local useState for show mode; obtain releaseShowMode and setReleaseShowMode from useAppStore.
unreadSnapshotRef and effect
src/components/ReleaseTimeline.tsx
Add unreadSnapshotRef and a useEffect to compute unread subscribed release IDs from readReleases, honoring releaseSubscriptions and includePreRelease.
Use snapshot in unread-mode filtering
src/components/ReleaseTimeline.tsx
When releaseShowMode === 'unread', filteredReleases filters preUnreadFilteredReleases by membership in unreadSnapshotRef.current and removes readReleases from memo deps.
Empty-state icon CSS correction
src/components/ReleaseTimeline.tsx
Fix missing space in Tailwind class list for the empty-state Package icon.
Persist and expose releaseShowMode
src/store/useAppStore.ts, src/types/index.ts
Extend persisted state to include releaseShowMode; coerce/normalize on hydrate to `'unread'

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hop through stores and stash unread keys,

a tiny ref remembers what I see,
the mode is saved so views stay true and small,
one space is fixed — the icon stands up tall. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title in Chinese addresses both specific issues: fixing empty state icon centering and preventing items from disappearing immediately when marked as read in unread-only filter mode. These changes are clearly reflected in the code modifications (Tailwind className fix and snapshot mechanism for unread releases).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/release-page-issues

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/ReleaseTimeline.tsx (1)

388-399: 💤 Low value

Consider consolidating snapshot update logic.

This inline snapshot creation duplicates the logic in updateUnreadSnapshot. While reading directly from getState() is more robust here (avoids stale closures), having two implementations increases maintenance burden.

After relocating updateUnreadSnapshot (per the earlier fix), consider whether you want to:

  1. Keep the inline approach here (more explicit about fresh state)
  2. Refactor updateUnreadSnapshot to also read from getState() and call it here

Either approach works; this is just a consistency consideration.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ReleaseTimeline.tsx` around lines 388 - 399, The inline
snapshot creation in the ReleaseTimeline component duplicates logic in
updateUnreadSnapshot and should be consolidated: remove the local block that
reads useAppStore.getState(), builds snapshot, and assigns
unreadSnapshotRef.current, and instead call updateUnreadSnapshot() here;
updateUnreadSnapshot should be modified to read fresh state via
useAppStore.getState(), compute the Set of unread release IDs using
releaseSubscriptions and state.readReleases, and assign
unreadSnapshotRef.current so this call preserves the same fresh-state behavior
as the original inline code (referencing releaseShowMode, unreadSnapshotRef,
updateUnreadSnapshot, useAppStore, and releaseSubscriptions).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ReleaseTimeline.tsx`:
- Around line 60-68: updateUnreadSnapshot (the useCallback that reads
subscribedReleases and readReleases and assigns unreadSnapshotRef.current) is
declared before subscribedReleases is defined, causing a TDZ ReferenceError;
relocate the entire declaration of unreadSnapshotRef and updateUnreadSnapshot
(the useRef and the useCallback that references subscribedReleases and
readReleases) to after the subscribedReleases useMemo/definition (i.e., after
the subscribedReleases symbol is created) so the dependency array and the
callback closure reference existing bindings; keep the same logic and
dependencies (subscribedReleases, readReleases) when moving.

---

Nitpick comments:
In `@src/components/ReleaseTimeline.tsx`:
- Around line 388-399: The inline snapshot creation in the ReleaseTimeline
component duplicates logic in updateUnreadSnapshot and should be consolidated:
remove the local block that reads useAppStore.getState(), builds snapshot, and
assigns unreadSnapshotRef.current, and instead call updateUnreadSnapshot() here;
updateUnreadSnapshot should be modified to read fresh state via
useAppStore.getState(), compute the Set of unread release IDs using
releaseSubscriptions and state.readReleases, and assign
unreadSnapshotRef.current so this call preserves the same fresh-state behavior
as the original inline code (referencing releaseShowMode, unreadSnapshotRef,
updateUnreadSnapshot, useAppStore, and releaseSubscriptions).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f72d7f4d-3005-48d0-9cb1-e4458da7453b

📥 Commits

Reviewing files that changed from the base of the PR and between 9aa6c34 and 41f2397.

📒 Files selected for processing (1)
  • src/components/ReleaseTimeline.tsx

Comment thread src/components/ReleaseTimeline.tsx Outdated
AmintaCCCP and others added 3 commits May 30, 2026 14:13
…ogic

1. Move unreadSnapshotRef/updateUnreadSnapshot after subscribedReleases
   definition to avoid temporal dead zone ReferenceError
2. Refactor updateUnreadSnapshot to read readReleases via useAppStore.getState()
   for fresh state access, removing stale closure dependency
3. Replace inline snapshot code in handleRefresh with updateUnreadSnapshot() call

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The snapshot update used a useCallback with stale closure — subscribedReleases
didn't include newly added releases yet when updateUnreadSnapshot() was called
from handleRefresh.

Replace the useCallback + manual call pattern with a useEffect that
automatically rebuilds the snapshot whenever releases, releaseSubscriptions,
includePreRelease, or readReleases change. This ensures the snapshot is always
in sync with the current state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move releaseShowMode from local useState to Zustand store with IndexedDB
persistence, matching the pattern used by releaseViewMode and other
release page settings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AmintaCCCP

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (2)
src/components/ReleaseTimeline.tsx (2)

578-578: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix dark-mode token on the empty-state icon.

tailwind.config defines the color as colors.text-quaternary, which corresponds to the Tailwind utility text-text-quaternary; dark:text-quaternary won’t resolve to that token. Update the icon to use dark:text-text-quaternary.

🎨 Proposed fix
-               <Package className="w-16 h-16 text-gray-500 dark:text-quaternary mx-auto mb-4" />
+               <Package className="w-16 h-16 text-gray-500 dark:text-text-quaternary mx-auto mb-4" />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ReleaseTimeline.tsx` at line 578, The empty-state icon's
dark-mode token is incorrect: update the Package element's className in
ReleaseTimeline (the <Package ... /> JSX) to replace the "dark:text-quaternary"
token with the correct Tailwind token "dark:text-text-quaternary" so it resolves
to colors.text-quaternary in tailwind.config; keep the existing base color
("text-gray-500") and other classes unchanged.

199-266: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Fix unread-mode snapshot so filteredReleases updates after refresh (ReleaseTimeline)

  • unreadSnapshotRef is written in a useEffect, but filteredReleases is a useMemo that reads unreadSnapshotRef.current while its dependency list excludes that snapshot/ref—ref writes won’t trigger recomputation, so refreshed/new unread releases can remain hidden in 'unread' mode until another unrelated dependency changes.
  • The effect depends on readReleases, which conflicts with the snapshot’s intended behavior (“stay visible until refresh/mode-switch”); keep the snapshot driven by refresh-relevant inputs only, and let render updates come from state.
🐛 Proposed fix: store snapshot in state and drop `readReleases` from the deps
- const unreadSnapshotRef = useRef<Set<number>>(new Set());
- useEffect(() => {
-   const state = useAppStore.getState();
-   const ids = new Set<number>();
-   releases.forEach(r => {
-     if (releaseSubscriptions.has(r.repository.id) &&
-         (includePreRelease || !r.prerelease) &&
-         !state.readReleases.has(r.id)) {
-       ids.add(r.id);
-     }
-   });
-   unreadSnapshotRef.current = ids;
- }, [releases, releaseSubscriptions, includePreRelease, readReleases]);
+ const [unreadSnapshot, setUnreadSnapshot] = useState<Set<number>>(new Set());
+ useEffect(() => {
+   const { readReleases: currentRead } = useAppStore.getState();
+   const ids = new Set<number>();
+   releases.forEach(r => {
+     if (releaseSubscriptions.has(r.repository.id) &&
+         (includePreRelease || !r.prerelease) &&
+         !currentRead.has(r.id)) {
+       ids.add(r.id);
+     }
+   });
+   setUnreadSnapshot(ids);
+ }, [releases, releaseSubscriptions, includePreRelease]);
  const filteredReleases = useMemo(() => {
    if (releaseShowMode === 'unread') {
-     return preUnreadFilteredReleases.filter(({ release }) => unreadSnapshotRef.current.has(release.id));
+     return preUnreadFilteredReleases.filter(({ release }) => unreadSnapshot.has(release.id));
    }
    return preUnreadFilteredReleases;
- }, [preUnreadFilteredReleases, releaseShowMode]);
+ }, [preUnreadFilteredReleases, releaseShowMode, unreadSnapshot]);
  • Minor: the empty-state icon uses dark:text-quaternary, but other usages use the configured token dark:text-text-quaternary; align it to dark:text-text-quaternary.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ReleaseTimeline.tsx` around lines 199 - 266, The unread
snapshot currently stored in unreadSnapshotRef is updated inside a useEffect
that depends on readReleases, but filteredReleases (which reads
unreadSnapshotRef.current) won't recompute when the ref changes; fix by storing
the snapshot in React state (e.g. const [unreadSnapshot, setUnreadSnapshot] =
useState<Set<number>>(new Set())) and update it in the effect driven only by
refresh-relevant inputs (releases, releaseSubscriptions, includePreRelease) —
drop readReleases from that effect's dependency list so the snapshot persists
until a refresh/mode switch — then change filteredReleases to read
unreadSnapshot (and include unreadSnapshot in its useMemo deps) instead of
unreadSnapshotRef.current; also normalize the empty-state icon class from
dark:text-quaternary to dark:text-text-quaternary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/ReleaseTimeline.tsx`:
- Line 578: The empty-state icon's dark-mode token is incorrect: update the
Package element's className in ReleaseTimeline (the <Package ... /> JSX) to
replace the "dark:text-quaternary" token with the correct Tailwind token
"dark:text-text-quaternary" so it resolves to colors.text-quaternary in
tailwind.config; keep the existing base color ("text-gray-500") and other
classes unchanged.
- Around line 199-266: The unread snapshot currently stored in unreadSnapshotRef
is updated inside a useEffect that depends on readReleases, but filteredReleases
(which reads unreadSnapshotRef.current) won't recompute when the ref changes;
fix by storing the snapshot in React state (e.g. const [unreadSnapshot,
setUnreadSnapshot] = useState<Set<number>>(new Set())) and update it in the
effect driven only by refresh-relevant inputs (releases, releaseSubscriptions,
includePreRelease) — drop readReleases from that effect's dependency list so the
snapshot persists until a refresh/mode switch — then change filteredReleases to
read unreadSnapshot (and include unreadSnapshot in its useMemo deps) instead of
unreadSnapshotRef.current; also normalize the empty-state icon class from
dark:text-quaternary to dark:text-text-quaternary.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b9657870-2e62-4e1a-9ac4-26776bbf25d8

📥 Commits

Reviewing files that changed from the base of the PR and between 428fa0b and eb0a458.

📒 Files selected for processing (1)
  • src/components/ReleaseTimeline.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/ReleaseTimeline.tsx (1)

198-212: 🏗️ Heavy lift

Snapshot timing may cause new releases to be missing after refresh in "unread" mode.

The useEffect runs after render, but filteredReleases (line 262) runs during render using the snapshot. When releases changes from a refresh:

  1. filteredReleases memo executes with the old snapshot
  2. New unread releases are excluded (not in old snapshot)
  3. Effect updates snapshot post-render, but memo won't re-run

Consider using useMemo (without readReleases in deps) to build the snapshot synchronously during render, and include it in filteredReleases dependencies. This ensures new releases appear immediately while still preserving the "don't disappear on mark-as-read" behavior.

♻️ Suggested refactor using useMemo
- const unreadSnapshotRef = useRef<Set<number>>(new Set());
- useEffect(() => {
-   const state = useAppStore.getState();
-   const ids = new Set<number>();
-   releases.forEach(r => {
-     if (releaseSubscriptions.has(r.repository.id) &&
-         (includePreRelease || !r.prerelease) &&
-         !state.readReleases.has(r.id)) {
-       ids.add(r.id);
-     }
-   });
-   unreadSnapshotRef.current = ids;
- }, [releases, releaseSubscriptions, includePreRelease, readReleases]);
+ // Snapshot rebuilds only on releases/subscription/prerelease changes, NOT on readReleases
+ const unreadSnapshot = useMemo(() => {
+   const state = useAppStore.getState();
+   const ids = new Set<number>();
+   releases.forEach(r => {
+     if (releaseSubscriptions.has(r.repository.id) &&
+         (includePreRelease || !r.prerelease) &&
+         !state.readReleases.has(r.id)) {
+       ids.add(r.id);
+     }
+   });
+   return ids;
+ }, [releases, releaseSubscriptions, includePreRelease]);

Then update filteredReleases to depend on unreadSnapshot:

  const filteredReleases = useMemo(() => {
    if (releaseShowMode === 'unread') {
-     return preUnreadFilteredReleases.filter(({ release }) => unreadSnapshotRef.current.has(release.id));
+     return preUnreadFilteredReleases.filter(({ release }) => unreadSnapshot.has(release.id));
    }
    return preUnreadFilteredReleases;
- }, [preUnreadFilteredReleases, releaseShowMode]);
+ }, [preUnreadFilteredReleases, releaseShowMode, unreadSnapshot]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ReleaseTimeline.tsx` around lines 198 - 212, The unread
snapshot is built in a useEffect (unreadSnapshotRef) which runs after render
causing filteredReleases to run with a stale snapshot and miss new releases;
replace that effect with a useMemo (e.g., const unreadSnapshot = useMemo(() => {
... }, [releases, releaseSubscriptions, includePreRelease])) that synchronously
builds the Set of unread IDs during render (read from useAppStore.getState()
inside the memo) and do NOT include readReleases in the memo deps so
marking-as-read doesn't immediately remove items; then update filteredReleases
to depend on unreadSnapshot instead of unreadSnapshotRef.current and remove the
post-render useEffect.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/store/useAppStore.ts`:
- Line 1271: Add the missing declaration for setReleaseShowMode to the
AppActions interface: declare setReleaseShowMode: (mode: 'all' | 'unread') =>
void; so the implemented action in useAppStore.ts (setReleaseShowMode) matches
the interface and TypeScript consumers like ReleaseTimeline can type-check
against AppActions; update the AppActions interface to include this method
signature.

---

Nitpick comments:
In `@src/components/ReleaseTimeline.tsx`:
- Around line 198-212: The unread snapshot is built in a useEffect
(unreadSnapshotRef) which runs after render causing filteredReleases to run with
a stale snapshot and miss new releases; replace that effect with a useMemo
(e.g., const unreadSnapshot = useMemo(() => { ... }, [releases,
releaseSubscriptions, includePreRelease])) that synchronously builds the Set of
unread IDs during render (read from useAppStore.getState() inside the memo) and
do NOT include readReleases in the memo deps so marking-as-read doesn't
immediately remove items; then update filteredReleases to depend on
unreadSnapshot instead of unreadSnapshotRef.current and remove the post-render
useEffect.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d182d5c-812a-4ca0-bf4a-57d3be995e5a

📥 Commits

Reviewing files that changed from the base of the PR and between eb0a458 and e62d2e2.

📒 Files selected for processing (3)
  • src/components/ReleaseTimeline.tsx
  • src/store/useAppStore.ts
  • src/types/index.ts

Comment thread src/store/useAppStore.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/store/useAppStore.ts (1)

1271-1271: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add missing setReleaseShowMode to AppActions interface.

The action is implemented but not declared in the AppActions interface (lines 82-217). Add the declaration for TypeScript type checking:

setReleaseShowMode: (mode: 'all' | 'unread') => void;

This should be added near line 184, alongside other Release Timeline View actions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/store/useAppStore.ts` at line 1271, The AppActions interface is missing
the declaration for the implemented action setReleaseShowMode; add a method
signature to the AppActions interface: declare setReleaseShowMode(mode: 'all' |
'unread'): void; — place this alongside the other Release Timeline View actions
(near the existing related actions in the AppActions block) so TypeScript
recognizes the implemented setReleaseShowMode function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ReleaseTimeline.tsx`:
- Around line 198-212: The useEffect that builds unreadSnapshotRef currently
lists readReleases in its dependency array causing snapshots to rebuild on
mark-as-read; update the dependency array for the effect that sets
unreadSnapshotRef (the effect referencing releases, releaseSubscriptions,
includePreRelease, unreadSnapshotRef) by removing readReleases and instead
include releaseShowMode so the snapshot is rebuilt when switching display modes
but not when individual releases are marked read.

---

Duplicate comments:
In `@src/store/useAppStore.ts`:
- Line 1271: The AppActions interface is missing the declaration for the
implemented action setReleaseShowMode; add a method signature to the AppActions
interface: declare setReleaseShowMode(mode: 'all' | 'unread'): void; — place
this alongside the other Release Timeline View actions (near the existing
related actions in the AppActions block) so TypeScript recognizes the
implemented setReleaseShowMode function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92cad2a-e20a-4449-9a3b-a56887c98f8c

📥 Commits

Reviewing files that changed from the base of the PR and between 9aa6c34 and e62d2e2.

📒 Files selected for processing (3)
  • src/components/ReleaseTimeline.tsx
  • src/store/useAppStore.ts
  • src/types/index.ts

Comment thread src/components/ReleaseTimeline.tsx Outdated
AmintaCCCP and others added 2 commits May 30, 2026 14:49
1. Replace readReleases with releaseShowMode in useEffect dependency array
   to avoid rebuilding snapshot on mark-as-read (which would defeat the
   purpose of the snapshot); rebuild on mode switch instead
2. Add setReleaseShowMode to AppActions interface for type completeness

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The useEffect updates unreadSnapshotRef but refs don't trigger useMemo
recalculation. Add snapshotVersion state as a bridge: the effect increments
it after updating the ref, and filteredReleases depends on it to recompute.

The effect deliberately excludes readReleases from its dependency array so
that marking an item as read does NOT rebuild the snapshot (preserving the
'items stay visible until next refresh' behavior).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AmintaCCCP AmintaCCCP merged commit e5a6169 into main May 30, 2026
5 checks passed
@AmintaCCCP AmintaCCCP deleted the fix/release-page-issues branch May 30, 2026 07:11
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.

1 participant