Skip to content

Develop - #4

Merged
EarMaster merged 12 commits into
mainfrom
develop
Aug 5, 2026
Merged

EarMaster merged 12 commits into
mainfrom
develop

Conversation

@EarMaster

Copy link
Copy Markdown
Owner

No description provided.

EarMaster and others added 12 commits August 5, 2026 11:38
The upload action deprecated the singular `track` and warns on every
run; it also rejects the build outright if both forms are set, so this
is a swap rather than an addition.

The workflow's own input stays singular: it passes exactly one track,
and renaming it would churn release.yml and the dispatch UI for nothing.
It now falls back to `internal` at the call site as well as in the input
default, because the action uploads to *production* when it receives no
track at all — not a default worth reaching by accident.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
[record-screenshots]

The only link Coil answered started a favourite, which is the wrong tool
for "put the app on screen" — and for a particular box, there was no way
to ask at all.

`coil://open` opens the app; `coil://open?box=<id>` opens it showing
that box. A separate host rather than a play link with the target left
off, because the two do different things and are worth telling apart in
a note or an automation app: a play link reaches the box, this one never
does. That also makes it the less privileged of the two — all it can ask
for is what tapping the launcher icon already does, plus which of the
user's own boxes comes up.

`box` is optional here where a play link requires it: a folder path
means nothing without the box it came from, but "just open the app" is a
complete request. The id is checked against the configured boxes before
use, since setActive writes straight to settings and a stale link would
otherwise point the app at a box that does not exist.

Settings hands the link out per box, for the same reason a favourite's
menu does: the id is a UUID shown nowhere else, so `?box=` would be
unusable otherwise. The share-sheet helper moved to ui/components to be
shared with the favourites screen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
[record-screenshots]

Every string added since these files were first written had gone in as
English only — the sleep timer, search, the details sheet, the library
crawl, the links, and the settings rows added yesterday. 46 keys, missing
in all four translated locales.

Nothing reported it. Android falls back to the source locale silently, so
each feature looked finished while three of the five launch locales
showed English in the middle of a translated screen; `library/folders_de`
had been showing "Search the library" over German tabs since the day it
was recorded. MissingTranslation was configured as a warning and scrolled
past.

Also adds the CLDR "many" category to the French and Spanish plurals,
which lint had been asking for on the three freshness labels as well.

Drafts, marked as such, in the same standing as the rest of these files:
they still need a fluent speaker. Absence was the worse failure, because
a draft gets reviewed and an absence does not — AGENTS.md now says a new
string lands in all five locales in the same change, and names the lint
check that proves it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Picking a box, adding a box and editing the current box sat next to each
other in settings as rows of the same shape, so the section read as three
overlapping ways to say "box". Box management is now its own screen with
a page per box, behind one "Manage boxes" row.

Both screens address a box by id rather than through "the active box", so
a box that is not active can be renamed or re-addressed without switching
to it first — previously impossible, since every field described whichever
box was active. Switching stays in the top bar only; the library actions
stay in settings, because they run against the active box.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A Phoniebox serves artwork over plain HTTP from its own web server, and
Android refuses cleartext by default at targetSdk 28 and up, so every
cover request was rejected before it left the phone. Verified against a
real box that the protocol side was never at fault: playerstatus.file ->
get_single_coverart -> the HTTP fetch all answer correctly.

It has to be a base-config rather than a domain-config, because the box
address is entered at runtime and this file is fixed at build time.

Two things hid this through an earlier hardware run: the ZMQ sockets are
raw TCP and so were never subject to the policy, leaving everything but
covers working; and the cover error branch draws the same placeholder as
a song with genuinely no artwork. The image loader now carries a
DebugLogger in debug builds so the next such failure names its reason.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The site was a single Markdown page from before there were
screenshots or a settled feature set. It now has a hero, the twelve
features, phone and tablet galleries, a lightbox and a links panel.

Built on emilbaehr/automatic-app-landing-page (MIT). Vendored rather
than used via remote_theme, because the theme keeps index.html and
main.scss at its repo root while remote_theme only pulls _layouts,
_includes, _sass and assets; its licence notice travels along in
docs/pages/_THEME-LICENSE.txt.

The theme is written for iOS apps, so the parts that assumed one had
to go. The iPhone body and its notched clip-path were sized 1125x2436
and squashed Coil's 1233x2460 shots; it is now a CSS Android bezel
that takes its height from the image. The unconditional App Store
badge and apple-itunes-app banner became a Play badge and a Releases
button. The itunes.apple.com lookup that filled in icon, name and
price at page load is gone, along with the jQuery it needed.

The tablet strip is a curated three. The 10-inch player and sleep
timer use the width properly, but library, favourites and search
still stretch the phone layout across 1280 dp, and showing those
advertises the weakest part of the tablet build. flattenStoreAssets
now copies all three sets to the site so that choice stays a
_config.yml edit.

ci.yml gains a Pages build, since pages.yml only runs on main and a
broken template would otherwise reach the live site unnoticed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"Show controls" offered two settings and both put a notification up
sooner or later. A third, "Never", creates no media session at all.

The mode is enforced in MediaSessionBinder rather than the service: a
bound service outlives its own stopSelf, so dropping the binding is
what actually keeps media3 from posting a notification on the next
state == play. The service stops itself on the same setting, which is
what takes an existing notification down mid-playback.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The check could never pass. `github-pages build` sets
`exclude: [CNAME]` itself whenever the site's own `exclude` is Jekyll's
default, so the official builder strips docs/pages/CNAME from the
output on purpose. Removing the upstream theme's `exclude` block is
what put the config back on that default and armed the rule.

The custom domain is unaffected, and never depended on that file: the
Pages API reports cname=coilforphoniebox.app with build_type=workflow,
so the domain comes from the repository settings and nothing reads a
CNAME out of an Actions artifact.

A local `jekyll build` has no such rule and does copy CNAME, which is
why this only surfaced in CI. In its place, check that the galleries
and the hero frame actually rendered and that no Liquid tag was left
unprocessed — failures a missing-file test would not have caught.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The third session-mode option landed in bb71543 without its pictures, so
verifyRoborazziDebug failed on settings_ and settings_lower_ for phone
and tablet. The diff is the new row and the shift below it; nothing else
on those screens moved. Small is untouched — at 360x640 the group sits
below the fold in both goldens either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An ordinary build never compares the goldens — `./gradlew test` only
checks that every screen still composes — so a stale one survives
locally and CI is the first place it shows up. That is a bad moment to
find out during a release.

The new step works out whether the release touched UI or user-visible
strings without touching the screenshots folder, and treats that as
reason enough to run verify before committing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@EarMaster
EarMaster merged commit 3bc055b into main Aug 5, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant