Commit graph

70 commits

Author SHA1 Message Date
Adam Brown
e25d80c051 Prepared for release: v3.8.2
Some checks failed
Build CI / build (push) Has been cancelled
Build CI / static-analysis (push) Has been cancelled
Build CI / android-instrumented-tests (push) Has been cancelled
Build CI / iOS compile & test (push) Has been cancelled
Build CI / iOS UI tests (push) Has been cancelled
PublishInternal / publish-google-play (push) Has been cancelled
2026-08-11 01:05:31 -07:00
Adam Brown
51f79a8631 Prepared for release: v3.8.1
Some checks are pending
Build CI / build (push) Waiting to run
Build CI / static-analysis (push) Waiting to run
Build CI / android-instrumented-tests (push) Waiting to run
Build CI / iOS compile & test (push) Waiting to run
Build CI / iOS UI tests (push) Waiting to run
PublishInternal / publish-google-play (push) Waiting to run
2026-08-08 14:34:38 -07:00
Adam Brown
1c856dc32b
Fix the F3 sync and Ctrl+Alt+S shortcuts, and give them to Android and iOS (#865)
Some checks are pending
Build CI / build (push) Waiting to run
Build CI / static-analysis (push) Waiting to run
Build CI / android-instrumented-tests (push) Waiting to run
Build CI / iOS compile & test (push) Waiting to run
Build CI / iOS UI tests (push) Waiting to run
PublishInternal / publish-google-play (push) Waiting to run
* Handle F3 and Ctrl+Alt+S on the project window

Both shortcuts hung off a Modifier.onPreviewKeyEvent in ProjectRootUi, so
they only fired when focus sat inside the project subtree and did nothing
from the home screen. Move them to the window onKeyEvent that already owns
Esc, Ctrl+W, Ctrl+Q and Ctrl+Shift+F.

F3 now goes through ProjectRoot.startProjectSync(), which opens the sync
modal only for server-linked projects, restoring the gate the old sync menu
item had.

* Match shortcut modifiers exactly and run them pre-focus

F3 and Ctrl+Alt+S were hand-rolled in the window's when-chain, which
dropped the exact-modifier matching onKeyShortcut enforced: Ctrl+F3 and
Ctrl+Alt+Shift+S both fired. Extract that predicate as
KeyEvent.matchesShortcut and use it for both.

Move the two to onPreviewKeyEvent as well. onKeyEvent only runs when
nothing on the focus path consumed the key, so a focused editor could
swallow them; the docs claimed otherwise. The other window shortcuts stay
on onKeyEvent so a focused component can still handle Esc first.

* Give Android and iOS the project shortcuts back

Moving F3 and Ctrl+Alt+S to the desktop window left the other platforms
with nothing. Add ProjectShortcutHost, which ProjectRootScaffold binds
while the project UI is composed, and drive it from each platform's own
key hook: Activity.dispatchKeyEvent on Android and UIKit key commands on
iOS. Both are focus independent, which the Compose modifiers were not.

The iOS container lives in Swift because keyCommands is an Objective-C
category member and Kotlin cannot override those.

* Bind the project shortcuts in one place

Desktop kept its own copy of the save-all action while Android and iOS went
through ProjectShortcutHost. Move the binding down to ProjectRootUi, the one
composable all three platforms render, so each host only detects keys and
calls the host object.

That also lets the window drop the snackbar state and coroutine scope it had
hoisted purely to run the action.
2026-08-07 00:45:59 -07:00
Adam Brown
c1fac8ff1e Prepared for release: v3.8.0 2026-08-04 21:47:41 -07:00
Adam Brown
22520baca3
Fix flaky iOS scene-editor save UI test (#786)
tapUntilGone gated the save tap solely on isHittable. Under CI load the
top-bar save button's accessibility frame can never settle to hittable
within the timeout, so the loop waited out the whole budget without ever
tapping and failed with 'Element still present after 20.0s'.

Keep the proven isHittable hit-tested fast path and add a geometry
fallback: once the button's frame has settled (fully below the status
bar, ruling out the transient dead-pixel position, and stable across two
samples) tap it via tapCenter. This guarantees a tap eventually fires
even when isHittable never flips true, while still avoiding the
dead-pixel/scroll-away hazard the isHittable gate originally fixed.
2026-07-28 22:38:18 -07:00
Adam Brown
fdeab5b992 Prepared for release: v3.7.2 2026-07-27 13:45:42 -07:00
Adam Brown
3375d81b55 Prepared for release: v3.7.1 2026-07-23 14:36:28 -07:00
Adam Brown
8742202de5 Prepared for release: v3.7.0 2026-07-21 09:10:11 -07:00
Adam Brown
fab1da62de Revert "Prepared for release: v3.7.0"
This reverts commit 9bfc9ec8e1.
2026-07-21 09:01:45 -07:00
Adam Brown
9bfc9ec8e1 Prepared for release: v3.7.0 2026-07-21 00:56:45 -07:00
Adam Brown
8bc1322c82
Retry the focus tap in the iOS UI test type() helper (#757)
A dropped coordinate tap left the field unfocused, so the software
keyboard never rose and the test failed on the single 10s wait.
Re-focus until the keyboard appears, matching typeIntoEditor.
2026-07-20 10:29:31 -07:00
Adam Brown
57f4f2a9fe
Harden flaky iOS scene-editor UI test with tap-retry helpers (#741)
* Harden flaky iOS scene-editor UI test with tap-retry helpers

SceneEditorWorkflowUITests.testEditSceneTextThenSave intermittently timed
out (most visibly waiting 20s for the save affordance to disappear). The
UI is Compose Multiplatform, which renders to a single surface, so
XCUITest taps are best-effort coordinate taps onto that surface. An
individual tap can be silently dropped (mid-relayout, under simulator
load, or while the software keyboard geometry is shifting). A lone tap
followed by one long wait is the classic XCUITest flake: a single dropped
tap costs the whole timeout and fails the test.

Add a small retry primitive and route the flake-prone taps through it:

- tapUntil(element, until:) re-taps on a short sub-timeout until the app
  demonstrably reacts, converging instead of eating the full timeout on
  one dropped tap.
- tap(_:expecting:) drives each scene-creation step by the element its
  tap surfaces (add menu, then the create-item dialog).
- tapUntilGone(_:) replaces the lone save tap + long wait; it also covers
  a late IME keystroke re-dirtying the buffer right after a save.
- openProjectCard re-taps the card until the project root's nav rail
  renders (same dropped-tap resilience), keeping its existing
  name/firstMatch card selection.

Validated by running the full iosUITests scheme on freshly-erased
simulators across 6 consecutive runs (all four UI test classes green
every run).

* Fix save-tap flake: only tap the save button when it's settled/hittable

CI surfaced the actual flake this test was meant to harden: the save tap
timed out because the button's accessibility frame is briefly stale right
after the edit that surfaces it — reported up under the status bar (a dead
pixel) until the top-bar layout settles. Blindly re-tapping that stale
coordinate never saved and could even scroll the app away from the editor,
so the re-tap loop ran the full timeout and failed.

Make tapUntilGone tap only when the button reports itself hittable
(settled), using a hit-tested tap() that re-resolves its real position;
otherwise wait for it to settle. Left untouched, the button stays hittable
even under load, so this converges cleanly instead of fighting a dead spot.

Scoped to the save helper; the navigation/card taps are unchanged.

Validated on a CI-sized simulator (iPhone 16e, 390x844) across 6 runs
under CPU load, all green.
2026-07-16 17:56:29 -07:00
Wavesonics
cfd3fefb5c Promote iOS scene editor UI test to full edit+save flow
The iOS SceneEditorWorkflowUITests was scoped to "scene opens" rather than
the Android-parity edit->save flow because the scene-editor-save affordance
never surfaced to XCUITest. Root cause: the iOS EditorTopBar save IconButton
was missing the SCENE_EDITOR_SAVE_TAG testTag that the Android/desktop
variants carry, so even once the edit dirtied the buffer and the button
rendered, XCUITest had no accessibility identifier to find.

- Tag the iOS EditorTopBar save button with SCENE_EDITOR_SAVE_TAG.
- Add a typeIntoEditor(_:into:until:) helper to HammerUITest that re-focuses
  and re-injects until the edit propagates, mirroring the Android
  typeIntoEditor retry loop (guards the enabled=hasReceivedInitialBuffer
  gate on the initial buffer load).
- Promote testCreateSceneOpensEditor to testEditSceneTextThenSave: type into
  the editor, assert save appears, tap it, assert it disappears — matching
  SceneEditorWorkflowTest.editSceneTextThenSave.

Verified on iPhone 16 (iOS 18.6) simulator: TEST SUCCEEDED.
2026-07-14 23:01:08 -07:00
Adam Brown
c5c42f2938 Prepared for release: v3.6.1 2026-07-12 23:30:39 -07:00
Adam Brown
501de2e597 Prepared for release: v3.6.0 2026-07-07 23:22:53 -07:00
Adam Brown
177e4bbe4f Prepared for release: v3.5.3 2026-06-30 15:16:45 -07:00
Adam Brown
43a836844d
Add iOS UI smoke tests (XCUITest) (#707)
* Add iOS UI smoke tests (XCUITest)

Adds an iOS UI smoke-test suite that drives the real app on a simulator via
XCUITest, the iOS analogue of the android/src/androidTest Compose UI tests.
The whole iOS UI is Compose Multiplatform, and CMP (1.8+) maps Compose testTags
to iOS accessibilityIdentifiers automatically, so the tests target the same
testTags the Android suite uses.

Workflows covered (all green on simulator):
- LaunchSmoke: app boots through the SwiftUI entry point, Koin + data migration
  run, project selection renders.
- ProjectWorkflow: create + open a project (exercises the create dialog text
  entry and navigation into the editor).
- SceneEditorWorkflow: create a scene and confirm it opens in the editor.
- NotesWorkflow: navigate to Notes and open the create-note screen.

Setup:
- ios/scripts/add_ui_test_target.rb idempotently creates the iosUITests
  UI-testing target + shared scheme via the xcodeproj gem (the folder previously
  had source files but no actual target).
- ios/scripts/disable_sim_hardware_keyboard.sh forces the software keyboard so
  XCUITest text entry lands (Compose fields need it).
- ios-ui-tests CI job runs the suite on a simulator and uploads the xcresult on
  failure.
- composeUi ProjectCreateDialog: tag the name field so the create flow is
  targetable (also benefits Android).

Known limitation: the app's custom rich-text editors (scene body, note body via
MarkdownEditField) do not report keyboard focus to XCUITest, so their text entry
can't be driven (only standard Compose text fields can). The scene and notes
tests therefore stop at "editor opens" / "creation screen opens"; the full
edit/create-with-body paths remain covered by the Android suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* iOS UI tests: type into note body via composetexteditor 2.3.0

composetexteditor 2.3.0 publishes text-editing accessibility semantics on its
editor, so XCUITest can now drive text entry into it. Bump the dependency and
promote the Notes UI test to the full Android-parity flow: create a note by
typing into the body, then assert its card appears.

The scene edit+save flow stays scoped to "scene opens" for now — text entry
works, but the scene editor's initial-buffer gating + dirty-driven save make
the save affordance unreliable to assert from an IME-driven edit; promoting it
is a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:39:04 -07:00
Adam Brown
57de1c6522 Prepared for release: v3.5.2 2026-06-29 22:15:55 -07:00
Adam Brown
46ce5042d3 Prepared for release: v3.5.1 2026-06-27 23:51:29 -07:00
Adam Brown
1a0a50bd76 Prepared for release: v3.5.0 2026-06-27 00:39:39 -07:00
Adam Brown
3b23dc6cf0 Prepared for release: v3.4.2 2026-06-23 10:10:05 -07:00
Adam Brown
77f1eb1884 Prepared for release: v3.4.1 2026-06-23 00:45:34 -07:00
Adam Brown
080c403619 Prepared for release: v3.4.0 2026-06-22 22:02:40 -07:00
Adam Brown
49ba08b55a Prepared for release: v3.3.1 2026-06-16 00:34:56 -07:00
Adam Brown
18bcc4652f Prepared for release: v3.3.0 2026-06-13 12:44:51 -07:00
Adam Brown
6fd3fd15ae
Prepared for release: v3.2.1 2026-06-10 19:41:32 -07:00
Adam Brown
93de0e7fd1
Prepared for release: v3.2.0 2026-06-08 00:08:51 -07:00
Wavesonics
97bc5a1b1a Prepared for release: v3.1.3 2026-06-04 21:56:12 -07:00
Adam Brown
35ecc7b750
Prepared for release: v3.1.2 2026-06-03 00:37:43 -07:00
Adam Brown
6c705d11bb
Prepared for release: v3.1.1 2026-06-02 00:29:07 -07:00
Adam Brown
28d0d2bdf1
Prepared for release: v3.1.0 2026-06-01 23:10:53 -07:00
Wavesonics
2517bb80c6 Add manifest-driven asset generation pipeline
Replace ad-hoc icon scripts with a single source-of-truth manifest
  (scripts/assets.yaml) and a Python generator that renders every app icon,
  store-listing graphic, MSIX tile, favicon, and the Play feature graphic from
  two SVG sources. Compositions (icon + "Hammer" wordmark in Kingthings
  Trypewriter) are defined once as percentages of canvas and reused across the
  Play feature graphic, MSIX wide/splash tiles, and the Snap featured banner.

  Adds the missing snap store icon, fixes the snap desktop icon to the correct
  256x256 hicolor size, and routes uploads-only assets to build/store-assets/
  (gitignored).

  See docs/ASSET-GENERATION.md for the manifest schema.
2026-05-22 19:26:49 -07:00
Wavesonics
246914d10f Cleanup plist 2026-05-20 23:27:12 -07:00
Wavesonics
331ff2336c Prep iOS Info.plist + profile reference for App Store submission
Declare ITSAppUsesNonExemptEncryption=false so App Store Connect stops
asking on every upload, drop the legacy armv7 UIRequiredDeviceCapabilities
entry, and align CFBundleShortVersionString with the shared codebase
version (3.0.3) in gradle/libs.versions.toml. pbxproj now references the
freshly-issued "Hammer AppStore iOS" provisioning profile.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:16:31 -07:00
Wavesonics
496e05d934 clean up ios user files 2026-05-20 22:45:14 -07:00
Wavesonics
a3b077824a Add iOS support via Compose Multiplatform
iOS now runs the same shared Compose UI as Android and Desktop. The
existing Decompose component graph (IosRoot, ProjectSelection,
ProjectRoot) is reused; the Swift app shrinks to an AppDelegate, a
Koin bootstrap, and a UIViewControllerRepresentable that hands off to
a Kotlin ComposeUIViewController. The SwiftUI starter under
/ios/ios/ui and /ios/ios/DecomposeHelpers is deleted.

Hammer.framework moves from :common to :composeUi so the framework
ships the Compose entry point; Xcode's Run Script invokes
:composeUi:embedAndSignAppleFrameworkForXcode. iosArm64 and
iosSimulatorArm64 targets are declared with libbacktrace source-info
so K/N crashes report file:line. 17 expects across composeUi get iOS
actuals (file pickers via filekit, image loading via Coil3,
LanguageUtil via NSLocale.preferredLanguages, etc).

The adaptive nav scaffolds — bottom bar at compact width, side nav
rail otherwise — are extracted from the Android activities into
shared ProjectSelectScaffold and ProjectRootScaffold in
composeUi/commonMain, along with their Modifier helpers and the
close-confirm dialogs. Android activities are now thin shells that
delegate to these; iOS calls the same scaffolds, so phone/tablet
layout is unified across all three platforms.

App icon and CFBundleDisplayName set so the home screen reads
"Hammer" with the brand logo instead of the blueprint placeholder.
2026-05-20 00:36:29 -07:00
Wavesonics
327b5322cb Remove macos AppImage target format 2026-05-18 21:24:06 -07:00
Adam Brown
244cc78e3c
Drop iosX64 target (removed from Compose Multiplatform 1.11) 2026-05-13 21:58:48 -07:00
Adam Brown
4552279d75
Ios example project (#225)
* Implemented iOS example project installer zip file handling
2024-01-20 20:04:57 -08:00
Wavesonics
50ecb4f5f4 working on ios proj install 2024-01-15 13:33:05 -08:00
Wavesonics
baa193baca iOS proj select screen work 2024-01-15 13:26:01 -08:00
Wavesonics
3b5849a38d iOS seems to be up and running? 2024-01-15 13:10:05 -08:00
Wavesonics
c5f46cf71d ProjectList ios UI still sorta working 2024-01-15 00:30:38 -08:00
Wavesonics
50fb8a9569 Fix ios build 2024-01-15 00:05:56 -08:00
Wavesonics
13e99cf466 Fix ios build 2023-11-22 15:45:53 -08:00
Wavesonics
2a81346d02 Switch provisioning profile 2023-06-27 23:02:30 -07:00
Bill Booth
6cfe1a8388 Add ios build stage 2023-05-08 21:24:52 -07:00
Wavesonics
d9045cf741 ios signing 2023-05-07 22:26:44 -07:00
Wavesonics
0372f3f64e ios is building again 2023-04-17 23:57:31 -07:00
Adam Brown
f1165d3bf4 Upgraded to Decompose 2.0.0 alpha
- Kotlin 1.8.20
- Fixed some light/dark theme issues on Android
2023-04-13 20:23:37 -07:00