• v2.0.86-dev f9759ae370

    Phandroid v2.0.86-dev Pre-release

    thoralf released this 2026-10-23 08:03:15 +02:00 | 0 commits to main since this release

    Fixed

    • The images inside an edit-history snapshot can be opened again. A snapshot is a
      StatusEdit and carries no status id, so the preview cards in the history sheet
      rendered media links pointing at /s/undefined: the thumbnails were there, tapping
      them did nothing, and the page's own viewer could not help either — it resolves its
      attachments from the store by status id, and a snapshot is never in the store. Tapping
      a snapshot's image now opens the real viewer with that snapshot's attachments
      (carousel, zoom, alt text, captions, and the back button closes the image before the
      sheet). The same links are broken on the web, so the fix is not gated on native.
    Downloads
  • v2.0.25 1655d4e2e1

    thoralf released this 2026-10-23 06:56:20 +02:00 | 4531 commits to main since this release

    Same fixes as dev 2.0.81 — the upstream-merge model and the release-pipeline fixes of 2026-10-18/19.

    Fixed

    • The F-Droid "What's New" can no longer be blocked by a changelog entry that mentions
      a heading.
      The converter stripped backticks and bold but left a literal ### in the
      text, so the release gate's "no Markdown left" assertion failed — and that is exactly
      what happened to 2.0.81 on the dev channel: the entry about the duplicate ### Changed
      heading fed its own heading into the What's New text, the gate refused, and the release
      was never signed (dev stayed on 2.0.80). The converter now drops heading hash runs (the
      words stay, so the entry still reads correctly), which makes its guarantee hold for any
      input. prod was not affected.
    • merge=ours can no longer silently discard your change. The fork-owned files
      (README, CHANGELOG, LICENSE, SECURITY, PRIVACY) must keep our version on an upstream
      merge — but git calls that driver for every three-way merge, and on a rebase or
      cherry-pick "ours" is the branch being replayed onto while "theirs" is your commit.
      The built-in true therefore threw your change away, silently: it did exactly that
      three times on 2026-10-18/19 (both prod cherry-picks and one rebase, each losing a
      CHANGELOG entry), with no conflict and nothing in the diffstat to catch the eye.
      scripts/phandroid-merge-ours.sh replaces it: it still keeps ours, but writes the
      discarded version to .git/phandroid-dropped/<path> and names it on stderr, so the
      loss is visible while it happens and recoverable afterwards. It needs the driver once
      per clone (git config merge.phandroid-ours.driver …; the workflow declares it for
      CI), and a clone without it now gets a visible conflict instead of silence.
    • The upstream sync no longer re-resolves the lockfile from a stale base — the
      outage class that stranded dev at 2.0.79 for two days is closed.

      package-lock.json is now merge=theirs: a merge takes upstream's lock, the
      dependency resolution they actually build and test with, and the sync
      regenerates it only to re-add the fork's eleven overlay entries. The old model
      kept our lock (merge=ours) and re-resolved it from scratch on every merge,
      handing each upstream dependency bump to npm's peer resolver as a fresh coin
      flip: on 2026-10-16 upstream bumped @lingui to ~6.9.1 and npm walked the
      unguarded peerOptional chain (@lingui/vite-plugin →
      @rolldown/plugin-babel → @babel/plugin-transform-runtime) into Babel 8.x
      against the tree's @babel/[email protected] — ERESOLVE, and the sync failed
      eleven consecutive runs while dev sat 20 commits behind upstream. Starting from
      upstream's lock instead, the identical regeneration touches nothing upstream
      owns (measured: 716 entries, 0 changed, 0 removed, 195 added by the overlay;
      verified under npm 9.2 and 11.21). A new guard,
      scripts/phandroid-lockfile-invariant.mjs, fails the run if the regeneration
      changes or drops any upstream-owned entry — the drift can neither crash the
      sync nor ship silently again. This branch carries the same model and the same
      guard, so the next upstream/production move cannot hit the same wall.
    • The lockfile guard fails closed. Input it cannot check — a lockfile without a
      packages map (lockfileVersion 1), an unparsable or missing file — now stops the
      run with one line naming the file and the reason (exit 2), instead of comparing
      zero entries and reporting a green "0 upstream entries unchanged". A guard that
      validates nothing is the failure mode this pipeline keeps hitting: an unmatched
      test glob ran zero tests and exited 0, and the awk the changelog bump replaced
      exited 0 on a missing [Unreleased] heading. Only exit 0 means the invariant held.
    • A release section no longer carries two ### Changed headings. The generated
      upstream-merge block was followed by the moved hand-written entries including
      their own ### Changed, so a release whose entries had one showed that heading
      twice — in the release body on both instances (2.0.80 shipped that way) and, for
      sections short enough to survive the 500-character limit, twice as "Changed:" in
      the F-Droid "What's New" text (measured against the pre-fix script; in 2.0.80 the
      truncation dropped the second block, so there only the release body showed it).
      Hand-written ### Changed bullets now merge into the generated block, which stays
      first because the upstream merge is the release's headline; every other
      hand-written section keeps its place. A body without a ### Changed heading still
      produces byte-identical output — verified against the pre-fix script over six
      input shapes. A heading spelled with extra whitespace (### Changed) counts as
      the same heading, and a body of nothing but headings no longer counts as fork
      changes: it used to append a stray empty heading and drop the "no Android-fork
      code changes" claim for a release that had none.

    Changed

    • A failed sync now says why, and for how long it has been failing. The
      lockfile step tees its output into the failure report — the ERESOLVE that
      killed eleven runs was previously only findable by pulling job logs by hand —
      a failed merge lists its conflicted files the same way, and every CI-failure
      issue now carries a trend line ("N consecutive failed run(s); last success:
      run X on …") computed from the run history. Forgejo notifies nobody about
      Actions results, so the issue body is the only alarm channel — and "still
      down" reads differently than "another failure".
    • The sync announces conflict candidates before merging. Files that both
      upstream and the fork changed since the last merge — minus the ones the merge
      drivers own — are printed up front, so the next real conflict shows up in the
      job log and the issue instead of being a surprise mid-merge.
    • The conflict-candidate list is read from .gitattributes instead of a fixed
      list of files.
      Upstream edits its own CHANGELOG.md regularly and merge=ours
      resolves that without a human, so the hardcoded version would have announced a
      conflict candidate on most runs — the noise that makes a real one invisible.
    Downloads
  • v2.0.85-dev e19aa9bb0a

    Phandroid v2.0.85-dev Pre-release

    thoralf released this 2026-10-22 16:39:04 +02:00 | 2 commits to main since this release

    Changed

    • Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see CHANGELOG.phanpy.md for upstream detail):
      • bb2c7ea3 I need the total net diff
    Downloads
  • v2.0.84-dev 02d46aa3a5

    Phandroid v2.0.84-dev Pre-release

    thoralf released this 2026-10-22 10:34:29 +02:00 | 5 commits to main since this release

    Changed

    • Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see CHANGELOG.phanpy.md for upstream detail):
      • 33924e31 Missed this one
      • cf9b91f5 Add "View profile" button in profile sheets
      • 27c8bfb9 Improve copies
    Downloads
  • v2.0.83-dev 579d05a12b

    Phandroid v2.0.83-dev Pre-release

    thoralf released this 2026-10-21 10:35:31 +02:00 | 10 commits to main since this release

    Changed

    • Merged upstream Phanpy — 3 commit(s); no Android-fork code changes (see CHANGELOG.phanpy.md for upstream detail):
      • 19ff20fe More lowercases
      • 8727c68c Loading indicator for notifications popover
      • 27aa49e1 Dedupe quotes too in Mentions page
    Downloads
  • v2.0.82-dev 3ad2dc2d9d

    Phandroid v2.0.82-dev Pre-release

    thoralf released this 2026-10-20 16:34:01 +02:00 | 15 commits to main since this release

    Changed

    • Merged upstream Phanpy — 5 commit(s) (see CHANGELOG.phanpy.md for upstream detail):
      • 2ef1b407 Allow emulate boost/like/bookmark
      • 53b2b2e7 Experiment: lowercase post text
      • 78710d8d username setting for bylines too
      • e272ba27 Add note for quote post count field
      • 22cc47dd i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,es-ES,eu-ES,fi-FI,fr-FR,he-IL,kab,pl-PL,zh-CN) (#1620)

    Fixed

    • The F-Droid "What's New" can no longer be blocked by a changelog entry that mentions
      a heading.
      The converter stripped backticks and bold but left a literal ### in the
      text, so the release gate's "no Markdown left" assertion failed — and that is exactly
      what happened to 2.0.81: the entry about the duplicate ### Changed heading fed its
      own heading into the What's New text, the gate refused, and the release was never
      signed. The converter now drops heading hash runs (the words stay, so the entry still
      reads correctly), which makes its guarantee hold for any input. prod was unaffected;
      dev stayed on 2.0.80 until the release was re-run.
    Downloads
  • v2.0.81-dev 155fe2586f

    Phandroid v2.0.81-dev Pre-release

    thoralf released this 2026-10-19 20:41:16 +02:00 | 22 commits to main since this release

    Changed

    • Merged upstream Phanpy — 2 commit(s) (see CHANGELOG.phanpy.md for upstream detail):
      • 63d26fda Upgrade deps
      • 2a801b1e Only generate used icons
    • The conflict-candidate list is read from .gitattributes instead of a fixed
      list of files.
      Upstream edits its own CHANGELOG.md regularly and merge=ours
      resolves that without a human, so the hardcoded version would have announced a
      conflict candidate on most runs — the noise that makes a real one invisible.

    Fixed

    • merge=ours can no longer silently discard your change. The fork-owned files
      (README, CHANGELOG, LICENSE, SECURITY, PRIVACY) must keep our version on an upstream
      merge — but git calls that driver for every three-way merge, and on a rebase or
      cherry-pick "ours" is the branch being replayed onto while "theirs" is your commit.
      The built-in true therefore threw your change away, silently: it did exactly that
      three times on 2026-10-18/19 (both prod cherry-picks and one rebase, each losing a
      CHANGELOG entry), with no conflict and nothing in the diffstat to catch the eye.
      scripts/phandroid-merge-ours.sh replaces it: it still keeps ours, but writes the
      discarded version to .git/phandroid-dropped/<path> and names it on stderr, so the
      loss is visible while it happens and recoverable afterwards. It needs the driver once
      per clone (git config merge.phandroid-ours.driver …; the workflow declares it for
      CI), and a clone without it now gets a visible conflict instead of silence.
    • The lockfile guard fails closed. Input it cannot check — a lockfile without a
      packages map (lockfileVersion 1), an unparsable or missing file — now stops the
      run with one line naming the file and the reason (exit 2), instead of comparing
      zero entries and reporting a green "0 upstream entries unchanged". A guard that
      validates nothing is the failure mode this pipeline keeps hitting: an unmatched
      test glob ran zero tests and exited 0, and the awk the changelog bump replaced
      exited 0 on a missing [Unreleased] heading. Only exit 0 means the invariant held.
    • A release section no longer carries two ### Changed headings. The generated
      upstream-merge block was followed by the moved hand-written entries including
      their own ### Changed, so a release whose entries had one showed that heading
      twice — in the release body on both instances (2.0.80 shipped that way) and, for
      sections short enough to survive the 500-character limit, twice as "Changed:" in
      the F-Droid "What's New" text (measured against the pre-fix script; in 2.0.80 the
      truncation dropped the second block, so there only the release body showed it).
      Hand-written ### Changed bullets now merge into the generated block, which stays
      first because the upstream merge is the release's headline; every other
      hand-written section keeps its place. A body without a ### Changed heading still
      produces byte-identical output — verified against the pre-fix script over six
      input shapes. A heading spelled with extra whitespace (### Changed) counts as
      the same heading, and a body of nothing but headings no longer counts as fork
      changes: it used to append a stray empty heading and drop the "no Android-fork
      code changes" claim for a release that had none.
    Downloads
  • v2.0.80-dev 42ece6622f

    Phandroid v2.0.80-dev Pre-release

    thoralf released this 2026-10-18 23:23:48 +02:00 | 30 commits to main since this release

    Changed

    • Merged upstream Phanpy — 20 commit(s) (see CHANGELOG.phanpy.md for upstream detail):
      • 78ca68d7 new config style for lingui
      • 5fbc3a01 Upgrade deps
      • 651c2421 Update lock file
      • e01ebe59 Rearrange and hide some visibilities
      • 045e3577 Restyle mini translation block
      • f0bb03c4 Actually can share the locale strings
      • cf05b2df i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1615)
      • 5840c0e6 Remove this "fix"
      • 6a051937 Experiment: "Hide post metrics"
      • 2dd139cd Experiment: only show usernames
      • dbe778a4 i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1617)
      • f90c2f6e Sorry, translators.
      • 4eac7b15 i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,eo-UY,es-ES,eu-ES,fa-IR,fi-FI,fr-FR,gl-ES,he-IL,hu-HU,it-IT,ja-JP,kab,ko-KR,lt-LT,nb-NO,nl-NL,oc-FR,pl-PL,pt-BR,pt-PT,ru-RU,th-TH,tok,tr-TR,uk-UA,zh-CN,zh-TW) (#1618)
      • e2d2f1e4 Names in filtered posts also need subtle treatment
      • c3cddcac Add toggles for hide post metrics and display username
      • 285fb248 Apply metrics hiding for notifications too
      • de2c88d6 Apply display username setting to notifications too
      • 8ca38b7a A little bit of "life" in the carousel dots
      • dc6a27f2 i18n updates (ar-SA,ca-ES,cs-CZ,de-DE,es-ES,eu-ES,fi-FI,fr-FR,pl-PL,zh-CN) (#1619)
      • 15f73bbf Update README.md

    Fixed

    • The upstream sync no longer re-resolves the lockfile from a stale base — the
      outage class that stranded dev at 2.0.79 for two days is closed.

      package-lock.json is now merge=theirs: a merge takes upstream's lock, the
      dependency resolution they actually build and test with, and the sync
      regenerates it only to re-add the fork's eleven overlay entries. The old model
      kept our lock (merge=ours) and re-resolved it from scratch on every merge,
      handing each upstream dependency bump to npm's peer resolver as a fresh coin
      flip: on 2026-10-16 upstream bumped @lingui to ~6.9.1 and npm walked the
      unguarded peerOptional chain (@lingui/vite-plugin →
      @rolldown/plugin-babel → @babel/plugin-transform-runtime) into Babel 8.x
      against the tree's @babel/[email protected] — ERESOLVE, and the sync failed
      eleven consecutive runs while dev sat 20 commits behind upstream. Starting from
      upstream's lock instead, the identical regeneration touches nothing upstream
      owns (measured: 716 entries, 0 changed, 0 removed, 195 added by the overlay;
      verified under npm 9.2 and 11.21). A new guard,
      scripts/phandroid-lockfile-invariant.mjs, fails the run if the regeneration
      changes or drops any upstream-owned entry — the drift can neither crash the
      sync nor ship silently again. Ported to the prod branch as well, so the next
      upstream/production move cannot hit the same wall.

    Changed

    • A failed sync now says why, and for how long it has been failing. The
      lockfile step tees its output into the failure report — the ERESOLVE that
      killed eleven runs was previously only findable by pulling job logs by hand —
      a failed merge lists its conflicted files the same way, and every CI-failure
      issue now carries a trend line ("N consecutive failed run(s); last success:
      run X on …") computed from the run history. Forgejo notifies nobody about
      Actions results, so the issue body is the only alarm channel — and "still
      down" reads differently than "another failure".
    • The sync announces conflict candidates before merging. Files that both
      upstream and the fork changed since the last merge — minus the ones the merge
      drivers own — are printed up front, so the next real conflict shows up in the
      job log and the issue instead of being a surprise mid-merge.
    Downloads
  • v2.0.79-dev 646e0abd84

    Phandroid v2.0.79-dev Pre-release

    thoralf released this 2026-10-15 22:31:56 +02:00 | 54 commits to main since this release

    Changed

    • Merged upstream Phanpy — 2 commit(s); no Android-fork code changes (see CHANGELOG.phanpy.md for upstream detail):
      • b4804d90 Fix notification dot color
      • 36f9f259 Try remove @babel/plugin-transform-runtime this time
    Downloads
  • v2.0.78-dev 16cd2ebb2a

    Phandroid v2.0.78-dev Pre-release

    thoralf released this 2026-10-15 04:30:55 +02:00 | 58 commits to main since this release

    Changed

    • Merged upstream Phanpy — 1 commit(s); no Android-fork code changes (see CHANGELOG.phanpy.md for upstream detail):
      • 2fb534db Experiment: pagination dots for boosts carousel
    Downloads