Commit graph

518 commits

Author SHA1 Message Date
renovate[bot]
86dbe1219b
Update Gradle to v9.5.1 (#438)
* Remove macos AppImage target format

* Update Gradle to v9.5.1

---------

Co-authored-by: Wavesonics <adamwbrown@gmail.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-29 22:46:41 -07:00
renovate[bot]
a38fff2465
Update dependency io.zonky.test.postgres:embedded-postgres-binaries-bom to v17.10.0 (#529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-29 22:45:56 -07:00
Adam Brown
f837d66729
Downgrade AGP 2026-05-28 22:13:57 -07:00
Adam Brown
9e44fdf394
lib bumps 2026-05-28 21:42:09 -07:00
renovate[bot]
ec5240bfa4
Update dependency com.darkrockstudios:epub4kmp-core to v0.3.0 (#510)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 00:56:32 -07:00
renovate[bot]
dc25b8ca21
Update android.gradle.plugin to v9.2.1 (#502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 00:41:33 -07:00
Adam Brown
08c8b1791f
Replace vendored kzip with no.synth:kmp-zip dependency (#509)
Delete the in-tree de.jonasbroeckmann.kzip ZIP format implementation
(~700 lines across commonMain/jvmMain/iosMain) and the kompress.core
dependency, in favor of the published no.synth:kmp-zip 0.11.3 library
plus its okio adapter.

ZipUtils now wraps zipTo/unzipFrom for directory operations and uses
the synchronous ZipInputStream(ByteArray) constructor for the in-memory
extract path, removing the previous write-temp-file workaround. The
skipHiddenFiles parameter is dropped (production callers already passed
false) and the corresponding tests are removed.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-27 00:02:25 -07:00
Adam Brown
6fcd09f4ba
Upgrade database libs 2026-05-26 00:25:11 -07:00
Adam Brown
912a636c0e
Fix junit 2026-05-26 00:20:59 -07:00
Adam Brown
6851e3a98f
Upgrade UI libs 2026-05-26 00:17:57 -07:00
Adam Brown
3ed57a5986
Style the epub export better 2026-05-24 10:45:58 -07:00
Adam Brown
88ffe142d5
Add epub export format
Also refactor the export system, much cleaner now
2026-05-24 10:22:05 -07:00
Adam Brown
77e553cb3b
Polish the prepareForRelease dialog
- Switch to FlatLaf (Darcula) for an IntelliJ-grade look and feel.
  Lives in buildSrc only — never ships in the released app.
- Restructure the dialog into TitledBorder sections: Version,
  Publish scope, Will push tag, Changelog.
- Replace the always-on checkbox grid with an All / Targeted scope
  toggle. Full release (the common case) is now one click and shows
  the bare vX.Y.Z tag; Targeted enables the per-store checkboxes.
- Make the computed tag the dialog's focal point — large monospaced
  bold, italic + dimmed when no platforms are picked.
- Right-align Commit button, live-update window title to show the
  version transition, bump frame size for more changelog room.
2026-05-24 01:17:19 -07:00
Adam Brown
7f5e65df53
Fix #504
Skia version mismatch, downgrade CMP until its fixed
Also remove alpha picker in theme screen, we dont need it
2026-05-23 02:21:31 -07:00
Adam Brown
8f2592ad58
Merge branch 'postgres-server-refactor' into develop
Migrate the sync server's storage from SQLite to PostgreSQL with two
drivers: an in-process Zonky embedded server (the personal-install
experience) and a remote-Postgres mode (for multi-tenant deployments).
Single dialect, single set of .sq files, single set of DAOs.

The v1 schema bakes in Tier 1+2 cleanup: CITEXT for case-insensitive
columns, UUID for project ids, TIMESTAMPTZ everywhere, real BOOLEANs,
BIGSERIAL keys, partial indexes for sparse columns, and explicit ON
DELETE behavior plus CHECK constraints on every table.

A one-shot SQLite-to-Postgres migrator runs at startup against an
existing ~/hammer_data/server.db, copies it row-by-row in a single
transaction, verifies row counts in-transaction, then renames the
source to server.db.migrated-<ts>.bak. --migrate-dry-run lets operators
rehearse against a copy of production.

Verified:
- :server:test 409/0/0/0 (~2 min, embedded Postgres shared across the
  JVM with truncate-between-tests)
- :integrationTests:jvmTest 9/0/0/0 (~54s)
- :desktopTest green via pre-commit hook
- Embedded-mode boot smoke against a fresh ~/hammer_data
- Remote-mode boot smoke against a Postgres 16 container, schema landed
  cleanly with CITEXT/UUID/TIMESTAMPTZ promotions intact.

Notable carry-overs documented for ops:
- auth_token PK changed from `token` to (user_id, install_id); the
  migrator collapses any historical duplicates via ON CONFLICT.
- One-shot migration is irreversible; an off-box backup of server.db
  is the operator's job, not a replacement for the in-process .bak.
- 120MB of embedded Postgres binaries are now bundled in the server
  jar (one of five platform artifacts is extracted at boot).
- Pre-commit hook now skips :server:test; CI should still run it.
2026-05-22 23:30:23 -07:00
Adam Brown
7f2dea41a5
Remove flatpakGradleGenerator
We only needed this for flathub which we gave up on
2026-05-22 23:30:04 -07:00
Adam Brown
d22b6f9120
Migrate server storage from SQLite to PostgreSQL
The server now persists its sync state to PostgreSQL, with two interchangeable
drivers selected by `storage.type` in the TOML config:

  * EMBEDDED (default): in-process Zonky Postgres on a pinned port, data dir
    `~/hammer_data/pgdata`. Preserves the "single JAR, no external services"
    feel of the old SQLite setup for personal installs.
  * REMOTE: HikariCP-pooled JDBC to an externally-managed Postgres for
    multi-tenant deployments.

Schema is laid in at v1 with Tier 1 + Tier 2 features baked in:
  * TIMESTAMPTZ AS Instant for every timestamp column (via
    `InstantColumnAdapter`).
  * BOOLEAN columns (was `INTEGER AS kotlin.Boolean`).
  * BIGSERIAL primary keys.
  * CITEXT extension promoted onto `account.email`, `account.pen_name`, and
    `white_list.email` after `Schema.create()` for case-insensitive UNIQUE
    indexes.
  * Explicit `ON DELETE` per FK; partial UNIQUE index on `account.pen_name`;
    partial index for community-author lookup; CHECK constraints for length
    and `expires > created` invariants.
  * `INSERT ... ON CONFLICT DO UPDATE` for upserts; insert-then-lookup
    pattern replaces `last_insert_rowid()` triple-queries.

UUID promotion for `project.uuid` and `deleted_project.uuid` is deferred to a
follow-up release; existing tests pass placeholder strings that fail UUID
validation.

The legacy SQLite SqlDelight setup moves to
`src/main/sqldelight-legacy-sqlite/.../legacy/` and stays compiled as a
read-only `LegacySqliteDatabase` so the one-time migrator can stream rows
from it.

`SqliteToPostgresMigrator` runs at startup when a legacy `server.db` is
present alongside a Postgres-configured server: copies row-for-row inside a
single Postgres transaction with `session_replication_role = replica` to
suppress FK checks during the bulk insert, runs a row-count parity check on
the same connection, commits, and renames the source file to
`server.db.migrated-<timestamp>.bak`. A `--migrate-dry-run` CLI flag runs
the same flow but rolls back, for staging rehearsal.

Downstream consumers (DAOs, repositories, frontend pages) updated to use
`kotlin.time.Instant` directly instead of SQLite-flavored date strings.
2026-05-21 00:28:06 -07:00
Wavesonics
c8336b54af Update gradle 9.5.0 2026-05-18 21:09:52 -07:00
Wavesonics
7664c1fe8d Upgrade to Gradle and AGP 9 2026-05-18 18:48:39 -07:00
renovate[bot]
4349c3193c
Update nucleus to v1.15.5 (#493)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-17 20:10:18 -07:00
Adam Brown
90ed8e0fd5
Switch desktop window chrome to Material3-themed DecoratedWindow and MaterialTitleBar 2026-05-17 14:54:46 -07:00
Adam Brown
3f9c497657
Add recent-projects launcher menus for Linux (D-Bus quicklist) and macOS (Dock menu), reaching parity with the Windows jump list. All three platforms are now unified behind a QuickShortcuts interface so callers don't care which OS they're on. Pulled the shared "top N projects by lastAccessed" pipeline up onto ProjectsRepository.getRecentProjects() (used by the desktop and Android shortcut managers), and replaced scattered os.name string-matching with a typed HostOs enum. 2026-05-17 14:40:56 -07:00
Adam Brown
6762eb61e6
Add deep linking to Desktop!
You can now deep link to any project and even entity inside that project.
Added jumplist support for windows to deep link directly to a project
2026-05-17 13:35:40 -07:00
Adam Brown
35b0d7e937
Prepared for release: v3.0.3 2026-05-17 01:26:30 -07:00
Adam Brown
9ebcf795b2
Library updates 2026-05-17 01:23:05 -07:00
Adam Brown
241bfec73f
Library updates 2026-05-17 01:12:52 -07:00
Adam Brown
6acd022c78
Unblock F-Droid builds while keeping JBR for desktop (#490)
When -Pfdroid=true (or FDROID_BUILD env var) is set:
  - skip the foojay-resolver-convention plugin
  - exclude :desktop from the build (its eager jbrLauncher.get()
    needs JBR, which F-Droid can't provide)
2026-05-16 20:49:53 -07:00
Adam Brown
1a6316aad9
Prepared for release: v3.0.2 2026-05-15 00:31:21 -07:00
Adam Brown
18febe2e60
Prepared for release: v3.0.1 2026-05-14 21:54:12 -07:00
Adam Brown
6112eaac49
Prepared for release: v3.0.0 2026-05-14 01:46:43 -07:00
Adam Brown
4b19951655
Remove Nucleus from build pipeline (keep runtime libs)
Reverts the Nucleus packaging port and its follow-ups:
  - 93c7973c Trying nucleus for packaging Snap stays bespoke
  - 7c14bcd5 Broaden artifact staging to handle Nucleus sandboxed pipeline paths
  - d24f6183 Add homepage and debMaintainer for electron-builder
  - 8831e9c5 Update release workflows for Nucleus packaging
  - 4af31163 Port :desktop packaging to Nucleus framework

Compose Desktop is back as the packaging backend (jpackage targets,
custom packageMsix task, bespoke buildDistSnap/AppImage/Flatpak via
registerLinuxDistributionTasks). The Nucleus runtime libraries —
nucleus.darkmode-detector and nucleus.decorated-window-jbr — are
kept for window decoration and dark-mode detection in code, along
with the JBR jvmToolchain vendor pin and the libs.versions.toml
'nucleus' version entry that they depend on.

The Nucleus-pipeline state is preserved on branch
'nucleus-build-pipeline' for future reference.
2026-05-14 00:49:10 -07:00
Adam Brown
f4cd7f9eb7
Update libs
- Clean up jewel
2026-05-13 21:58:48 -07:00
Adam Brown
60416a6c43
No longer needed now that we're using JBR 2026-05-13 21:12:59 -07:00
Adam Brown
1e0050aff3
Switch to the JBR runtime 2026-05-13 20:42:51 -07:00
Adam Brown
276b2c7352
Remove unused Darklaf theme dependency 2026-05-13 19:59:52 -07:00
Wavesonics
6fd67c59c1
Apply Nucleus Linux HiDPI fix
Detect the native Linux desktop scale factor and feed it to AWT via
sun.java2d.uiScale before Swing initializes. No-op on macOS/Windows and
on JetBrains Runtime (which detects scale natively); needed for any
non-JBR JVM and for future GraalVM Native Image builds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 19:22:11 -07:00
Wavesonics
ae5baf7695
Use Nucleus JNI decorated window with Jewel styling
Wrap desktop windows in JewelDecoratedWindow + JewelTitleBar so the app
draws its own title bar (works on any JVM, no JBR needed). Adds nucleus
decorated-window-jni + decorated-window-jewel artifacts, plus the Jewel
int-ui-standalone dep for the IntUiTheme wrapper that JewelDecoratedWindow
reads its colors from. Jewel artifacts live in the IntelliJ snapshots
repo (cache-redirector path resolves to cloudfront 404, the direct
www.jetbrains.com URL works).

DecoratedWindowScope implements FrameWindowScope, so the existing
EditorMenuBar (which uses FrameWindowScope.MenuBar) keeps working — the
JMenuBar will render below the custom title bar on Windows/Linux, and on
macOS it stays in the system menu bar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 19:22:11 -07:00
Wavesonics
950e5c9c55
Replace jSystemThemeDetector with Nucleus dark-mode detector
Swaps the bespoke OsThemeDetector for Nucleus's dark-mode detector.
The non-composable initial LAF install uses getPlatformDarkModeDetector(),
and the live-update path inside application{} uses the isSystemInDarkMode()
composable so theme changes recompose without a manual listener.

Drops the explicit jna / jna-platform deps that only existed to back-fill
jSystemThemeDetector's transitive graph.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 19:22:11 -07:00
Wavesonics
4af31163b2
Port :desktop packaging to Nucleus framework
Replaces Compose Desktop's bespoke nativeDistributions + the hand-rolled
packageMsix, snapcraft, flatpak-builder, and appimagetool tasks with
the Nucleus plugin's unified DSL. Nucleus is a fork of compose-desktop-
application that adds first-class AppX/Portable/Snap/Flatpak/AppImage
targets, so org.jetbrains.compose can no longer be applied alongside
it (task name collisions); compose.desktop.currentOs and
compose.components.uiToolingPreview are now resolved via explicit
Maven coordinates instead.

The hand-edited msix/AppxManifest.xml, snap/snapcraft.yaml, and
flatpak/*.yaml are now generated from the DSL; the source files
remain in-tree for now and will be deleted once CI validates the
nucleus output across all targets.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 19:21:55 -07:00
Adam Brown
76883d7c25
Add Story Info home-screen widget
Resizable single-project stats widget (4x1 / 2x2 / 3x2 / 3x3+) showing
total word count, cadence-goal progress, today/streak, a 7-day sparkline,
and Open/Note actions. Adds a config activity for project selection.

Bumps Glance to 1.2.0-rc01 and wires up providePreview + setWidgetPreviews
so all three widgets render previews on Android 15+ pickers. Adds the
project name to the Add Note widget header. Extracts parseDailyWordTotals
and formatWidgetWords as shared helpers.
2026-05-12 12:03:44 -07:00
Adam Brown
078a869b97
Update text editor 2026-05-10 23:48:32 -07:00
Adam Brown
f272abbcc9
Lib bumps 2026-05-10 23:13:03 -07:00
Adam Brown
e867623ea7
Upgrade libs 2026-05-09 00:31:43 -07:00
Adam Brown
341d2c97e5
Add MarkdownEditField and MarkdownView, wire into Notes/Timeline/Encyclopedia
Notes, Timeline events, and Encyclopedia entries now share a markdown-aware
edit field (with format bar + spell-check) and a lightweight read-only
renderer that uses the editor's draw pipeline without its chrome.

Bumps composetexteditor to 1.8.2-SNAPSHOT (mavenLocal) for the new
RichTextView API; adds mavenLocal() to allprojects.repositories.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 10:04:51 -07:00
Adam Brown
683162f2ab
Lib bumps 2026-05-01 23:21:02 -07:00
Adam Brown
585c9919c5
Apply project theme to project window UI
Renames ProjectTheme.color1/color2 to primary/secondary and pipes them
into a Material 3 ColorScheme via material-kolor's dynamicColorScheme.
The user's secondary seeds both the Material 3 secondary and tertiary
palettes, the Rainbow palette style keeps them in distinct hue lanes
instead of collapsing toward the primary, and surfaceTint is redirected
to secondary so elevated surfaces (cards, dialogs, top bars) pick up
the accent.

The override is hoisted to the platform entry points
(ProjectEditorWindow.AppContent on desktop, ProjectRootActivity.Content
on Android) so a single ProjectThemeOverride wraps the NavigationRail,
ProjectRootUi, FAB stack, and confirm-close dialogs. ProjectRootUi and
ProjectRootFab no longer self-wrap.

All five project FABs (notes, encyclopedia, timeline, scene group,
scene) explicitly draw containerColor/contentColor from
secondaryContainer so the second color is the obvious accent on the
heaviest visible chrome.
2026-04-28 20:59:15 -07:00
Adam Brown
b1189d50dd
Add per-project synced settings (author, theme, word goal)
New project-data sync phase runs before entity transfer. The blob is a
single per-project row on the server, hash-checked for conflicts; the
client surfaces a per-field pick-a-side resolver UI when both sides
edited concurrently. Author name is a text field, custom theme uses a
clickable color swatch backed by skydoves/colorpicker-compose, and the
word-count goal is cadence + count. Each opt-in section nulls out its
data when unchecked so the wire signal is unambiguous.
2026-04-28 19:31:45 -07:00
Adam Brown
8831bb20ad
Prepared for release: v2.2.0 2026-04-26 20:25:35 -07:00
Adam Brown
0d6f87f480
Add Gradle toolchain/wrapper config and ignore .claude directory 2026-04-26 20:13:28 -07:00
Adam Brown
0b271cfcca
Add predictive back to FocusMode 2026-04-26 01:09:26 -07:00