More reliable deep-link navigation with improved error handling and cleanup.
Status filter query parameter is now consistently preserved when switching views.
New Features
Unified pagination for stream lists, providing more consistent “load more” behavior and smoother loading across filters.
- **paginate for open and closed streams**
- **fix: add platform abstraction for deeplink (#251)**
- **cleanup**
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
* **Bug Fixes**
* More reliable deep-link navigation with improved error handling and cleanup.
* Status filter query parameter is now consistently preserved when switching views.
* **New Features**
* Unified pagination for stream lists, providing more consistent “load more” behavior and smoother loading across filters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 4ab5069d-93dd-41b7-9c58-fcb43e4241c4
📥 Commits
Reviewing files that changed from the base of the PR and between 0604b260d2 and 89d78246d3.
📒 Files selected for processing (1)
js/desktop/src/App.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
js/desktop/src/App.tsx
📝 Walkthrough
Walkthrough
Adds a portable platform.deepLink API (getPending, onNavigate) with Electron and web implementations; App uses it to fetch pending deep links and subscribe to navigation with error logging. Unifies stream pagination to a single limit state for both statuses. NetworkRoot now always writes the status query parameter.
Platform interface extended with deepLink capability providing getPending(): Promise<string | null> and onNavigate(callback): () => void.
Platform implementations for deepLink js/desktop/src/lib/platform/electron.ts, js/desktop/src/lib/platform/web.ts
Electron wires getPending and onNavigate to window.electronDeepLink methods; web implementation stubs getPending to resolve null and onNavigate to return a no-op unsubscribe.
Deep-link navigation listener via platform abstraction js/desktop/src/App.tsx
DeepLinkNavigationListener now calls platform.deepLink.getPending() and navigates only when a path exists, logs errors via logError, and subscribes via platform.deepLink.onNavigate() with cleanup.
Stream pagination refactoring to unified limit model js/desktop/src/hooks/use-stream-particles.ts
Replaces closed-tab-specific pagination constants and gating with shared INITIAL_PAGE_SIZE / PAGE_INCREMENT and a single limit state; canLoadMore uses streams.length >= limit and loadMore increments limit.
Network status tab query parameter handling js/desktop/src/features/network-root.tsx
setStatusTab now always sets the status query parameter (including open) instead of deleting it; two inline layout comments were removed.
Sequence Diagram
sequenceDiagram
participant App as App (DeepLinkNavigationListener)
participant Platform as platform.deepLink
participant Electron as window.electronDeepLink
App->>Platform: getPending()
Platform->>Electron: getPending()
Electron-->>Platform: Promise<string|null>
Platform-->>App: pending path or null
alt pending path exists
App->>App: navigate(pendingPath)
end
App->>Platform: onNavigate(callback)
Platform->>Electron: onNavigate(callback)
Electron-->>Platform: unsubscribe function
Platform-->>App: unsubscribe function
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
flowy-live/llink#251: Modifies deep-link flow in App.tsx and related platform API usage; overlaps with the platform.deepLink consumption.
flowy-live/llink#246: Adds Electron-side electronDeepLink IPC/preload/main routing that complements the renderer changes in this PR.
Poem
🐰 I hopped between platforms, brave and spry,
Deep-links now whisper where they lie.
Streams stretch longer with a single goal,
Query strings set, the route feels whole. 🥕✨
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name
Status
Explanation
Resolution
Docstring Coverage
⚠️ Warning
Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.
Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name
Status
Explanation
Description Check
✅ Passed
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
✅ Passed
The title 'paginate open streams' directly describes the main feature added in this PR—unified pagination for both open and closed streams via the use-stream-particles hook refactor.
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 docstrings
Create stacked PR
Commit on current branch
🧪 Generate unit tests (beta)
Create PR with unit tests
Commit unit tests in branch paginate-open-streams
Comment @coderabbitai help to get the list of available commands and usage tips.
<!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/flowy-live/llink/pull/252?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
No actionable comments were generated in the recent review. 🎉
<details>
<summary>ℹ️ Recent review info</summary>
<details>
<summary>⚙️ Run configuration</summary>
**Configuration used**: defaults
**Review profile**: CHILL
**Plan**: Pro Plus
**Run ID**: `4ab5069d-93dd-41b7-9c58-fcb43e4241c4`
</details>
<details>
<summary>📥 Commits</summary>
Reviewing files that changed from the base of the PR and between 0604b260d21f5b9dc539e3400d7aceb97e8940e7 and 89d78246d3cb7d515aefecfff3c895915d2885b9.
</details>
<details>
<summary>📒 Files selected for processing (1)</summary>
* `js/desktop/src/App.tsx`
</details>
<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>
* js/desktop/src/App.tsx
</details>
</details>
---
<!-- walkthrough_start -->
<details>
<summary>📝 Walkthrough</summary>
## Walkthrough
Adds a portable platform.deepLink API (getPending, onNavigate) with Electron and web implementations; App uses it to fetch pending deep links and subscribe to navigation with error logging. Unifies stream pagination to a single limit state for both statuses. NetworkRoot now always writes the `status` query parameter.
## Changes
**Platform and feature updates**
| Layer / File(s) | Summary |
|---|---|
| **Platform deepLink interface contract** <br> `js/desktop/src/lib/platform/types.ts` | `Platform` interface extended with `deepLink` capability providing `getPending(): Promise<string \| null>` and `onNavigate(callback): () => void`. |
| **Platform implementations for deepLink** <br> `js/desktop/src/lib/platform/electron.ts`, `js/desktop/src/lib/platform/web.ts` | Electron wires `getPending` and `onNavigate` to `window.electronDeepLink` methods; web implementation stubs `getPending` to resolve `null` and `onNavigate` to return a no-op unsubscribe. |
| **Deep-link navigation listener via platform abstraction** <br> `js/desktop/src/App.tsx` | `DeepLinkNavigationListener` now calls `platform.deepLink.getPending()` and navigates only when a path exists, logs errors via `logError`, and subscribes via `platform.deepLink.onNavigate()` with cleanup. |
| **Stream pagination refactoring to unified limit model** <br> `js/desktop/src/hooks/use-stream-particles.ts` | Replaces closed-tab-specific pagination constants and gating with shared `INITIAL_PAGE_SIZE` / `PAGE_INCREMENT` and a single `limit` state; `canLoadMore` uses `streams.length >= limit` and `loadMore` increments `limit`. |
| **Network status tab query parameter handling** <br> `js/desktop/src/features/network-root.tsx` | `setStatusTab` now always sets the `status` query parameter (including `open`) instead of deleting it; two inline layout comments were removed. |
## Sequence Diagram
```mermaid
sequenceDiagram
participant App as App (DeepLinkNavigationListener)
participant Platform as platform.deepLink
participant Electron as window.electronDeepLink
App->>Platform: getPending()
Platform->>Electron: getPending()
Electron-->>Platform: Promise<string|null>
Platform-->>App: pending path or null
alt pending path exists
App->>App: navigate(pendingPath)
end
App->>Platform: onNavigate(callback)
Platform->>Electron: onNavigate(callback)
Electron-->>Platform: unsubscribe function
Platform-->>App: unsubscribe function
```
## Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
## Possibly related PRs
- [flowy-live/llink#251](https://github.com/flowy-live/llink/pull/251): Modifies deep-link flow in `App.tsx` and related platform API usage; overlaps with the platform.deepLink consumption.
- [flowy-live/llink#246](https://github.com/flowy-live/llink/pull/246): Adds Electron-side `electronDeepLink` IPC/preload/main routing that complements the renderer changes in this PR.
## Poem
> 🐰 I hopped between platforms, brave and spry,
> Deep-links now whisper where they lie.
> Streams stretch longer with a single goal,
> Query strings set, the route feels whole.
> 🥕✨
</details>
<!-- walkthrough_end -->
<!-- pre_merge_checks_walkthrough_start -->
<details>
<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>
### ❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |
<details>
<summary>✅ Passed checks (4 passed)</summary>
| Check name | Status | Explanation |
| :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title 'paginate open streams' directly describes the main feature added in this PR—unified pagination for both open and closed streams via the use-stream-particles hook refactor. |
| 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. |
</details>
<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>
</details>
<!-- pre_merge_checks_walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId": "3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `paginate-open-streams`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>
<!-- tips_end -->
<!-- internal state start -->
<!-- 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 -->
<!-- internal state end -->
coderabbitai[bot]
(Migrated from github.com)
reviewed 2026-06-09 17:15:44 +00:00
coderabbitai[bot]
(Migrated from github.com)
left a comment
Copy Link
Copy Source
Actionable comments posted: 2
🤖 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 `@js/desktop/src/App.tsx`:
- Around line 59-66: The call to logError inside the deep link handler
(platform.deepLink.getPending().catch(...)) is missing its import and will fail;
add an import for logError from the desktop errors module (import { logError }
from '`@/lib/errors`';) at the top of js/desktop/src/App.tsx so the catch handler
inside the DeepLinkNavigationListener / platform.deepLink.getPending() block can
call logError correctly.
In `@js/desktop/src/hooks/use-stream-particles.ts`:
- Line 53: The pagination limit (state variables limit and setLimit initialized
from INITIAL_PAGE_SIZE in use-stream-particles.ts) isn't reset when the
filter/status changes, causing over-fetching; add an effect that watches the
status value and calls setLimit(INITIAL_PAGE_SIZE) whenever status changes so
pagination starts fresh on tab switches (keep existing useState for limit, just
add a useEffect targeting status to reset it).
🪄 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 Plus
Run ID: 83437b28-ff74-41ed-8b53-30374668f0be
📥 Commits
Reviewing files that changed from the base of the PR and between f38835ceee and 0604b260d2.
📒 Files selected for processing (6)
js/desktop/src/App.tsx
js/desktop/src/features/network-root.tsx
js/desktop/src/hooks/use-stream-particles.ts
js/desktop/src/lib/platform/electron.ts
js/desktop/src/lib/platform/types.ts
js/desktop/src/lib/platform/web.ts
**Actionable comments posted: 2**
<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>
```
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 `@js/desktop/src/App.tsx`:
- Around line 59-66: The call to logError inside the deep link handler
(platform.deepLink.getPending().catch(...)) is missing its import and will fail;
add an import for logError from the desktop errors module (import { logError }
from '`@/lib/errors`';) at the top of js/desktop/src/App.tsx so the catch handler
inside the DeepLinkNavigationListener / platform.deepLink.getPending() block can
call logError correctly.
In `@js/desktop/src/hooks/use-stream-particles.ts`:
- Line 53: The pagination limit (state variables limit and setLimit initialized
from INITIAL_PAGE_SIZE in use-stream-particles.ts) isn't reset when the
filter/status changes, causing over-fetching; add an effect that watches the
status value and calls setLimit(INITIAL_PAGE_SIZE) whenever status changes so
pagination starts fresh on tab switches (keep existing useState for limit, just
add a useEffect targeting status to reset it).
```
</details>
<details>
<summary>🪄 Autofix (Beta)</summary>
Fix all unresolved CodeRabbit comments on this PR:
- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes
</details>
---
<details>
<summary>ℹ️ Review info</summary>
<details>
<summary>⚙️ Run configuration</summary>
**Configuration used**: defaults
**Review profile**: CHILL
**Plan**: Pro Plus
**Run ID**: `83437b28-ff74-41ed-8b53-30374668f0be`
</details>
<details>
<summary>📥 Commits</summary>
Reviewing files that changed from the base of the PR and between f38835ceeefe5bd1afebe4d063140b0cd4807142 and 0604b260d21f5b9dc539e3400d7aceb97e8940e7.
</details>
<details>
<summary>📒 Files selected for processing (6)</summary>
* `js/desktop/src/App.tsx`
* `js/desktop/src/features/network-root.tsx`
* `js/desktop/src/hooks/use-stream-particles.ts`
* `js/desktop/src/lib/platform/electron.ts`
* `js/desktop/src/lib/platform/types.ts`
* `js/desktop/src/lib/platform/web.ts`
</details>
</details>
<!-- This is an auto-generated comment by CodeRabbit for review status -->
#!/bin/bash
# Description: Find logError definition and check if it's globally available# Search for logError exportsecho"=== Searching for logError exports ==="
rg -n --type=ts --type=tsx 'export.*logError' js/
# Search for logError declarationsecho -e "\n=== Searching for logError declarations ==="
rg -n --type=ts --type=tsx 'function logError|const logError|let logError' js/
# Check if logError is used elsewhere in the codebaseecho -e "\n=== Other usages of logError ==="
rg -n --type=ts --type=tsx 'logError\(' js/ -A1 -B1
Repository: flowy-live/llink
Length of output: 280
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo"=== Inspect js/desktop/src/App.tsx (imports + deepLink catch) ==="
sed -n '1,120p' js/desktop/src/App.tsx | nl -ba | sed -n '1,120p'echo -e "\n=== Find logError usage in App.tsx ==="
rg -n "logError\(" js/desktop/src/App.tsx ||trueecho -e "\n=== Find logError definitions across js/ ==="
rg -n "export\s+(function|const|let)\s+logError|function\s+logError|const\s+logError|let\s+logError" js/ ||trueecho -e "\n=== Find logError imports across js/ ==="
rg -n "import\s+\{[^}]*\blogError\b[^}]*\}\s+from|from\s+['\"][^'\"]+['\"];\s*$" js/ ||trueecho -e "\n=== Find all logError(...) callsites across js/ ==="
rg -n "logError\(" js/ -S ||true
Repository: flowy-live/llink
Length of output: 187
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo"=== Check target file exists ==="
ls -la js/desktop/src/App.tsx ||trueecho -e "\n=== App.tsx imports + deepLink block (line-numbered) ==="# Use cat -n since nl isn't available
cat -n js/desktop/src/App.tsx | sed -n '1,140p'echo -e "\n=== Find logError usage in App.tsx ==="
rg -n "logError\s*\(" js/desktop/src/App.tsx ||trueecho -e "\n=== Find logError imports in App.tsx ==="
rg -n "import\s+\{[^}]*\blogError\b[^}]*\}\s+from" js/desktop/src/App.tsx ||trueecho -e "\n=== Find logError definitions/exports across js/ ==="
rg -n "export\s+(function|const|let)\s+logError|function\s+logError|const\s+logError|let\s+logError" js/ ||trueecho -e "\n=== Find all logError(...) callsites across js/ ==="
rg -n "logError\s*\(" js/ ||true
Repository: flowy-live/llink
Length of output: 9928
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo"=== Inspect js/desktop/src/lib/errors.ts around logError ==="
sed -n '1,140p' js/desktop/src/lib/errors.ts | cat -n
echo -e "\n=== Check for barrel exports (desktop src/lib index) ==="for f in js/desktop/src/lib/index.ts js/desktop/src/lib/index.tsx js/desktop/src/lib.ts js/desktop/src/lib/index.js js/desktop/src/lib/index.ts;doif[ -f "$f"];thenecho"--- $f ---"
sed -n '1,200p'"$f"| cat -n
fidoneecho -e "\n=== Search for re-export of logError in desktop lib ==="
rg -n "export\s+\*\s+from|export\s+\{[^}]*\blogError\b[^}]*\}" js/desktop/src/lib/ ||trueecho -e "\n=== Search for logError exports outside lib/errors.ts (desktop) ==="
rg -n "export\s+function\s+logError|export\s+\{\s*logError\s*\}" js/desktop/src/ ||true
Repository: flowy-live/llink
Length of output: 4013
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo -e "=== logError import usages in desktop ==="
rg -n "import\s+\{[^}]*\blogError\b[^}]*\}\s+from" js/desktop/src ||trueecho -e "\n=== Possible global declarations ==="
rg -n "declare\s+(const|function)\s+logError|globalThis\.logError|window\.logError" js/ ||trueecho -e "\n=== Does App.tsx import '`@/lib/errors`' or similar? ==="
rg -n "from\s+['\"]`@/lib/`(errors|error|logger)['\"]" js/desktop/src/App.tsx ||trueecho -e "\n=== Any re-export barrel that could make logError available without local import? ==="
rg -n "export\s+\*\s+from\s+['\"][^'\"]*errors['\"]|export\s+\{\s*logError\s*\}" js/desktop/src/lib js/desktop/src ||true
Repository: flowy-live/llink
Length of output: 942
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "declare\s+(var|const|let|function)\s+logError|globalThis\[['\"]logError['\"]\]|globalThis\.(logError)|window\[['\"]logError['\"]\]|window\.(logError)" js/ ||true
Repository: flowy-live/llink
Length of output: 42
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "declare\s+(var|const|let|function)\s+logError|globalThis\.(logError)|window\.(logError)|global\s+logError|logError:\s*\(.*\)\s*=>" . ||true
Repository: flowy-live/llink
Length of output: 42
Fix missing logError import in DeepLinkNavigationListener
js/desktop/src/App.tsx (line 65) calls logError, but the file has no import. logError is exported from @/lib/errors (js/desktop/src/lib/errors.ts), and other desktop files import it from there—so this call will fail at runtime (and/or typecheck).
Add:
import { logError } from '@/lib/errors';
🤖 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 `@js/desktop/src/App.tsx` around lines 59 - 66, The call to logError inside the
deep link handler (platform.deepLink.getPending().catch(...)) is missing its
import and will fail; add an import for logError from the desktop errors module
(import { logError } from '`@/lib/errors`';) at the top of js/desktop/src/App.tsx
so the catch handler inside the DeepLinkNavigationListener /
platform.deepLink.getPending() block can call logError correctly.
Pagination limit does not reset when status changes.
When the user switches between the "open" and "closed" tabs, the limit state persists. If a user loads several pages of closed streams (e.g., limit reaches 60), then switches to the open tab, the hook will immediately query for 60 open streams instead of starting fresh at 12. This causes unnecessary over-fetching and changes the previous behavior that reset pagination on tab switch.
🛠️ Proposed fix to reset limit on status change
+import { useCallback, useEffect, useMemo, useState } from 'react';
-import { useCallback, useMemo, useState } from 'react';
‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const [limit, setLimit] = useState(INITIAL_PAGE_SIZE);
// Reset pagination when switching between open/closed tabs
useEffect(() => {
setLimit(INITIAL_PAGE_SIZE);
}, [status]);
import { useCallback, useEffect, useMemo, useState } from 'react';
🤖 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 `@js/desktop/src/hooks/use-stream-particles.ts` at line 53, The pagination
limit (state variables limit and setLimit initialized from INITIAL_PAGE_SIZE in
use-stream-particles.ts) isn't reset when the filter/status changes, causing
over-fetching; add an effect that watches the status value and calls
setLimit(INITIAL_PAGE_SIZE) whenever status changes so pagination starts fresh
on tab switches (keep existing useState for limit, just add a useEffect
targeting status to reset it).
_⚠️ Potential issue_ | _🟠 Major_ | _⚡ Quick win_
**Pagination `limit` does not reset when `status` changes.**
When the user switches between the "open" and "closed" tabs, the `limit` state persists. If a user loads several pages of closed streams (e.g., limit reaches 60), then switches to the open tab, the hook will immediately query for 60 open streams instead of starting fresh at 12. This causes unnecessary over-fetching and changes the previous behavior that reset pagination on tab switch.
<details>
<summary>🛠️ Proposed fix to reset limit on status change</summary>
```diff
+import { useCallback, useEffect, useMemo, useState } from 'react';
-import { useCallback, useMemo, useState } from 'react';
```
Then add a reset effect after the `useState`:
```diff
const [limit, setLimit] = useState(INITIAL_PAGE_SIZE);
+ // Reset pagination when switching between open/closed tabs
+ useEffect(() => {
+ setLimit(INITIAL_PAGE_SIZE);
+ }, [status]);
+
```
</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
const [limit, setLimit] = useState(INITIAL_PAGE_SIZE);
// Reset pagination when switching between open/closed tabs
useEffect(() => {
setLimit(INITIAL_PAGE_SIZE);
}, [status]);
```
```suggestion
import { useCallback, useEffect, useMemo, useState } from 'react';
```
</details>
<!-- suggestion_end -->
<details>
<summary>🤖 Prompt for AI Agents</summary>
```
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@js/desktop/src/hooks/use-stream-particles.ts` at line 53, The pagination
limit (state variables limit and setLimit initialized from INITIAL_PAGE_SIZE in
use-stream-particles.ts) isn't reset when the filter/status changes, causing
over-fetching; add an effect that watches the status value and calls
setLimit(INITIAL_PAGE_SIZE) whenever status changes so pagination starts fresh
on tab switches (keep existing useState for limit, just add a useEffect
targeting status to reset it).
```
</details>
<!-- fingerprinting:phantom:medusa:ocelot -->
<!-- cr-comment:v1:210709595e4896f04c075821 -->
<!-- This is an auto-generated comment by CodeRabbit -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary by CodeRabbit
Bug Fixes
New Features
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID:
4ab5069d-93dd-41b7-9c58-fcb43e4241c4📥 Commits
Reviewing files that changed from the base of the PR and between
0604b260d2and89d78246d3.📒 Files selected for processing (1)
js/desktop/src/App.tsx🚧 Files skipped from review as they are similar to previous changes (1)
📝 Walkthrough
Walkthrough
Adds a portable platform.deepLink API (getPending, onNavigate) with Electron and web implementations; App uses it to fetch pending deep links and subscribe to navigation with error logging. Unifies stream pagination to a single limit state for both statuses. NetworkRoot now always writes the
statusquery parameter.Changes
Platform and feature updates
js/desktop/src/lib/platform/types.tsPlatforminterface extended withdeepLinkcapability providinggetPending(): Promise<string | null>andonNavigate(callback): () => void.js/desktop/src/lib/platform/electron.ts,js/desktop/src/lib/platform/web.tsgetPendingandonNavigatetowindow.electronDeepLinkmethods; web implementation stubsgetPendingto resolvenullandonNavigateto return a no-op unsubscribe.js/desktop/src/App.tsxDeepLinkNavigationListenernow callsplatform.deepLink.getPending()and navigates only when a path exists, logs errors vialogError, and subscribes viaplatform.deepLink.onNavigate()with cleanup.js/desktop/src/hooks/use-stream-particles.tsINITIAL_PAGE_SIZE/PAGE_INCREMENTand a singlelimitstate;canLoadMoreusesstreams.length >= limitandloadMoreincrementslimit.js/desktop/src/features/network-root.tsxsetStatusTabnow always sets thestatusquery parameter (includingopen) instead of deleting it; two inline layout comments were removed.Sequence Diagram
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
App.tsxand related platform API usage; overlaps with the platform.deepLink consumption.electronDeepLinkIPC/preload/main routing that complements the renderer changes in this PR.Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
🧪 Generate unit tests (beta)
paginate-open-streamsComment
@coderabbitai helpto get the list of available commands and usage tips.Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID:
83437b28-ff74-41ed-8b53-30374668f0be📥 Commits
Reviewing files that changed from the base of the PR and between
f38835ceeeand0604b260d2.📒 Files selected for processing (6)
js/desktop/src/App.tsxjs/desktop/src/features/network-root.tsxjs/desktop/src/hooks/use-stream-particles.tsjs/desktop/src/lib/platform/electron.tsjs/desktop/src/lib/platform/types.tsjs/desktop/src/lib/platform/web.ts⚠️ Potential issue | 🔴 Critical
🧩 Analysis chain
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 280
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 187
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 9928
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 4013
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 942
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 42
🏁 Script executed:
Repository: flowy-live/llink
Length of output: 42
Fix missing
logErrorimport inDeepLinkNavigationListenerjs/desktop/src/App.tsx(line 65) callslogError, but the file has no import.logErroris exported from@/lib/errors(js/desktop/src/lib/errors.ts), and other desktop files import it from there—so this call will fail at runtime (and/or typecheck).Add:
import { logError } from '@/lib/errors';🤖 Prompt for AI Agents
✅ Addressed in commit
89d7824⚠️ Potential issue | 🟠 Major | ⚡ Quick win
Pagination
limitdoes not reset whenstatuschanges.When the user switches between the "open" and "closed" tabs, the
limitstate persists. If a user loads several pages of closed streams (e.g., limit reaches 60), then switches to the open tab, the hook will immediately query for 60 open streams instead of starting fresh at 12. This causes unnecessary over-fetching and changes the previous behavior that reset pagination on tab switch.🛠️ Proposed fix to reset limit on status change
Then add a reset effect after the
useState:📝 Committable suggestion
🤖 Prompt for AI Agents