Skip to content

fix: show a skipped release in Settings instead of "up to date" - #311

Merged
chattymin merged 1 commit into
chattymin:mainfrom
Borisserz:fix/skipped-update-stays-visible
Sep 18, 2026
Merged

chattymin merged 1 commit into
chattymin:mainfrom
Borisserz:fix/skipped-update-stays-visible

Conversation

@Borisserz

Copy link
Copy Markdown
Contributor

Summary

Fixes #310.

  • The banner button labeled Later called skipCurrent(), which permanently hid that version. Settings treated available == nil as "You're on the latest".
  • Keep the skip. Rename the button to Skip this version, and show the skipped release in Settings with Update and Show again.
  • A newer tag than the skipped one still opens the banner. Show again restores the banner without defaults delete.

Type of change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • Other:

UI changes

Before After
Banner: Later sits beside Update in one row. Clicking it hides that version forever. Banner: Skip this version on its own row, so the longer label fits. It still hides the banner for that version only.
Settings → Check now: skipped release prints "You're on the latest". No way back except defaults delete. Settings → Check now: "You skipped vX", plus Show again and Update. A later release still uses the update-found row.

Checklist

  • swift build and swift test pass locally (1079 tests, 13 skipped, 0 failures)
  • PR title and description are written in English
  • UI changes are described above (before/after — images optional)
  • No copyrighted assets, secrets, or private tooling references are committed (see CONTRIBUTING)
  • Tests were added or updated for this change

Test plan

  • UpdateCheckerTests/testSkippedReleaseStaysVisibleAndANewerOneReturnsToTheBanner fails if a skipped release is dropped, then passes
  • UpdateCheckerTests/testShowAgainRestoresTheBannerAndUpdateUsesTheSkippedRelease passes
  • LocalizationInterpolationTests keeps the skipped-version placeholder in all 7 languages
  • swift build and swift test locally: 1079 passed, 13 skipped, 0 failed
  • CI swift test

The banner button was labeled Later but permanently skipped that version, so Check now claimed the installed build was latest.
@chattymin
chattymin merged commit 1c695c7 into chattymin:main Sep 18, 2026
2 checks passed
@chattymin

Copy link
Copy Markdown
Owner

Thank you for your contribution!

LuceteYang added a commit to LuceteYang/PikaTokenBar that referenced this pull request Sep 24, 2026
All 17 accepted. chattymin#288 (Unown letter forms) is Gen 2 content but dormant here:
every form path is gated on species 201, outside the fork's 1...151 pool.

Conflicts kept both sides:
- UpdateChecker: fork's Effects/resolveBrewCask injection + upstream's
  skipped-release notice (chattymin#311); init takes both.
- UsageStore: upstream's new defaults; dropped the fork's duplicate
  session-key load (upstream chattymin#241 already carries it).
- READMEs: upstream text, fork's session-key row/bullet and
  PikaTokenBar support path kept.
- defect-log: upstream continuation paragraph, then fork bullets.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
donky-ey added a commit to donky-ey/PokeDexBar that referenced this pull request Oct 16, 2026
#21)

* fix: stop a second instance from appearing when the login agent is registered (upstream chattymin#163)

The login item is an SMAppService agent whose plist sets RunAtLoad, so
registering it while the app runs makes launchd exec the binary again.
LaunchServices' duplicate-launch protection does not cover a direct exec,
so turning on "Launch at login" left two menu bar icons, and both
instances wrote player-state.json.

At launch, the later instance yields (ordered by the kernel's p_starttime;
launchDate is nil for launchd-exec'd processes) before the status item and
before CrashReporter.install, so the yielding instance cannot clear the
crash marker. Missing or tied start times never yield.

Fork changes: the legacy login-item migration path does not exist here;
an extra test pins the guard's position before CrashReporter.install
(mutation-checked); e2e.sh asserts a single instance.

* fix: flush AppLog on the willTerminate exit path (upstream chattymin#174)

AppKit posts willTerminate and then exits, so markClean's async
"clean shutdown" line was usually lost. AppLog now writes through an
injectable AsyncLineLog backend, and exit paths (markClean, the duplicate
instance yield) use AppLog.writeAndFlush, which drains the queue before
returning. The bundled-app write guard stays, so tests never touch the
real log.

Fork change: AppLogTests' functionBody helper now stops at the nearest
boundary. Upstream preferred the next `func` over the next `///`, so with
the fork's member order the scanned body ran into writeIfChanged and
failed on its legitimate write(message) call. The routing guard still
fails when writeAndFlush is rewritten as write()+flush() (checked).

* fix: wait for the app's PID instead of its name in the update loop (upstream chattymin#175)

The detached upgrade script waited with 'pgrep -x PokeDexBar', which matches
any instance by name. With a duplicate instance running it always ran out
the 20 s wait and then swapped the bundle under a live app. Pass the
terminating PID as $3 and wait with 'kill -0'. The script body is now a
static constant so tests can pin it; a fork-only assertion checks that it
upgrades this app's cask.

* fix: read a trailing zero as ending in a consonant for Korean particles

Josa's digit table left out 0, so a number ending in 0 took the
no-final-consonant particle ("#20가", "v1.19.0를"). However it is read
(영, 십, 백, 천, 만), a trailing zero ends in a consonant. Found while
porting the skipped-version copy; the digit test never covered 0.

* fix: show a skipped release in Settings instead of "up to date" (upstream chattymin#311)

The banner button said "Later" but permanently skipped that version, so
Check now then claimed the installed build was the latest. The button now
reads "Skip this version"; a skipped release is kept as `skipped`, and
Settings says so, with "Show again" and an Update button that installs it.
UpdateChecker takes injected UserDefaults so tests do not touch the real
skip key. Strings are ko/en/ja only; the Korean copy picks its particle
from the version.

* fix: stamp the update-check cooldown only after a validated release (upstream chattymin#321)

check() stamped lastChecked before fetching, so one failed lookup (network,
bad response, unsafe URL) blocked the next attempt for 30 minutes. Record the
cooldown only when the release has a trusted github.com URL and a plain
MAJOR.MINOR.PATCH tag; malformed and prerelease tags count as failed checks.
An in-flight guard keeps overlapping popover opens to one fetch. The fetch is
injectable so tests never hit the network. Upstream's stray default.profraw
is not ported.

* fix: let an overlapping update check wait for the one in flight (review)

Upstream chattymin#321 made a check return immediately while another was running.
Here that regressed manual checks: pressing Check now in Settings while a
popover-triggered lookup was in flight returned at once and showed "up to
date" until the first lookup finished (up to 15 s on a slow network). On
main, a manual check always waited for its own lookup. Keep the in-flight
Task and have overlapping callers await it, so there is still one fetch and
every caller sees its result. testOverlappingChecksShareOneFetch now fails
on the early return; the failed-then-retry case moved to its own test.

Also remove AppLog.flush(): since the chattymin#174 port, production uses only
writeAndFlush.

---------

Co-authored-by: 이동기 <ldg0831@midasin.com>
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.

"Later" on the update banner skips the version permanently, and Settings then reports the app is up to date

2 participants