Commit graph

108 commits

Author SHA1 Message Date
Avi
b05894efc7 fix(layout): redesign first-run guide with visual step indicators
- Replace plain numbered list with icon circles (primary-soft bg)
- Each step uses flex layout: indicator + content
- Step titles and body text have clear hierarchy
- Remove legacy padding-left on ol, use gap-based spacing
- Consistent 14px font size for step content
2026-09-01 11:17:20 -05:00
Avi
96dcbe4264 fix(polish): align HomeScreen with design system
- Remove identity card gradient (flat surface + success border per
  flat-by-default rule)
- Fix profile row border-radius from 8px to var(--radius-sm) (9px)
- Improve publication empty state: centered layout with icon + button
  instead of inline sentence
- Normalize home-identity-name font-size to 16px (matches profile-name)
- Remove redundant grid-template-columns from home-grid
2026-09-01 11:12:49 -05:00
Avi
e9022b36b9 fix(a11y): add keyboard accessibility to HomeScreen profile list
- Profile list rows are now focusable (tabIndex) and operable via
  Enter/Space (onKeyDown handler)
- Added role=listbox on the <ul> and role=option + aria-selected on
  non-active rows
- Added descriptive aria-label including profile name and active state
- Added focus-visible CSS ring matching the design system pattern
- Updated test role from 'list' to 'listbox'
2026-09-01 11:07:42 -05:00
Avi
0207636a7a feat: expose profile import over IPC
Wire the existing profiles::import_profile through the JSON-lines IPC
protocol so the GUI can add an existing account: ImportProfile request
and handler in src/ipc.rs, import_profile added to the Electron method
allowlist, api/AppProvider importProfile, and the Add existing account
buttons in ProfilesScreen.

Also add the active signing identity card on Home and fix the HomeScreen
tests whose text queries now match the identity card as well as the
profile row.
2026-09-01 10:41:28 -05:00
Avi
b368958a91 fix: derive imported profile name 2026-09-01 09:48:38 -05:00
Avi
d2d773a8ff fix: remove Stardust background dots 2026-09-01 09:17:00 -05:00
Avi
a3b509cb09 feat: rename app to Keynctr 2026-08-31 13:13:47 -05:00
Avi
76deca6a7f feat: add Cosmic theme + motion system 2026-08-31 00:35:30 -05:00
Avi
8366af7d86 feat: add Impeccable themes (light + dark) + unified ProfileEditModal
- settings: add Theme::Impeccable / ImpeccableDark (serde rename impeccable-dark)
- types: extend Theme union
- styles: add :root[data-theme=impeccable] (oklch lacquer/kinpaku) and impeccable-dark (lacquer-deep), Alumni Sans display, editorial refinements
- SettingsScreen: add Impeccable options with live swatch preview
- ProfilesScreen: wire ProfileEditModal (Paper Lift) with segmented tabs, keep legacy modals for compat
- DESIGN.md/PRODUCT.md + .impeccable/design.json from impeccable document
2026-08-27 14:12:52 -05:00
Avi
9e635e7a93 fix: restore profile delete/undo and themed auto-dismiss undo bar
- ipc: add DeleteProfile/UndoDelete requests returning state_view
- profiles: expose delete_profile outside tests
- api: deleteProfile/undoDelete now return AppState; AppProvider uses applyState
- fakeBackend: implement delete/undo handlers
- ProfilesScreen: themed 'Profile deleted — Undo and restore profile' (primary color, primary-soft) with 5s auto-dismiss, shown in both empty and grid states
2026-08-27 12:07:13 -05:00
Avi
8130c3e7e5 frontend: click a profile row on Home to select it
Mirrors the Profiles screen: the whole non-active row in the Home
'Your profiles' list now selects the profile on click, guarded so the
Copy/Select buttons don't double-trigger. Added a pointer cursor for
non-active rows and a test for row-click selection.
2026-08-26 14:59:51 -05:00
Avi
98f45204dc frontend: show active-profile picture on Compose and sidebar
Avatar was rendered without the 'picture' prop, so the active profile's
image only appeared on Home. Added picture={active.picture} to both
Compose avatars (write + preview) and the sidebar active-profile avatar.
2026-08-26 14:53:46 -05:00
Avi
f53416528c frontend: remove redundant Profiles sidebar tab
The Profiles screen is still reachable via Home's 'Manage profiles'
button, so the left-nav Profiles tab was redundant. Dropped the
'profiles' entry from the sidebar NAV_ITEMS and updated App.test.tsx
to navigate to the screen via 'Manage profiles' instead.
2026-08-26 14:49:52 -05:00
Avi
835b0a02fd frontend: list all profiles on Home, pin dev host, widen profiles card
- Home now shows every profile with its picture, an inline Active badge,
  and a working Select button (was only the active profile).
