Sürüm Notları
Songbook Buddy'nin en son güncellemeleri ve iyileştirmeleri.
Version 1.0.25
August 31, 2026
A large release built out of three weeks of device testing: 507 commits since 1.0.24, 101 reported problems closed, verified by roughly 4,400 automated tests and 217 hands-on checks on real Macs, iPads, an Android tablet, a Windows machine and a Linux box. The password-change story is finished on the other devices, "receive only" turned into a working mirror, and these are the fixes that came out of the campaign:
- Your other devices notice a password change themselves. Detection used to hang on sign-in only, so a device that stayed signed in kept pulling rows it could not decrypt and said nothing — thousands of failed fields, no hint, no prompt. The sync cycle now recognises a rotated key, stops touching the encrypted tables and asks for the new password. A second lock in the same app run asks again instead of leaving a red icon and no way in.
- A password change is no longer rolled back by another device. While the re-encryption sweep runs the library is half rotated; a second device holding the old key pulled the half it could not read, held it back and pushed it up again under the old key. A stale local copy can no longer overwrite a newer server row.
- A password change signs out your other devices, and the dialog says so. This used to be offered as an opt-in checkbox whose hint promised that, left unticked, the other devices stay signed in. Measured on a live account on 2026-08-28 with the box off: the second machine was signed out within minutes and the account was left with one session. The server ends those sessions whatever the client asks for, so the control was inert and its sentence untrue — both are gone, replaced by a plain statement of what happens. Signing out also clears the encryption key, which used to survive the sign-out and be reloaded on the next launch.
- The password change checks its precondition before it asks. On a device with an incomplete local mirror the dialog opened, three fields were filled in and GoTrue changed the password — and only then did the sweep refuse. It now states the situation up front, with an explicit "change it anyway". The forgotten-password flow warns before sending the mail that a reset does not unlock the cloud library.
- "Receive only" is a mirror with temporary edits. A receive-only device still writes into the outbox, but every sync cycle resets those edits to the server's state: fetch the server's rows by id, drop never-pushed local creations, purge. First-edit notice, status-bar counter chip with a details sheet, reset notice with "Switch to manual". Four classes are locked instead of reset — song creation/import, synchronised preferences, band actions, permanent delete — including the band buttons themselves, which used to stay enabled and fail after the confirm dialog. Band content writes that bypassed the outbox entirely are refused. Switching direction offers "Keep and send" or "Discard". The refetch expands bulk entries into their row ids, and an offline abort marks the reset as waiting for a connection.
- End-to-end encryption reads a wrapped data key. The password-derived key now only encrypts the data key. Existing accounts were migrated at no cost, and no ciphertext was touched. Write support ships off (
kE2eeWrapWritesEnabled = false): this release reads and tolerates wraps, a password change still re-encrypts the library. Sheet blobs survive a rotation, the re-key sweep no longer strands rows, and the self-healer no longer rolls a sweep back. - Fonts get their own Preferences section, with missing bold/italic styles shown and individually re-fetchable — a failed cut used to render silently in the regular style. Intro/outro/lyrics/custom blocks now print with their own font settings, and emoji print monochrome instead of vanishing.
- The ChordPro parser and the editor agree again. A raw newline inside
{t:…}is not a title — the metadata extractor swallowed it while the tokenizer did not, so the sheet printed a lyric line while the song list mirrored a two-line title. Backslash line continuation (ChordPro 6.010) is implemented. The editor's highlighter no longer colours past what the tokenizer accepts: unclosed braces, mid-line#, open chord brackets.{socm}is a multi-line comment, not a lyrics synonym. - Wi-Fi sync answers instead of hanging. Peer search ends in a verdict, "Sync now" no longer requires a visible peer, transfer and write failures are explained and counted, a dead
synced_audiostore is probed every two minutes and named in the report footer, quitting withdraws the Bonjour announcement, and a peer that fails three times in a row is dropped. - Support reports carry what the questions actually need. A new Display/Print section (deltas only, capped) with font, display and print settings. Attachments upload rather than failing RLS, the 10 MB promise is enforced by the bucket, skipped files are named in one sentence, and a key rotation no longer floods the tail — repeating lines are collapsed instead of enumerated per field.
- Linux: the published zip starts on the oldest supported LTS base again — Ubuntu 22.04, Mint 21.x, Debian 12 (glibc 2.35 / GLIBCXX_3.4.30). 1.0.24 was built on a newer host whose headers silently raised the floor to 2.38, so it did not launch there at all. A pinned ABI floor header is pulled into every translation unit, a pre-upload check measures the finished bundle, and a bundled libmpv that cannot load now hands over to the system one instead of taking playback down with it.
- Band setlists no longer lose other members' rows. The reconcile pass took the server set as "songs owned by me" and deleted every entry contributed by someone else as an orphan — in both directions, silently, leaving the owner unable to add anything afterwards (position collision into the dead-letter queue).
- Sheet blobs: re-uploading a score no longer looks like a mismatch (ciphertext differs per encryption — the pointer is what is compared), a cloud object that was deleted reports "not on this device" instead of a failed download retried against a 404, and a discarded sweep hangs off the state rather than the upload branch.
- macOS keychain: an item owned by a differently-named bundle (
Songbook Buddy.appvs.SongbookBuddy.app) refused every delete with-25244, so a signed-out device kept handing the library key back. The app now rotates to a slot of its own, reportsstorage_cleared=falsehonestly, and the next sign-in writes an item it owns. The stale item stays behind and can be removed by hand. - Notices that carry an action disappear again. Flutter defaults such a SnackBar to
persist = true, which made itsdurationdead code — the two "receive only" hints stood indefinitely and their button led into Preferences rather than closing them. - Crash reporting: an unsent crash log is no longer evicted by newer sessions, a hard-killed session is recovered as a
crashrather than an ordinary log, a report deferred during a bad start is sent at the next healthy one, and acknowledging an incident no longer disarms the start that is still running. - macOS 12: Impeller is globally off (
FLTEnableImpeller=false) — its pipeline pre-compilation deadlocked in the Metal XPC compiler before the first frame, so the app never started. - Play Store / App Store:
.sbblsetlist import now counts against the Starter library cap. Content-identical songs merge for free, bundle-internally too; on overflow the user picks "import the first N" or cancels, and a fully blocked import gets the normal song-limit upsell. - Smaller fixes: iOS "Bold Text" no longer overrides the song display; touch line metrics match desktop (no +16 px); the footswitch hot path is a gate plus a set lookup with a key-storm counter; the shell reclaims orphaned focus after an iPad field commit; the DMX interface verdict is calibrated for iOS, where an empty enumeration proves nothing; an epoch-start pull saves a fresh cursor so the stale loop converges; an offline cycle ends at the first failure and says it once; hard delete clears local junction rows and the reconcile pass drops pre-existing orphans; a deleted chord fingering is no longer re-uploaded every cycle; the trash keeps the sheet plaintext and permanent delete clears file and bucket object; attachment paths are canonical POSIX rather than platform-dependent; quotes in the search field search exactly; the pinned insert sidebar is suppressed below the minimum editor width; the import-plan flow moved to the app shell with the wait spinner as a cancel route; PDF autoscroll re-measures after viewport changes; a missing sheet song shows the Wi-Fi route instead of an exception;
ConnectionClosedExceptionat quit counts as teardown noise; the song header is localised in both branches; the signed-out dialog can no longer become a dead end; the manual PDF renders blockquotes as hint blocks with real em dashes; the password-change progress dialog can no longer be dismissed, leaving progress and result invisible;ensure()returns only once the ready flag is actually set; 8 px of breathing room before the help block in Preferences; plus refreshed translations and rebuilt manuals for all 23 locales.
Version 1.0.24
August 23, 2026
A reliability release for stage output, sync convergence and the purchase flow, plus an in-app password change that keeps the encrypted library readable:
- Change your account password in the app (Preferences → Account → Advanced). The dialog takes the current password alongside the new one — GoTrue requires it even after a fresh sign-in — and states the policy up front. Because the E2EE key derives from the password, the change runs a full library re-encryption sweep (~93 s for 1301 songs, resumable, progress shown) and only then rotates the account's key fingerprint. Other devices are not signed out: they keep their session and need the new password before they can read anything written after the change. (Corrected 2026-08-23 — this note originally claimed a server-side sign-out with a prefilled banner. That was never implemented. From 1.0.25 the other devices notice the rotation themselves and ask for the new password.) A wrong password verifies before anything is persisted, so it changes nothing.
- Sheet PDFs: Windows scrolls freely instead of snapping page by page, autoscroll is driven by playing time on every viewer family, pinch-zoom works again on iOS/macOS, the raster viewer re-renders at zoom instead of scaling pixels, and a malformed PDF is rejected at import rather than crashing the app.
- Space controls playback again after editing a song's play time; the text field kept the focus scope and the shell shortcut never saw the key. On Windows a quit the OS ignored could leave the process alive behind the closing scrim — that now ends in a dead process.
- DMX / Art-Net leaves macOS and iOS devices again. Packets were sent to the catch-all 255.255.255.255 broadcast, which Darwin drops without a word, so nothing reached the fixtures however correct the setup looked. They now go to the network's own directed broadcast address, with an explicit interface binding.
- Discarding a failed sync item is final. The discard removed the dead-letter row that had exempted the record from the stranded-pending sweep, so the next sync re-queued the very mutation the user discarded, spent five more attempts on it and filed it again. The pending stamp is now cleared as part of the discard.
- Setlist position collisions converge. Two devices reordering one setlist could reach a collision that blocked that setlist's sync permanently, because recovery bypassed the reorder RPC. Both sides now converge instead.
- The reconcile scan paginates. It stopped at PostgREST's 1000-row cap, so any library larger than that was compared against a truncated set of server ids.
- A rotated end-to-end encryption key is detected and reported instead of surfacing as an opaque decrypt failure.
- Purchase and sign-in dead ends. "Secure your purchase" hung when GoTrue parked the new address in
new_email, and failed outright when that address already had an account; the sign-in escape hatch no longer offers a button the current channel does not have. Orphaned purchases now move onto the real account atomically, and Restore no longer gives up when a single App Store host is slow to answer. - Import: duplicates are now detected within a single import run, not only against the existing library, and an imported archive can no longer write outside its target folder (Zip-Slip guard).
- Smaller fixes: PDF-backed sheet songs open again on Windows, a restored backup bundle no longer keeps its file locked, database streams are fully closed on quit so the app cannot hang there, the delete tooltip names the trash, mDNS discovery for linked audio ends with the foreground, the import-plan heading is back in the English help, plus refreshed translations and rebuilt manuals for every locale.
Version 1.0.23
August 12, 2026
A sync-reliability release fixing a permanent resync loop and a false "library was repaired" prompt on wiped devices:
- Uploaded rows are no longer stored as
pending. The generic outbox push uploaded the full local row without stamping its sync status, sopending— the local marker for "still waiting to be pushed" — was written into the server copy and pulled straight back down. The row then looked stranded, the 1.0.21 stranded-row rescue re-queued it, and that local write scheduled the next sync: a self-sustaining loop that resynced hundreds of rows on a library nobody had touched (one report: 765 rows, four cycles in a row). Uploads now strip the server-managed columns and stampsyncedat the single choke point every full-row upload passes, and pulls assertsyncedon every row written locally, so the wedged state cannot be represented on the device whatever arrives from the server. Existing backlogs heal on the next pull with no migration, and because the push also repairs the stored server value, devices still running an older build stop looping without updating. - A device with no library is not "behind a library repair". "Wipe local database" deletes the device's library-generation marker along with everything else, and reading it back defaulted to generation 1 while the account's server generation stays where an earlier repair left it. "This device has no idea which generation it is on" was therefore indistinguishable from "this device is two generations behind", so every wiped or freshly installed device on a once-repaired account took the destructive catch-up path — prompting about unsynced changes an empty device cannot have, and on a send-only device raising a hard sync block it had no way to clear. A missing marker together with an empty library and an empty outbox is now recognised as a fresh device: it adopts the server generation and lets the ordinary full pull fetch the library. A library that has rows but no marker still gets the prompt, because those rows can genuinely be pushed at the wrong generation.
- Smaller fixes: the release publisher no longer aborts one channel's publish because a different, deliberately retired channel still lists deleted artifacts — asset checks are now scoped to the channel being published, and a channel marked unavailable is skipped entirely.
Version 1.0.22
August 12, 2026
A fix release for chord spelling, enharmonic chord diagrams, silent DMX output and a stuck macOS modifier:
- Transposed chords keep their scale degree. The tonic moves a fixed number of letter steps and every chord moves with it, so a D in a song in E now transposes to Bb in C rather than A#. Borrowed and diatonic chords are both spelled the way a chart spells them; where the degree-correct name would need a double accidental or one of B#/E#/Cb/Fb, the song's own preference decides instead.
- Both spellings of a note reach the same chord diagrams. Db and C#, Gb and F# were separate namespaces in the chord lookup, so one of each pair fell through to calculated shapes while 254 of 260 curated fingerings sat unused. Reads now match either spelling for guitar, ukulele, banjo and mandolin, existing user grips and synced rows are found without a rename, and duplicate twins are folded away.
- DMX output reports when it is being dropped. When the OS refuses the app's Art-Net datagrams, the DMX sidebar now shows a warning naming the likely cause (the "Local network" permission on iOS/macOS) instead of looking healthy while nothing reaches the fixtures. The automatic socket rebind now backs off exponentially (2 s → 60 s) rather than retrying every two seconds indefinitely, and resets on recovery or a new target address.
- macOS: a stale ⌘ modifier heals itself. A lost key-up from a native menu or sheet could leave Command permanently "held", turning every plain keystroke in the editor into its shortcut until the app was switched away and back. The keyboard state is now reconciled against the engine after native menu callbacks and after each shell shortcut fires, so at most one keystroke misfires before typing works again.
- Smaller fixes: support reports now record which modifier keys were held when a shortcut fired; the DMX rebind log pair is throttled so it no longer crowds the rest of the support log out of the tail; two macOS marketing-capture failures (an IFS leak and a first-launch Gatekeeper timeout) fixed in the build tooling.
Version 1.0.21
August 12, 2026
A reliability release: multi-device sync integrity, uninterrupted playback, and a working update check:
- Sync updates carry only the fields you changed. An edit on one device no longer overwrites unrelated fields edited on another — every update path in the library now reports per-field changes.
- Conflicts resolve by edit time, not upload time. An offline edit no longer loses to an older change that happened to reach the server later.
- Stuck syncs recover on their own. A hung network request no longer blocks sync until restart, queued changes stranded as "pending" are re-enqueued, and bulk edits carry their record IDs.
- Stable installs see updates again. The update check followed a channel preference that could point release installs at the beta feed and report "no update"; the channel now follows the build itself and the picker is gone.
- Playback keeps playing. Starting autoscroll no longer stops running audio, and a background plan re-check no longer tears playback down.
- Editor & import. A typed {duration: 3:45} survives the save path; the editor honours "Move field directives into controls"; the import dialog mirrors the typed title, artist and album live into the ChordPro preview.
- Smaller fixes: support-report logs are no longer flooded by DMX frame traffic; artist-metadata healing stays local instead of re-uploading on every open; the iOS upload's export-compliance declaration is fixed; help, manuals and screenshots refreshed across all 22 languages.
Version 1.0.20
July 23, 2026
Songbook Buddy's first public (non-beta) release: the four-plan licensing model introduced across the 1.0.19 beta line goes stable, with account-less purchasing.
- Four plans, hierarchical. Starter (free) · Basic (€7.99 one-time) · Pro (€29.99/year) · Pro Cloud (€79.99/year); each plan includes everything below it. The upgrade screen leads with your current plan and offers only the steps above it.
- Buy without an account. Unlock a plan with PayPal without first creating a Sync account; add an email and password afterwards to protect the purchase, restore it on another device, and turn on sync.
- Android direct download. A sideloadable Android build (its own applicationId and
songbookbuddy-directdeep-link scheme) is published from the website for the PayPal purchase path, installing alongside the Play Store build. - Printing. Songbook and setlist printing are Pro; single-song print stays Basic. Setlist portability:
.sbblexport (Pro) and import (free, merge), from the normal Import dialog. - Apple font collections on macOS. The font browser lists
.ttccollections (Avenir Next, Optima, Palatino …) for use in songs, print and PDF. - Smaller fixes: a plan change made on the server — a refund or an expiry — now reaches the running app within seconds instead of waiting for the next launch; after paying with PayPal the browser returns to the app on its own; refunds restore the year they bought, not just a pointer; every paid tier grants the permanent Basic floor; restrictions no longer fire on an unhydrated tier (no "Starter library full" flash for paying users); nine upsells no longer told paying users to buy what they already own; export/print default filenames keep non-ASCII characters; a corrupt local database self-heals on open; band-song decrypt recovery; device-identity convergence ends the solo-owner band-key ping-pong; refreshed help, manuals and screenshots in all supported languages.