Compare commits

...

2 commits

Author SHA1 Message Date
5eb476a059 Fix landscape image rotating opposite to device
OrientationDetector mapped the OrientationEventListener angle to
Surface.ROTATION_* with 90 and 270 swapped relative to the CameraX
docs example. The angle reports the device's physical clockwise
rotation, whereas Surface.ROTATION_* describes the screen's logical
rotation (opposite direction), so the values must be inverted.

Symptom: rotating the phone clockwise rotated the live preview counter-
clockwise (and vice versa), instead of keeping world-up at screen-up.
The bug was previously masked because the only consumer of the value
(deviceRotation in capturePhoto) is unused — the live preview commit
(d321f07) wired this same value into CameraX's setTargetRotation, which
exposed the inverted mapping.

Bump to 1.1.7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 13:51:17 +02:00
fc64081712 Add dcat issue tracking setup
Introduce AGENTS.md with dcat workflow, .gitattributes merge driver for
dcat JSONL files, and .dogcats/ config + empty issue store. Update
CLAUDE.md to point agents at AGENTS.md and avoid the TodoWrite tool, and
ignore local-only dcat files (config.local.toml, .issues.lock).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 13:50:39 +02:00
8 changed files with 48 additions and 4 deletions

1
.dogcats/config.toml Normal file
View file

@ -0,0 +1 @@
namespace = "tilt-shift-camera"

0
.dogcats/issues.jsonl Normal file
View file

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Dogcat JSONL merge driver
.dogcats/*.jsonl merge=dcat-jsonl

2
.gitignore vendored
View file

@ -92,3 +92,5 @@ lint/tmp/
ehthumbs.db ehthumbs.db
Thumbs.db Thumbs.db
.signing/ .signing/
.dogcats/config.local.toml
.dogcats/.issues.lock

30
AGENTS.md Normal file
View file

@ -0,0 +1,30 @@
# Agent Instructions
## Issue tracking
This project uses **dcat** for issue tracking. You MUST run `dcat prime --opinionated` for instructions.
Then run `dcat list --agent-only` to see the list of issues. Generally we work on bugs first, and always on high priority issues first.
When running multiple `dcat` commands, make separate parallel Bash tool calls instead of chaining them with `&&` and `echo` separators.
Mark each issue `in_progress` right when you start working on it — not before. Set `in_review` when work on that issue is done before moving on. The status should reflect what you are *actually* working on right now.
It is okay to work on multiple related issues at the same time, but do NOT batch-mark an entire backlog as `in_progress` upfront. If there is a priority conflict, ask the user which to focus on first.
If the user brings up a new bug, feature or anything else that warrants changes to the code, ALWAYS ask if we should create an issue for it before you start working on the code. When creating issues, set appropriate labels using `--labels` based on the issue content (e.g. `cli`, `tui`, `api`, `docs`, `testing`, `refactor`, `ux`, `performance`, etc.).
When research or discussion produces findings relevant to an existing issue, ask these as **separate questions in order**:
1. First ask: "Should I update issue [id] with these findings?"
2. Only after that, separately ask: "Should I start working on the implementation?"
Do NOT combine these into one question. The user may want to update the issue without starting work.
### Closing Issues - IMPORTANT
NEVER close issues without explicit user approval. When work is complete:
1. Set status to `in_review`: `dcat update --status in_review $issueId`
2. Ask the user to test
3. Ask if we can close it: "Can I close issue [id] '[title]'?"
4. Only run `dcat close` after user confirms
5. Ask: "Should I add this to CHANGELOG.md?" — update if yes

View file

@ -101,3 +101,6 @@ Bitmaps emitted to `StateFlow`s are **never eagerly recycled** immediately after
- `minSdk = 35` (Android 15) — intentional for personal use. Lower to 26-29 if distributing. - `minSdk = 35` (Android 15) — intentional for personal use. Lower to 26-29 if distributing.
- Dependencies updated to March 2026 versions (AGP 9.1, Kotlin 2.3, Compose BOM 2026.03). - Dependencies updated to March 2026 versions (AGP 9.1, Kotlin 2.3, Compose BOM 2026.03).
- Fragment shader uses `int` uniform branching in GLSL ES 1.00 — works but could be cleaner with ES 3.00. - Fragment shader uses `int` uniform branching in GLSL ES 1.00 — works but could be cleaner with ES 3.00.
## Issue tracking & task management
- Do NOT use the `TodoWrite` tool in this project. Issue tracking and progress is managed with **dcat** as specified in `AGENTS.md` — see that file for the full workflow (`dcat prime --opinionated`, `dcat list --agent-only`, status transitions, closing rules, etc.).

View file

@ -24,11 +24,17 @@ class OrientationDetector(private val context: Context) {
override fun onOrientationChanged(orientation: Int) { override fun onOrientationChanged(orientation: Int) {
if (orientation == ORIENTATION_UNKNOWN) return if (orientation == ORIENTATION_UNKNOWN) return
// OrientationEventListener reports the device's physical rotation
// (clockwise from natural). Surface.ROTATION_* describes the screen's
// logical rotation, which is the opposite direction — so device tilted
// 90° CW (orientation ≈ 90, "left side at top") maps to ROTATION_270,
// and 90° CCW (orientation ≈ 270) maps to ROTATION_90. Matches the
// CameraX docs example for setTargetRotation.
val rotation = when { val rotation = when {
orientation >= 315 || orientation < 45 -> Surface.ROTATION_0 orientation >= 315 || orientation < 45 -> Surface.ROTATION_0
orientation >= 45 && orientation < 135 -> Surface.ROTATION_90 orientation >= 45 && orientation < 135 -> Surface.ROTATION_270
orientation >= 135 && orientation < 225 -> Surface.ROTATION_180 orientation >= 135 && orientation < 225 -> Surface.ROTATION_180
else -> Surface.ROTATION_270 else -> Surface.ROTATION_90
} }
if (rotation != lastRotation) { if (rotation != lastRotation) {

View file

@ -1,4 +1,4 @@
versionMajor=1 versionMajor=1
versionMinor=1 versionMinor=1
versionPatch=6 versionPatch=7
versionCode=8 versionCode=9