- Remove the Relays card from Home (status lives on the Relays screen) and
  its unused connection-check logic/test.
- Pin Vite dev server to 127.0.0.1 so Electron and the dev server agree on
  the address (fixes white-box window in dev mode).
- Make the profiles card full-width to match the publication card below.
- Badge now accepts className.
2026-08-26 14:32:22 -05:00
Avi
71e580f474 Trim white margins from sidebar logo artwork
The 512px source had ~25% baked-in white padding on every side, so the
38px sidebar tile showed a small bird floating in a white square.
Cropped to the content bounding box plus a 6% pad (keeps wing/beak
tips clear of the rounded corners); the img already fills the tile via
object-fit: cover. Window/packaged icons untouched.
2026-08-25 14:36:02 -05:00
Avi
7098e75ca3 refactor: share modal save lifecycle 2026-08-25 11:04:20 -05:00
Avi
e6a1efc7f2 refactor: share hex-id shortening in lib/format 2026-08-25 10:12:49 -05:00
Avi
dd50b24ec1 Rename glass theme display to Aurora; fix unreadable select options
The theme dropdown popup inherited the near-transparent select
background and rendered white-on-white under the glass theme.
Options now get an explicit dark surface, plus color-scheme: dark
so native controls render correctly. User-facing name is Aurora;
the internal 'glass' id is unchanged so saved settings keep working.
2026-08-24 19:49:30 -05:00
Avi
ecb666bc1d Glass theme: real frosted-glass look
Translucent surfaces with backdrop blur over an aurora gradient
backdrop, hairline light borders, softened accent tints, frosted
modal scrim, inverted sidebar logo. Scoped entirely to
html[data-theme='glass'] — other themes untouched.
2026-08-24 19:44:11 -05:00
Avi
bfe14f0d97 Fix glass theme: repair broken Default impl that blocked all builds
Commit a01f258 removed Theme::System but missed Settings::default(),
so the crate failed to compile and every desktop launch kept spawning
a stale backend binary that rejected 'glass'. Also untangles the
glass palette CSS that was duplicated as nested blocks inside the
neon rule, and re-applies the theme reactively when settings change.
2026-08-24 19:39:32 -05:00
Avi
db2d22f999 Theme: add glass theme (CAJAFUERTE-inspired) alongside light/dark/neon 2026-08-24 14:34:35 -05:00
Avi
a01f258d4b Remove system theme, keep light/dark/neon only 2026-08-24 14:23:15 -05:00
Avi
c080a8d1c8 App icon: remove white border, restore original 512x512 dimensions 2026-08-24 13:52:47 -05:00
Avi
90d699cff1 App icon: subtle white border around black artwork 2026-08-24 12:30:37 -05:00
Avi
74072b7d6d Neon theme: pure-black Matrix palette (CAJAFUERTE-inspired) alongside light/dark/system 2026-08-24 12:14:39 -05:00
Avi
a00c7c9897 Sidebar brand mark: hummingbird-key artwork replaces the shield icon 2026-08-24 11:56:16 -05:00
Avi
cbbe779faa Desktop entry + Wayland app id so the taskbar shows the app icon 2026-08-24 11:46:48 -05:00
Avi
8a644afd80 App icon: hummingbird-key mark for window and packaged Linux builds 2026-08-24 11:33:45 -05:00
Avi
c11ab9f735 Security: major dependency upgrades clearing all npm advisories; show per-advisory fix paths 2026-08-24 11:00:18 -05:00
Avi
8bce42810a Updates card: scan npm/cargo deps, surface security advisories, install compatible updates 2026-08-24 09:54:04 -05:00
Avi
55a49b442b Feed: 'My notes' scope with per-profile dropdown filter 2026-08-24 00:13:58 -05:00
Avi
045fa47476 Add NIP-05 identifiers: store, publish, GUI modal, CLI helpers
- Store an optional nip05 on each profile; publish it in kind 0 metadata
- set-nip05 CLI (+ validation, lower-casing, clear) and nip05-file helper
  that prints the .well-known/nostr.json document for a domain
- Profiles screen: NIP-05 button, handle shown on cards, Nip05Modal with
  client-side validation and Remove action
- Fix Modal stealing focus from autoFocus inputs one frame after open
2026-08-23 21:59:11 -05:00
Avi
d618a5a4a0 Add profile rename with metadata republish (GUI + CLI) 2026-08-23 18:48:45 -05:00
Avi
64502c1b14 Wrap profile card action buttons on narrow windows 2026-08-23 16:25:07 -05:00
Avi
653945a5e8 Select a profile by clicking anywhere on its card 2026-08-23 15:34:24 -05:00
Avi
24b34b6f93 Remove duplicate productName entries from package.json 2026-08-23 11:06:32 -05:00
Avi
6ead6f418c Fix hardcoded dev window title to Keynectr 2026-08-23 11:04:09 -05:00
Avi
31ef3057e0 Rebrand remaining UI strings to Keynectr
Sidebar brand, home welcome title, settings version line, stylesheet
header comment and the three tests asserting them.
2026-08-23 10:43:20 -05:00
Avi
7c6a085bf1 Rename the app to Keynectr
- Crate/binary: nostr-manager-backend -> keynectr
- Data directory: nost-feed-manager -> keynectr, migrated automatically
  on first data_dir() call (existing vaults, settings and backups move)
