update
Rust / build (macos-latest, stable) (push) Waiting to run
Rust / build (ubuntu-latest, stable) (push) Waiting to run
Rust / build (windows-latest, stable) (push) Waiting to run
Rust / build (macos-latest, stable) (pull_request) Waiting to run
Rust / build (ubuntu-latest, stable) (pull_request) Waiting to run
Rust / build (windows-latest, stable) (pull_request) Waiting to run

This commit is contained in:
2026-09-12 10:27:36 +07:00
parent 4684e01e89
commit 8a229cb212
3 changed files with 158 additions and 179 deletions
+23 -21
View File
@@ -59,7 +59,7 @@ Data hooks:
| Priority | Section | Notes |
|---|---|---|
| **P0** | Inbox panel | Activity directed at you and your own activity, **grouped by repository**; unread badge; mark all read; all groups shown |
| **P1** | Click-through | Open the repo panel at the relevant PR/issue |
| **P1** | Click-through | Open the issue/PR detail panel at the relevant thread root |
| **P2 (defer)** | Standalone notifications page, NIP-65 relay discovery, pagination | Web-app concerns |
| **Out of scope** | Greeting header, my repositories, followed repositories, private repositories, pinned repositories, Unread/Archived sub-views | Not needed in Signed |
@@ -592,7 +592,6 @@ In `views/sidebar/mod.rs`:
### 5.4 Click-through (P1)
Reuse the single `RepoStore` that `RepoDetailView` already creates instead of making a second one.
The detail panels need a `Window`, and GPUI's `Entity::update_in` only exists on a `VisualContext`,
which a synchronous `App` + `Window` pair is not - so the entry point is a free function rather than
a `RepoDetailView::open_item` method. In `repo_detail/mod.rs`:
@@ -606,25 +605,28 @@ pub(crate) enum RepoItem {
pub(crate) fn open_repo_item(
dock_area: &WeakEntity<DockArea>,
store: Entity<RepoStore>,
announcement: &Announcement,
item: RepoItem,
window: &mut Window,
cx: &mut App,
) { /* new IssueDetailView / PullRequestDetailView, added to the center */ }
) { /* build the RepoStore here, then a new IssueDetailView / PullRequestDetailView, added to the center */ }
```
- `RepoDetailView::store()` exposes its `Option<Entity<RepoStore>>`, so the caller reuses the repo
panel's store rather than building one. `views/mod.rs` re-exports `RepoItem` and `open_repo_item`.
- `InboxView` resolves `item.address` to an `Announcement` from `RepoListStore`, calls
`open_repo_panel` (which returns `Entity<RepoDetailView>`), takes its store, and calls
- `open_repo_item` builds its own `RepoStore` from `announcement` (a private `repo_store` helper calls
`RepoStore::new(addr, relays, cx)`), so the item panel is the **only** panel docked. An earlier
version opened `RepoDetailView` first and reused its store via `RepoDetailView::store()`; that
docked the repository panel too, which surfaced the repository load state (a `not found` error for
an announced repo with no local worktree) and left two center tabs. `RepoDetailView::store()` was
removed with it.
- `views/mod.rs` re-exports `RepoItem` and `open_repo_item`.
- `InboxView::open_item` resolves `item.address` to an `Announcement` from `RepoListStore`, and calls
`open_repo_item` with the root id and kind. The detail panel renders a "not found" placeholder
until the store's fetch lands, then re-renders.
- The repository panel and the detail panel are two tabs of the center group; the detail is
activated. This matches the sidebar, which also opens a fresh repo panel per click.
- The item panel is added to the center group and activated.
Patches have no detail view in Signed (they are only consumed inside `PullRequestDetailView`), so a
patch-root click opens the repo panel only. `RepoItem::Patch` carries no id for that reason. A group
whose root is not an issue/PR/patch, or whose repository is not in `RepoListStore`, opens nothing.
patch-root click opens nothing. `RepoItem::Patch` carries no id for that reason. A group whose root is
not an issue/PR/patch, or whose repository is not in `RepoListStore`, opens nothing.
## 6. File-by-file change list
@@ -643,7 +645,7 @@ whose root is not an issue/PR/patch, or whose repository is not in `RepoListStor
| `crates/workspace/src/views/inbox.rs` | `InboxView` home panel owning the threads, the repository grouping, and the thread click-through |
| `crates/workspace/src/views/mod.rs` | `mod inbox; pub use inbox::InboxView;`; re-export `RepoItem`, `open_repo_item`, `open_repo_panel` |
| `crates/workspace/src/views/sidebar/mod.rs` | `inbox` field, `open_inbox`, nav wiring |
| `crates/workspace/src/views/repo_detail/mod.rs` | `RepoItem`, `open_repo_item`, `RepoDetailView::store()` |
| `crates/workspace/src/views/repo_detail/mod.rs` | `RepoItem`, `open_repo_item` (builds its own `RepoStore` via the private `repo_store` helper) |
No changes to `desktop` or `signed_nostr`. `signed_state::init` gains no parameters; `Backend::sync_inbox`
activates the `Inbox` child entity at each signer transition.
@@ -822,23 +824,23 @@ store changes.
Files: `crates/workspace/src/views/{inbox.rs, mod.rs, repo_detail/mod.rs}`. No store changes.
- `RepoItem { Issue(EventId), PullRequest(EventId), Patch }` and `pub(crate) fn open_repo_item` live
in `repo_detail/mod.rs`, next to `open_repo_panel`. `open_repo_item` takes the store as a
parameter, avoiding a second `RepoStore`.
in `repo_detail/mod.rs`, next to `open_repo_panel`. `open_repo_item` builds its own `RepoStore` from
the announcement (private `repo_store` helper), so only the item panel is docked.
- It is a free function, not `RepoDetailView::open_item`: the detail constructors take a `Window`, and
a synchronous `&mut App` + `&mut Window` pair is not a `VisualContext`, so `Entity::update_in` is
not available. `InboxView` already has the window in the list's `on_click`, so it drives the free
function directly. The plan's original `detail.update_in(window, cx, ...)` sketch could not compile.
- `RepoDetailView::store()` (`pub(crate)`) exposes the panel's `Option<Entity<RepoStore>>`. The repo
panel is opened first and its store reused, so the detail panel shares one store with the repo it
came from.
- `InboxView::open_item` is also a free function (it needs nothing but `dock_area`, which it captures
from the panel) because the `gpui::list` item closure only receives `&mut App`. It resolves
`item.address` through `RepoListStore`, returns silently when the repository is unknown, opens the
repo panel, then maps the root kind to a `RepoItem` and calls `open_repo_item`.
`item.address` through `RepoListStore`, returns silently when the repository is unknown, maps the
root kind to a `RepoItem`, and calls `open_repo_item`.
- Fixed: the first version opened `RepoDetailView` to borrow its store (`RepoDetailView::store()`),
which docked the repository panel alongside the item panel and showed its `not found` load error.
`open_repo_item` now builds the `RepoStore` itself and `RepoDetailView::store()` is gone.
- Only the notification rows are clickable. Activity rows are display-only. The Phase 3 mark-read /
archive row behaviour is gone with the sub-views.
- `RepoItem::Patch` is a unit variant because the id would be unused: patches have no detail panel, so
`open_repo_item` returns before doing anything and only the repository panel opens.
`open_repo_item` returns before doing anything and nothing is docked.
- `cargo clippy -p workspace --all-targets` is clean, `cargo check --workspace --all-targets` succeeds,
and `cargo test -p signed_core -p signed_state -p workspace -p dock` passes (68 / 24 / 7 / 1).