- Gitea URL used as primary (same-version tie-break), GitHub as fallback
- download() tries base url first; if it fails, automatically retries
the fallback URL
- version 1.9.1 -> 1.9.2 (code 30 -> 31)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same-version update was picking GitHub URL (crowded first) which
downloads fail in China. Now Gitea info is inserted before GitHub
so maxByOrNull takes the Gitea one on version tie.
version 1.9.0 -> 1.9.1 (code 29 -> 30)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Meow channel mark now uses the official cat-face logo (transparent
background, cropped from brand image)
- All five channels now have proper brand/themed icons
- version 1.8.10 -> 1.8.11 (code 27 -> 28)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Bark: official logo from Finb/Bark repo (ic_bark_logo.png)
- ntfy: official logo from binwiederhier/ntfy repo (ic_ntfy_logo.png)
- Meow: Material Pets icon (paw) — no official logo found
- Email: Material Email icon
- SMS: Material Sms icon
- ChannelMark now supports both ImageVector and Painter (PNG logo)
- SectionCard gains optional titleIcon parameter
- version 1.8.9 -> 1.8.10 (code 26 -> 27)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Bark/ntfy help (info) icons now bright orange (#FF9800)
- Deleted all releases below v1.8.0 from GitHub and Gitea
- version 1.8.7 -> 1.8.8 (code 24 -> 25)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Replace "转发到 iOS Bark" with "多通道转发" across HomeScreen/FilterScreen
- Email config items now use EmailServerRow (two-line layout matching
Bark/ntfy): name + test/edit/delete on row 1, host:port + recipient
on row 2 with up/down buttons
- version 1.8.6 -> 1.8.7 (code 23 -> 24)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Small pulsing circle icon (top-right) that persists across all tabs,
blinks slowly (alpha 0.35↔1.0, 1.2s cycle). Tapping opens UpdateDialog.
version 1.8.5 -> 1.8.6 (code 22 -> 23)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- update-source in release notes now XOR-scrambled (not plain Base64)
- UpdateDialog filters out update-source comment line from notes
- Download progress shows "正在下载更新…" instead of percentage/source
- version 1.8.1 -> 1.8.2 (code 18 -> 19)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gitea URL removed from source code. UpdateChecker now only hardcodes
GitHub API; the Gitea mirror URL is embedded in release notes as an
HTML comment (<!-- update-source: ... -->) and discovered at runtime.
Keeps self-hosted server address out of the public codebase.
version 1.8.0 -> 1.8.1 (code 17 -> 18)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All four forwarding channels now support multiple configurations (add/
edit/delete/reorder/enable per item, matching Bark server UX):
- model: NtfyServer, EmailServer, SmsTarget data classes
- SettingsStore: ntfyServers/emailServers/smsTargets as List; full CRUD
(add/update/delete/move/setEnabled); legacy single-config auto-migrated
to list via config_version; 4 stopOnFirst toggles (bark=true, others
false)
- BarkSender/NtfySender/EmailSender: pushToEnabled(configs, stopOnFirst)
— stopOnFirst=true: first success stops; false: send to all
- SmsFallbackForwarder: forward iterates smsTargets per stopOnFirst
- UI: each channel SectionCard has toggle + stopOnFirst switch + config
list + add button; ConfigRow + ConfigDialog reusable components
- version 1.7.3 -> 1.8.0 (code 16 -> 17)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- start(): check on every launch (no 24h throttle) so the banner shows
after restart even if checked manually moments ago; plus a 24h loop
while app is resident
- check both Gitea and GitHub release APIs, skip whichever is
unreachable, notify the higher version
- version 1.7.2 -> 1.7.3 (code 15 -> 16)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ntfy.sh now treats any request body (PUT/POST, text/plain) as a file
attachment, so messages never showed in the app. Switch to ntfy's JSON
publish API: POST / with {topic,title,message}.
version 1.7.1 -> 1.7.2 (code 14 -> 15)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- HomeScreen update banner: gradient background (tertiary→primary), white
text, large version number, rocket emoji CTA button
- UpdateChecker now auto-notifies via all enabled channels (Bark/ntfy/
email) when a new version is discovered, with version/size/notes
- Periodic check every 24h via coroutine delay loop (replaces one-shot
startup check only); also honors updateCheckEnabled toggle
- version 1.7.0 -> 1.7.1 (code 13 -> 14)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLAUDE.md is now regenerated from memory, no need to track in repo.
Remove from remote tracking.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SMS fields (number / quota / carrier / balance) are now hidden when the
toggle is off. Previously entered values are preserved, just hidden.
Email forwarding already had this pattern. Settings page stays compact.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parallel to Bark: when email forwarding is enabled and a recipient is set,
notifications are also sent via SMTP over SSL (port 465, SMTPS). Works
standalone — no Bark server required.
- core/EmailSender: SMTP over SSL (implicit TLS, port 465), AUTH LOGIN,
UTF-8 subject/body via Base64/MIME; trySend() fire-and-forget helper
- SettingsStore: 7 email settings (enabled, host, port, user, password,
from, to)
- NotifyListenerService + PhoneCallMonitor: call EmailSender.trySend in
parallel with Bark forwarding; fires even if no Bark servers configured
- UI: new "电邮转发" SectionCard in settings (toggle + host/port/user/
password/from/to fields + save button)
- version 1.6.0 -> 1.6.1 (code 10 -> 11); CLAUDE.md synced
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Row 1: checkbox + name + test/edit/delete. Row 2: full URL + key +
move-up/move-down only — more room for the link.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Row 1: checkbox + name + edit/delete. Row 2: full server URL + key
status + test/move-up/move-down. Stops the address/key from being
truncated and feels far less cramped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
com.milink.service posts empty/high-frequency cross-device clipboard
notices. Add to silentPackages so they're dropped silently (no forward,
no log entry). CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bark servers now form an ordered failover chain: forwarding tries each
enabled server in list order, stopping at the first success.
- model: BarkServer.enabled (defaults true; legacy JSON compatible)
- core/BarkSender.pushToFirst: ordered try-until-success helper, shared
by NotifyListenerService / PhoneCallMonitor / RetryWorker
- BarkClient.push uses msg.copy(deviceKey=server.deviceKey) so each
server pushes its own key
- SettingsStore: drop currentServer/setCurrent; add moveServer +
setServerEnabled; NotificationProcessor no longer sources deviceKey
- UI: ServerRow RadioButton -> Checkbox + per-row test/move-up/move-down;
remove top "send test push" button; HomeScreen shows enabled count
- version 1.5.1 -> 1.6.0 (code 9 -> 10); CLAUDE.md synced
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch UpdateChecker source from api.github.com (flaky in CN) to the
self-hosted Gitea at git.sunlunfan.com. Releases must now be published
to Gitea too (github stays as mirror). parseRelease unchanged — Gitea
API fields are GitHub-compatible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prefer github as default; the self-hosted Gitea (now at
https://git.sunlunfan.com) stays available as a manually-entered
alternative. Drops the github->gitea migration added earlier.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Switch DEFAULT_ICON_PREFIX from github raw (flaky in CN) to the
self-hosted Gitea at 45.143.131.159:3000/song/a2i. Auto-migrate
existing users whose stored prefix is the old github default; custom
values kept. Icons are already mirrored to Gitea via every push.
CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extracted from the app's product_logo_gmail_2026_launcher_color_48
(xxxhdpi, 192x192). Existing icons are 192x192, size matches.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
com.xiaomi.smarthome posts both generic status updates (title=米家,
content=设备状态) and concrete events (e.g. 智能门锁开锁). Silence only
the generic "设备状态" ones; door-lock/security alerts still forward.
Filtered silently before the blacklist. CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Surfboard (and other VPN/proxy clients) post a high-frequency persistent
notification showing up/down traffic. Once day.app direct-routing was
configured, these got forwarded to Bark and spammed the log (300 entries).
Add silentPackages (Surfboard / Clash Meta / Clash for Android / v2rayNG)
to NotificationProcessor, filtered silently (no log, no forward) right
after the ongoing-notification check. CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Incoming calls are already handled by PhoneCallMonitor (pkg=phone_call);
com.android.server.telecom and com.xiaomi.aiasst.service emit redundant
in-call status notices. Add them to default blacklist (bl_version 3),
migrated into existing users' blacklist (add-only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Investigated 9 failed forwards on device: all "connection closed" to
api.day.app, while ping/curl to the server succeed -> not network-blocked,
but OkHttp transient connection drops that aren't retried (POST read-phase
connection close is not covered by retryOnConnectionFailure).
- BarkClient.push: manual retry up to 3x (600/1200ms backoff) on
IOException (connection closed/timeout/TLS reset); HTTP 4xx/5xx not retried.
- AppRulesStore: add recorder/gallery/find-device/password-manager to default
blacklist; versioned migration (bl_version) merges the new entries into
existing users' blacklist (add-only).
- version 1.5.0 -> 1.5.1 (code 8 -> 9); CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>