feat: rename app to Keynctr
This commit is contained in:
parent
76deca6a7f
commit
a3b509cb09
10 changed files with 38 additions and 20 deletions
|
|
@ -1,29 +1,40 @@
|
||||||
# Checkpoint — Impeccable themes + ProfileEditModal (2026-08-27)
|
# Checkpoint — Keynctr branding and Linux installers (2026-08-31)
|
||||||
|
|
||||||
## Where things are
|
## Where things are
|
||||||
- Project: `/home/avi/Projects/Nostr_Keynctr`
|
- Project: `/home/avi/Projects/Nostr_Keynctr`
|
||||||
- Git repo: `master` @ `8366af7` ("feat: add Impeccable themes (light + dark) + unified ProfileEditModal"). Before it: `832e114` (checkpoint: fix delete/undo), `9e635e7` (fix delete/undo bar), `56c2a6d` (click profile row), `8130c3e` etc.
|
- Git repo: `master` @ `76deca6` ("feat: add Cosmic theme + motion system").
|
||||||
- Working tree: clean except `.opencode/` (impeccable skill install, not tracked) and `KeynectrAppIconPossibility02.jpeg` untracked (long-standing).
|
- Working tree: uncommitted Keynctr branding, packaging metadata, and Cosmic palette/branding updates, plus untracked `.directory`, `.opencode/`, `COSMIC_THEME.md`, and `KeynectrAppIconPossibility02.jpeg`.
|
||||||
|
|
||||||
## What was completed
|
## What was completed
|
||||||
1. **Fixed broken profile delete/undo** (previous). `src/ipc.rs` missing `DeleteProfile`/`UndoDelete`; added handlers returning `state_view`; exposed `profiles::delete_profile` outside tests; `api.ts`/`AppProvider` now `call<AppState>` via `applyState`; `fakeBackend` delete/undo.
|
1. **Cosmic branding update.** The Cosmic theme now uses Gold `#F3B407` and Light Blue `#87E6FB`; Cosmic’s dark sidebar presents the logo in white while retaining black-on-white artwork elsewhere. The visible brand is `SOLARPUNK SUMMIT` with `KITCHEN 484`.
|
||||||
|
2. **Fixed broken profile delete/undo** (previous). `src/ipc.rs` missing `DeleteProfile`/`UndoDelete`; added handlers returning `state_view`; exposed `profiles::delete_profile` outside tests; `api.ts`/`AppProvider` now `call<AppState>` via `applyState`; `fakeBackend` delete/undo.
|
||||||
2. **Themed auto-dismiss undo bar.** Replaced permanent white bar with `var(--primary-soft)` + `var(--primary)` link `Undo and restore profile`, 5s `useEffect` watching `lastDeleted`, shown in both empty/populated states.
|
2. **Themed auto-dismiss undo bar.** Replaced permanent white bar with `var(--primary-soft)` + `var(--primary)` link `Undo and restore profile`, 5s `useEffect` watching `lastDeleted`, shown in both empty/populated states.
|
||||||
3. **Impeccable themes (light + dark).** `src/settings.rs`: `Theme::Impeccable` + `ImpeccableDark` (serde `impeccable-dark`); `types.ts` union extended; `styles.css` added `:root[data-theme='impeccable']` (oklch 97% lacquer light, kinpaku gold `oklch(77% .13 82)`, Alumni Sans 300) and `impeccable-dark` (oklch 15% lacquer-deep, champagne text), editorial refinements (uppercase labels, 8/3px radii, nav left-border active, card offset bar); `SettingsScreen.tsx` adds both options with live `var(--*)` swatches.
|
3. **Impeccable themes (light + dark).** `src/settings.rs`: `Theme::Impeccable` + `ImpeccableDark` (serde `impeccable-dark`); `types.ts` union extended; `styles.css` added `:root[data-theme='impeccable']` (oklch 97% lacquer light, kinpaku gold `oklch(77% .13 82)`, Alumni Sans 300) and `impeccable-dark` (oklch 15% lacquer-deep, champagne text), editorial refinements (uppercase labels, 8/3px radii, nav left-border active, card offset bar); `SettingsScreen.tsx` adds both options with live `var(--*)` swatches.
|
||||||
4. **Unified ProfileEditModal.** `frontend/src/components/ProfileEditModal.tsx` — Paper Lift modal (`var(--surface)`/`var(--border)`/`16px`/`0 12px 40px`), 3 tabs (Name/Picture/NIP-05) sharing `renameProfile`/`setProfilePicture`/`setNip05`; `ProfilesScreen.tsx` wires `Edit profile` (secondary) alongside legacy ghosts; `DESIGN.md` + `PRODUCT.md` + `.impeccable/design.json` from `impeccable document` (Vault & Atelier, warm ivory/charcoal/coral, 9 primitives).
|
4. **Unified ProfileEditModal.** `frontend/src/components/ProfileEditModal.tsx` — Paper Lift modal (`var(--surface)`/`var(--border)`/`16px`/`0 12px 40px`), 3 tabs (Name/Picture/NIP-05) sharing `renameProfile`/`setProfilePicture`/`setNip05`; `ProfilesScreen.tsx` wires `Edit profile` (secondary) alongside legacy ghosts; `DESIGN.md` + `PRODUCT.md` + `.impeccable/design.json` from `impeccable document` (Vault & Atelier, warm ivory/charcoal/coral, 9 primitives).
|
||||||
|
5. **Linux installers.** Electron Builder now produces both AppImage and Debian targets. Generated artifacts are `frontend/release/SOLARPUNK SUMMIT-0.1.0.AppImage` and `frontend/release/keynectr_0.1.0_amd64.deb`.
|
||||||
|
6. **Keynctr branding.** Replaced the visible `SOLARPUNK SUMMIT` / `KITCHEN 484` labels with `Keynctr` in the window, page title, sidebar, home screen, settings, and tests. Rebuilt artifacts: `frontend/release/Keynctr-0.1.0.AppImage` and `frontend/release/keynectr_0.1.0_amd64.deb`.
|
||||||
|
|
||||||
## Commits added in this session (newest first)
|
## Commits added in this session (newest first)
|
||||||
|
- No commit added; packaging metadata and checkpoint updates remain uncommitted.
|
||||||
|
- `76deca6` feat: add Cosmic theme + motion system (palette/branding refinements currently uncommitted)
|
||||||
- `8366af7` feat: add Impeccable themes (light + dark) + unified ProfileEditModal
|
- `8366af7` feat: add Impeccable themes (light + dark) + unified ProfileEditModal
|
||||||
- `832e114` checkpoint: fix delete/undo + themed auto-dismiss bar
|
- `832e114` checkpoint: fix delete/undo + themed auto-dismiss bar
|
||||||
- `9e635e7` fix: restore profile delete/undo and themed auto-dismiss undo bar
|
- `9e635e7` fix: restore profile delete/undo and themed auto-dismiss undo bar
|
||||||
|
|
||||||
## Verification commands run (all green)
|
## Verification commands run
|
||||||
- Rust (repo root): `cargo fmt --check` clean; `cargo clippy --all-targets` 2 pre-existing warnings; `cargo test` 115 passed; `cargo build --release` success
|
- Rust: `cargo fmt --check`, `cargo clippy --all-targets`, `cargo test` (115 passed), and `cargo build --release` passed; existing warnings remain in `src/ipc.rs` and `src/profiles.rs`.
|
||||||
- Frontend (`frontend/`): `npm test` 15 files / 99 tests passed; `npm run typecheck` clean; `npm run lint` clean; `npm run format:check` clean (after `npm run format`); `npm run build` success; `npm run electron:build` success
|
- Frontend: `npm test` (15 files / 99 tests), `npm run typecheck`, `npm run lint`, `npm run format:check`, `npm run build`, and `npm run electron:build` passed.
|
||||||
|
- Packaging: `npx electron-builder --linux AppImage deb` passed; AppImage and Debian files verified with `file`.
|
||||||
|
- Branding verification: `npm test`, `npm run typecheck`, `npm run lint`, `npm run format:check`, `npm run electron:build`, `npm run build`, and `npx electron-builder --linux AppImage deb` passed.
|
||||||
|
- Frontend build no longer reports the Cosmic font `@import` ordering warning; standard Vite/ESM and ESLint module warnings remain.
|
||||||
- Wayland `--ozone-platform` / `has no handler` messages on `electron:build` are harmless.
|
- Wayland `--ozone-platform` / `has no handler` messages on `electron:build` are harmless.
|
||||||
|
|
||||||
## How to resume / reproduce
|
## How to resume / reproduce
|
||||||
GUI (Impeccable): `cargo build --release && cd frontend && npm run build && npm run electron:build && npm start` (or dev: `npm run dev` in one terminal + `NOSTR_GUI_DEV_URL=http://localhost:5173 npm start` in second). Settings → Appearance → `Impeccable — Light` / `Impeccable — Dark` (gold on ivory lacquer vs lacquer-deep). Profiles → Delete → see themed undo bar 5s; Edit profile → tabbed modal. CLI: `cargo run -- settings set theme impeccable` / `impeccable-dark`.
|
GUI (Cosmic): `cargo build --release && cd frontend && npm run build && npm run electron:build && npm start` (or dev: `npm run dev` in one terminal + `NOSTR_GUI_DEV_URL=http://localhost:5173 npm start` in second). Settings → Appearance → `Cosmic — Stardust`. CLI: `cargo run -- settings set theme cosmic`.
|
||||||
|
- Build installers: `cd frontend && npm run build && npm run electron:build && npx electron-builder --linux AppImage deb`. Install the `.deb` with `sudo apt install ./release/keynectr_0.1.0_amd64.deb`, or run the AppImage with `./release/SOLARPUNK\ SUMMIT-0.1.0.AppImage`.
|
||||||
|
- Current installers: `sudo apt install ./release/keynectr_0.1.0_amd64.deb`, or `./release/Keynctr-0.1.0.AppImage`.
|
||||||
|
|
||||||
## Outstanding / next-step items
|
## Outstanding / next-step items
|
||||||
- Undo restores with empty `secret_key` (stores `ProfileSummary`); needs `StoredProfile` in `undo_history` for full secret recovery.
|
- Undo restores with empty `secret_key` (stores `ProfileSummary`); needs `StoredProfile` in `undo_history` for full secret recovery.
|
||||||
- `.opencode/` skill files and `KeynectrAppIconPossibility02.jpeg` remain untracked; not part of theme commits.
|
- `.opencode/`, `COSMIC_THEME.md`, and `KeynectrAppIconPossibility02.jpeg` remain untracked; no commit was created in this session.
|
||||||
|
- Installer artifacts are local build outputs under `frontend/release/` and are not committed.
|
||||||
|
|
|
||||||
|
|
@ -511,7 +511,7 @@ function createWindow(): void {
|
||||||
height: 760,
|
height: 760,
|
||||||
minWidth: 920,
|
minWidth: 920,
|
||||||
minHeight: 640,
|
minHeight: 640,
|
||||||
title: 'Keynectr',
|
title: 'Keynctr',
|
||||||
icon: resolveWindowIcon(),
|
icon: resolveWindowIcon(),
|
||||||
backgroundColor: '#f6f4f0',
|
backgroundColor: '#f6f4f0',
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Keynectr</title>
|
<title>Keynctr</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "keynectr",
|
"name": "keynectr",
|
||||||
"productName": "Keynectr",
|
"productName": "Keynctr",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "A friendly Linux desktop app for managing Nostr profiles and publishing text notes.",
|
"description": "A friendly Linux desktop app for managing Nostr profiles and publishing text notes.",
|
||||||
|
"author": {
|
||||||
|
"name": "Keynectr",
|
||||||
|
"email": "maintainers@keynectr.local"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/avi/Keynctr",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "dist-electron/main.js",
|
"main": "dist-electron/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
@ -64,7 +69,8 @@
|
||||||
],
|
],
|
||||||
"linux": {
|
"linux": {
|
||||||
"target": [
|
"target": [
|
||||||
"dir"
|
"AppImage",
|
||||||
|
"deb"
|
||||||
],
|
],
|
||||||
"icon": "build/icon.png",
|
"icon": "build/icon.png",
|
||||||
"category": "Network",
|
"category": "Network",
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function Sidebar({ screen, onNavigate }: SidebarProps) {
|
||||||
<img src={logoUrl} alt="" draggable={false} />
|
<img src={logoUrl} alt="" draggable={false} />
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<strong>Keynectr</strong>
|
<strong>Keynctr</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export function HomeScreen({ onNavigate, onCreateProfile }: HomeScreenProps) {
|
||||||
<div className="screen-inner">
|
<div className="screen-inner">
|
||||||
<EmptyState
|
<EmptyState
|
||||||
icon={<Icon name="users" size={30} />}
|
icon={<Icon name="users" size={30} />}
|
||||||
title="Welcome to Keynectr"
|
title="Welcome to Keynctr"
|
||||||
description={
|
description={
|
||||||
<span>
|
<span>
|
||||||
You haven't created a profile yet. A Nostr profile is your identity on the public
|
You haven't created a profile yet. A Nostr profile is your identity on the public
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,8 @@ export function SettingsScreen() {
|
||||||
</div>
|
</div>
|
||||||
<p className="hint">
|
<p className="hint">
|
||||||
"Light" and "Dark" follow your manual selection. "Aurora", "Neon", "Impeccable",
|
"Light" and "Dark" follow your manual selection. "Aurora", "Neon", "Impeccable",
|
||||||
"Impeccable Dark", and "Cosmic" are aesthetic themes with distinctive color palettes.
|
"Impeccable Dark", and "Cosmic" are aesthetic themes with distinctive color
|
||||||
|
palettes.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -404,7 +405,7 @@ export function SettingsScreen() {
|
||||||
<dl className="info-list">
|
<dl className="info-list">
|
||||||
<div>
|
<div>
|
||||||
<dt>Application</dt>
|
<dt>Application</dt>
|
||||||
<dd>Keynectr v{state?.version ?? '?'}</dd>
|
<dd>Keynctr v{state?.version ?? '?'}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt>Backend</dt>
|
<dt>Backend</dt>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ describe('App', () => {
|
||||||
const { user } = renderApp(backend);
|
const { user } = renderApp(backend);
|
||||||
render(<App />);
|
render(<App />);
|
||||||
|
|
||||||
expect(await screen.findByText('Welcome to Keynectr')).toBeInTheDocument();
|
expect(await screen.findByText('Welcome to Keynctr')).toBeInTheDocument();
|
||||||
expect(screen.getByRole('button', { name: /Create your first profile/i })).toBeInTheDocument();
|
expect(screen.getByRole('button', { name: /Create your first profile/i })).toBeInTheDocument();
|
||||||
expect(screen.getByText(/A Nostr profile is your identity/i)).toBeInTheDocument();
|
expect(screen.getByText(/A Nostr profile is your identity/i)).toBeInTheDocument();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ describe('HomeScreen', () => {
|
||||||
const { onCreateProfile } = renderHome(backend);
|
const { onCreateProfile } = renderHome(backend);
|
||||||
renderWithApp(<HomeScreen onNavigate={vi.fn()} onCreateProfile={onCreateProfile} />);
|
renderWithApp(<HomeScreen onNavigate={vi.fn()} onCreateProfile={onCreateProfile} />);
|
||||||
|
|
||||||
expect(await screen.findByText('Welcome to Keynectr')).toBeInTheDocument();
|
expect(await screen.findByText('Welcome to Keynctr')).toBeInTheDocument();
|
||||||
await userEvent
|
await userEvent
|
||||||
.setup()
|
.setup()
|
||||||
.click(screen.getByRole('button', { name: /Create your first profile/i }));
|
.click(screen.getByRole('button', { name: /Create your first profile/i }));
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ describe('SettingsScreen', () => {
|
||||||
installFakeBackend(backend);
|
installFakeBackend(backend);
|
||||||
renderWithApp(<SettingsScreen />);
|
renderWithApp(<SettingsScreen />);
|
||||||
|
|
||||||
expect(await screen.findByText(/Keynectr v/)).toBeInTheDocument();
|
expect(await screen.findByText(/Keynctr v/)).toBeInTheDocument();
|
||||||
expect(screen.getByText('Rust (nostr-sdk)')).toBeInTheDocument();
|
expect(screen.getByText('Rust (nostr-sdk)')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue