Beta 程式
在访问测试中签名或註冊,构建,發布注释,以及当前开发版本的详细程式資訊.
签名或註冊
在确认您的帳號后, 在 Songbook Buddy Beta app 中使用相同的邮件和密码 。
Beta 规则 — 在加入前阅读
Beta 构建是未完成的軟體. 通过註冊,您接受这些条件:
- 崩溃,資料丢失,和破损的特性都可能发生. 保留你关心的歌曲的备份.
- 使用单独的Songbook Buddy Betaapp和β雲后端——从不将测试資料与您的發布库混合.
- 你的Beta帳號只接受Pro和Cloud测试 这些赠款不转至公共發布应用或生产雲。
- 仅在我们的Discord频道中报告错误并提问——而不是通过公共支援的电子邮件.
- 移动测试仅通过TestFlight(iOS)和Google Play内部测试(Android)进行.
- 不要共享β构建,登入链接,或程式外的未释放特性.
- 您可以随时刪除您的β帳號; 当β结束时, 我们可以取消访问 。
註冊或签名意味着你接受这些规则。
Beta 规则 — 在加入前阅读
Beta 构建是未完成的軟體. 通过註冊,您接受这些条件:
- 崩溃,資料丢失,和破损的特性都可能发生. 保留你关心的歌曲的备份.
- 使用单独的Songbook Buddy Betaapp和β雲后端——从不将测试資料与您的發布库混合.
- 你的Beta帳號只接受Pro和Cloud测试 这些赠款不转至公共發布应用或生产雲。
- 仅在我们的Discord频道中报告错误并提问——而不是通过公共支援的电子邮件.
- 移动测试仅通过TestFlight(iOS)和Google Play内部测试(Android)进行.
- 不要共享β构建,登入链接,或程式外的未释放特性.
- 您可以随时刪除您的β帳號; 当β结束时, 我们可以取消访问 。
註冊或签名意味着你接受这些规则。
包含在β中的雲
每个确认的Beta帳號只得到Pro和Cloud在Beta后端. 在Songbook Buddy Beta内部用同一个帳號签名,以解锁乐队模式,雲同步,以及测试期间所有Pro特性.
最新公开beta建筑: 1.0.25
并排發布应用和β应用
在测试新建筑时,你应该能够继续使用稳定的应用来进行演出,而不要混淆你的歌曲库。
- 在您的平台上安装 beta 作为单独的应用程式, 并带有自己的图标和名称( Songbook Buddy Beta) 。
- 每个应用程式都保留自己的本地資料库,設定,以及裝置身份——在β中的编辑不会触碰您的發布库.
- β中的雲同步使用单独的后端项目,因此测试資料永远不会覆盖生产同步資料.
- 在桌面上,您可以同时运行两个应用程式;在移动/桌面上,您可以在两个安装的应用程式之间切换.
直到所有平台上的单独的β应用船,安装一个β构建可能取代该裝置上的当前应用. 在可能情况下,优先使用备用裝置。
Beta 支援频道
在β期间,我们只通过这些渠道支援测试者:
- Discord——错误、问题和讨论
- TestFlight — iOS beta 安装和更新
- Google 播放内部测试 — Android beta 安装和更新
公共支援页面和支援电子邮件不用于β期.
最近建筑
最新条目——开放旧楼完整名单.
仅成员
在上面签名或註冊以查看β發布注释和下載.
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+20
August 31, 2026
Test build for the manual release checks on the Intel Mac (GF-MBPro-2016, macOS 12.7.6) — not published. First signed + notarised DMG that carries the fixes made since 1.0.24+15, which is what that machine still runs:
- A keychain item owned by another bundle no longer blocks sign-out. When deleting the encryption key returns
-25244, the slot rotates instead of silently reporting success, so the next sign-in writes its own item (…_encryption_key_s1) — BUG-2026-08-28-08. This is the fix the Intel Mac run is for. - After a password change on another device, signing back in no longer asks for the password twice — BUG-2026-08-28-09.
- Band setlist entries added by other members survive the reconcile — BUG-2026-08-30-03; ⌘S no longer reports "Saved" over a refused band write — BUG-2026-08-30-04.
- Sheet attachments: a ciphertext-sha256 mismatch proves the pointer, not the file — the sheet opens and the pointer heals (BUG-2026-08-31-03); a deleted cloud object says "not on this device" instead of retrying a known 404 (BUG-2026-08-31-02); the re-key pre-flight cleans up the plaintext it fetched (BUG-2026-08-31-01).
- Notices with an action disappear again after their duration instead of standing forever — BUG-2026-08-31-04.