Skip to content

Releases: Diffechento/MetroMusic

MetroMusic 1.2

Choose a tag to compare

@github-actions github-actions released this 06 Aug 22:04

A release about how the app feels under a thumb, and one about the queue being somewhere you can go.
Built on MangoTile 1.0.2.

Every gesture follows your finger, and lets go at the speed your hand had. A report after 1.1 that
"doing any gestures is a bit rough" turned out to be four separate faults being felt as one. The largest:
a settle handed the finger's velocity accepted it and ignored it, because only a spring reads that
argument and every settle was an easing curve — so each gesture ended with the speed jumping to whatever
the curve started at, at exactly the moment your hand was judging the result. Everything that follows a
drag now ends on a critically damped spring given the gesture's own velocity: still an ease-out, with no
bounce and no seam where the finger lifts.

The player is dragged rather than nudged. Pulling the strip up used to move it 26dp, decide, and then
play a canned animation from wherever the page had got to — your hand doing one thing while your eye
watched another. The page's position is the drag now, and letting go only finishes a movement already
underway. One detector owns both of the player's axes, so a thumb thirty degrees off the horizontal no
longer starts the sideways swipe and the downward push at once.

And the player pages between tracks. The neighbouring tracks are laid out either side and your finger
moves all three, so the track that lands is the one that was visibly coming — instead of the screen
springing back to the middle and the change arriving afterwards as its own choreography, one movement of
which went the opposite way to the hand. Only the face pages: the slider, the times and the transport
belong to the player rather than to the track, and a swipe that carried the play button off the screen
would be moving the furniture to change a record. At the end of the queue the page resists instead of
flying a quarter of the screen and coming back to the same song.

The strip carries the top of the playing cover, because a player dropping back into a flat black bar
ends the movement by turning the artwork into a black rectangle. It is the same square the full player
draws — the cover at the screen's width, hung from the top of the page — so the strip shows its top,
pulling up draws the rest out from underneath, and the size never changes on the way.

The queue is a screen, one pull further up. The player comes out of the strip; pull it up again and
the queue comes out over it. Pushing it back down anywhere on the page, tapping its title, or Back puts
it away — the list hands the push over as soon as it has nothing left to scroll to, so a drag from the top
of the list or from the empty space under a short queue travels with your finger like any other page. The
way in has a mark of its own, a caret in the space under the transport, which opens it on a tap; it opens
on the track you are listening to rather than the top of a queue whose first forty songs have played.

Hold a row to pick it up, swipe it aside to remove it. Holding lifts the row under your finger and
dragging carries it a place at a time, with the list creeping while you hold it against either end.
Swiping sideways — either way — takes it out, with the word "remove" uncovered behind it at full strength
exactly where letting go would commit, so you are told where the threshold is instead of finding it out by
losing a song. There is no menu on this screen at all: both of the things you come here for are the row
itself moving under your hand. Three new switches on settings → gestures cover the lot, because the
upward pull shares an axis with the push that puts the player away and the sideways one shares a list with
scrolling.

Fixed: editing an album's tags did nothing on a release build — which is every build anyone has
installed. It worked in development throughout and listed an error per track on a phone. jaudiotagger
finds the class for each tag field by name and copies frames through a reflectively located constructor,
and minification is invisible to both, so the library could no longer build the field it was asked to
write. It did not say that: the message named the value, which is why the first report read as a problem
with Cyrillic text and was not one.

Fixed: the panorama went on taking a sideways swipe for a moment after it had visibly stopped moving,
so a scroll became a section change; and a band of tinted artwork appeared over the library while the
player was on its way up.


Scrobbling, the lyrics, the online cover lookup, sorting and the rest of playback are unchanged. The APK
carries the same signing certificate as 1.0, 1.0.1 and 1.1 (SHA-256 494018a9…2acf7c09), so it installs
over any of them as an update and keeps your settings, favourites, play counts and queue.

minSdk 26 · compileSdk 36 · GPLv3 · third-party notices are in the app, on settings → about.

MetroMusic 1.1

Choose a tag to compare

@github-actions github-actions released this 01 Aug 17:56

The first release with something in it that somebody asked for: sorting, from
issue #1. Built on
MangoTile 1.0.1.

Songs, albums and artists can each be arranged four ways. Hold a group header — the letter square,
or whatever the heading says — and the arrangements unroll out of it.

  • songs — name, date added, length, times played
  • albums — name, artist, date added, year
  • artists — name, songs, albums, times played

Every arrangement keeps its headings, so ordering by a number you cannot see still tells you where you
are: a run headed "5-19 plays" or "march 2026" instead of a list whose order you have to infer. Tapping
a heading zooms out over the groups exactly as the alphabet already did, so you can jump straight to
1997 or to the songs you have played most. Each section remembers its own arrangement, and tapping a
row plays the list as arranged rather than carrying on alphabetically from wherever that track sat.

