update sidebar

This commit is contained in:
2026-09-14 08:56:32 +07:00
parent 1a13d4e0d7
commit c6ada10afa
5 changed files with 267 additions and 74 deletions
+28 -24
View File
@@ -1,6 +1,6 @@
# Local repository NIP-34 detection
Status: Phases 12 implemented. Phases 35 pending.
Status: Phases 13 implemented. Phases 45 pending.
## Motivation
@@ -212,28 +212,31 @@ Implemented.
- [x] `crates/workspace/src/views/sidebar/mod.rs`: minimal adaptation of the existing folder-name
dedupe to the new entry type so the tree compiles; the badge/dedupe rewrite is Phase 3.
### Phase 3 — sidebar: derive the local list and link to announcements
### Phase 3 — derive the local list and link it to announcements
File: `crates/workspace/src/views/sidebar/mod.rs`.
Implemented. The matching lives in `signed_state` (per the data-model note above), so the sidebar
stays a thin renderer.
- [ ] Replace the folder-name dedupe in `refresh` with a resolution pass over
`LocalReposStore::global(cx).read(cx).repos`:
- For each entry, compute the detected `RepoAddr` when the binding is `Initialized` with
owner + identifier.
- Look the address up in `RepoListStore` announcements.
- If it matches an announcement **already shown** in the sidebar's list (the signed-in
user's own), drop it from the local list to avoid showing it twice.
- If it matches an announcement that is not in the shown list, keep it as a local entry
rendered with the "initialized" badge; clicking opens the announced repository (decision 1).
- Otherwise keep it with a badge derived from the binding kind.
- [ ] Extend the sidebar's local entry model from `Vec<PathBuf>` to a small struct carrying the
path, the binding kind, the tool label and the resolved address, so `render_repo_at` can
render the badge and route clicks.
- [ ] Add the badge rendering to the local row in `render_repo_at` (three visible states):
- [x] `crates/signed_state/src/local_repos.rs`: `ResolvedLocalRepo` and
`resolve_local_repos(repos, known, own)` resolve each scanned repository's `RepoAddr` against
the known announcements:
- a binding matching one of the user's **own** announcements is dropped, since it is already
listed as an announcement row;
- a binding matching any other known announcement is kept and linked to it;
- every other repository is kept unchanged.
- [x] `crates/signed_git/src/nip34.rs`: `Nip34Binding` derives `PartialEq` so the sidebar can
detect changes to the resolved list.
- [x] `crates/workspace/src/views/sidebar/mod.rs`: the local list is `Arc<Vec<ResolvedLocalRepo>>`;
`refresh` calls `resolve_local_repos` instead of the folder-name dedupe. A matched entry's
click opens the announced repository, the rest open the local detail view.
- [x] Badge rendering in `render_local_row`, derived from `Nip34Binding::signals`:
- `Initialized` → "NIP-34 · nak" / "NIP-34 · ngit"
- `Cloned` → "NIP-34 clone" (decision 2, its own visible state)
- `ToolingOnly` → "Nostr tooling" (muted)
- plain → unchanged.
- plain → unchanged warning icon.
Note: the announced-open path currently opens the announced repository without the local worktree;
attaching it is Phase 4.
### Phase 4 — detail view: open as announced, gate the publish CTA
@@ -295,14 +298,15 @@ Unit tests in `crates/signed_git/src/nip34.rs` (use `tempfile` and a small local
`https://host/repo.git` (no owner), a first segment that is not a valid `npub`, and an unrelated
scheme such as `ssh://`.
Integration test in `crates/signed_state`:
Integration tests in `crates/signed_state/src/local_repos.rs` (plain `#[test]`, no GPUI harness):
- A scanned repository whose binding resolves to a `RepoAddr` that matches a seeded announcement is
deduped out of the local list when it is the user's own; one with no matching announcement
remains and is labelled.
- a repository bound to the user's own announcement is dropped from the local list;
- one bound to another owner's announcement is kept and linked to it;
- one with an unmatched binding is kept with its binding and no announcement;
- a plain repository is kept with no binding and no announcement.
Final verification: `cargo check -p signed_git -p signed_state -p workspace` and
`cargo test -p signed_git`.
Final verification: `cargo clippy -p signed_git -p signed_state -p workspace --all-targets` and
`cargo test -p signed_git -p signed_state`.
## Out of scope