- Electron extraResources/spawn path, executableName, productName,
  window title and CLI usage strings updated to match
- Deliberately unchanged: crypto.rs KDF verifier string, so previously
  encrypted vault backups remain decryptable

Verified live: existing vault with two profiles migrated to
~/.local/share/keynectr and loads correctly.
2026-08-23 10:22:25 -05:00
Avi
ae5dddaa47 Allow new profile methods through the Electron IPC allowlist
set_profile_picture and publish_profile_metadata were rejected by the
renderer-method gate added in the 2026-08-21 hardening ('rejected renderer
method' in the log), so the GUI buttons could never reach the backend.
Also allow delete_profile / undo_delete from the deletion feature, which
were missing from the list as well.
2026-08-22 20:38:53 -05:00
Avi
a6329d5640 Publish profile metadata (name + picture) so external clients show it
Profiles created in the app never published a kind 0 metadata event, so
clients like Iris and Yakihonne showed generated petnames ("evil iguana")
or a truncated npub instead of the user's chosen name.

- Publish kind 0 metadata (name/display_name) automatically on creation
- Add "Publish name" action (GUI button + publish-name CLI) for existing
  profiles, with a per-relay success/failure report
- Add profile pictures: optional picture URL persisted in the vault,
  set via GUI modal (URL paste or nostr.build upload), set-picture CLI,
  and included in the published metadata; avatars render it in-app
- Run metadata publishing on its own thread so sync and async callers
  never nest tokio runtimes
- Expose undo_history in the state view and fix typecheck errors left by
  the unfinished delete/undo work (variants, icon, null-safety)
- Use offline relay settings in tests: Settings::default() points at real
  relays, which tests were silently publishing to (suite: 126s -> ~3s)

Verification: cargo test 96 passed; clippy/fmt/build clean. Frontend:
78 tests, typecheck, lint, format, vite and electron builds all pass.
2026-08-22 18:42:20 -05:00
Avi
db81f8dfda Implement profile deletion with undo functionality
- Add delete_profile() to profiles.rs - moves profile to undo stack
- Add undo_history field and undo_delete() method to App struct
- Add cli_delete_profile() and cli_undo_delete() CLI commands
- Add delete-profile <npub> and undo-delete to USAGE
- Update CHECKPOINT-encryption.md checkpoint

Verification: cargo test (91 passed), clippy clean, fmt clean, release build successful
2026-08-22 15:29:26 -05:00
Avi
f7db29e793 Add SSRF guard, signer queue cap, secret echo, request timeout 2026-08-21 16:06:18 -05:00
Avi
4d4dfde1de Enforce header-based CSP and block window open/navigation 2026-08-21 13:53:45 -05:00
Avi
6e627a3341 Replace upload file paths with single-use pick tokens 2026-08-21 13:48:34 -05:00
Avi
4bde3957b9 Restrict renderer IPC to an explicit method allowlist 2026-08-21 13:30:58 -05:00
Avi
5b0b87b784 Repair project paths after move 2026-08-20 18:50:19 -05:00
Avi
a1445d17a8 Add contact-aware feed scope
- src/feed.rs: contact_feed + contact_pubkeys fetch the active profile's
  kind 3 contact list and aggregate notes only from those authors;
  aggregate_for + FeedBuilder accept an optional author whitelist
- IPC: FeedGet accepts contacts_only, resolves the active profile npub
- CLI: feed --contacts [limit] filters to the active profile's contacts
- Frontend: Feed screen Everyone/My contacts toggle, scope-aware empty
  states, feedGet(limit, contactsOnly) threading
- Tests for author filtering and the contacts scope in feed.rs and
  FeedScreen.test.tsx
2026-08-06 11:01:27 -05:00
Avi
37a9d945c9 Add feed aggregation from enabled relays
- src/feed.rs: aggregate recent kind 1 notes from enabled relays into a
  newest-first, de-duplicated feed using a throwaway identity
- IPC: FeedGet; CLI: feed [limit]; frontend: Feed screen + nav + tests
- README: mark feed aggregation as shipped
2026-08-06 10:31:45 -05:00
Avi
ca3203cfc4 Require user approval for NIP-46 sign/encrypt requests 2026-08-06 10:03:50 -05:00