The library screens got a row and a half of space back. The panorama's title was spending 83dp
above its own letters and 63dp below them; it now clears the status bar by inset rather than by a
hand-picked 52dp, and the blank the font reserves above the capitals is trimmed away. On a 1080x2400
screen a section's first row started 788px down and now starts at 609px.

And the title rolls away when you scroll. It gives up its height rather than sliding over the list,
so the list grows into the space, and it comes back when you drag past the top. On an album page the
cover, the numbers and the app bar go with it — fourteen tracks fill the screen instead of six. There
is a switch for it in settings → interface, because the title is also how some people know where they
are.

Fixed: a banner ("added to queue", the volume strip) used to sit in a screen-sized window, so
nothing underneath it was clickable for the two seconds it was up.


Scrobbling, the lyrics and the online cover lookup are unchanged, as is the rest of playback. The APK
carries the same signing certificate as 1.0 and 1.0.1 (SHA-256 494018a9…2acf7c09), so it installs
over either as an update and keeps your settings, favourites, play counts and queue.

minSdk 26 · compileSdk 36 · GPLv3 · third-party notices are in the app, on settings → about.

MetroMusic 1.0.1

Choose a tag to compare

@github-actions github-actions released this 29 Jul 10:22

Packaging only. The application is unchanged from
1.0 — it scans, plays and scrobbles
exactly as that did — and this release exists so the app can be built from source by F-Droid
instead of distributed as a binary.

The release build no longer insists on signing itself. F-Droid's builder edits the Gradle file
before it builds: it deletes the signingConfigs { } block and every line matching
signingConfig = <one token>, and signs the result with its own key. The config here was assigned
over two lines, findByName("release") ?: getByName("debug"), of which their pattern matched only the
first — leaving a dangling ?: that does not compile. The choice is now made in a val above, so the
line they remove is a single token and what is left builds unsigned, which is what they want. Proven
by running their own remove_signing_keys over a clone and building it: app-release-unsigned.apk,
the first thing their build looks for.

A local assembleRelease is unaffected: with keystore.properties it signs with that key, without it
with the debug key, and the APK attached here carries the same certificate as 1.0
(SHA-256 494018a9…2acf7c09), so it installs over it as an update.

The app's page now lives in the repository, at fastlane/metadata/android/en-US: title, short and
full descriptions, the launcher icon rendered out of the vector the app itself draws, five screenshots
and a changelog per version code. F-Droid reads it from the same commit it builds, so the page and the
binary cannot drift apart.


minSdk 26 · compileSdk 36 · GPLv3 · third-party notices are in the app, on settings → about.

MetroMusic 1.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 08:48

A music player for Android in the Windows Phone 8 idiom, built on
MangoTile. It plays what is already on the phone, and
everything that talks to the network is optional.

The library is the start screen. The panorama you land on is it — artists, albums, songs,
genres, more, history and settings, circular, so settings sit one swipe to the left of where you
start and anything is one swipe from launch. Long lists carry the WP8 jump grid over Latin and
Cyrillic; tapping a section header searches inside that section; a cover flows into the page it opens.
The full player rises out of the mini player rather than arriving as a page.

Playback is Media3 in a media session: notification, lock screen, headset and Bluetooth controls,
audio focus, and playback that outlives the activity. Sleep timer with a fade, equalizer over the
device's own bands, a volume banner in place of the system panel, and a home-screen tile.

Apple Lossless is decoded in the app. Android ships no ALAC decoder, and where there is none
Media3 raises no error: it marks the track unsupported, renders nothing, and runs the position against
the clock — a player that appears to play an album in silence. There is now a software decoder behind
a renderer added after the platform's own, at 16 and 24 bits, hi-res not cut down on the way
through. The length of a file whose duration MediaStore leaves empty is measured from the container.

The queue survives being closed. It comes back paused and at the start of the track, resolved
from the library by id. play next inserts after the last block queued rather than always next, so
several albums play in the order they were picked.

Names that real files spell badly. One credit string is split into several artists (feat., &,
,, vs.) and filed under every one of them, with the display credit left alone; genre tags that
differ only in case or punctuation fold onto the spelling most of the library uses. Album metadata is
written to the tags inside the files, which is the only level where a save sticks from Android 10 on.

Last.fm and Genius, both optional. Scrobbling is local-first: a play is written to disk with the
second it started and sent when a validated network appears, so an hour underground turns up in the
right order. Favourites can be kept the same as loved tracks, in both directions, as a three-way merge
that only ever compares music actually on the device. Covers are fetched for albums whose files have
none, and lyrics are read from Genius with no API token.

Twenty accents, light and dark, one backdrop behind every page, switchable gestures, and every string
in strings.xml with counts through <plurals>.


minSdk 26 · compileSdk 36 · GPLv3 · third-party notices are in the app, on settings → about.