Sources like JMA, AccuWeather, Pirate Weather, and INMET (soon NWS)
serve both weather and alerts from the same provider, but alertSource
stayed NONE unless a user separately opened the alert-source picker
and picked it manually. Now, whenever a location's weather source is
set or changed to one with Capability.ALERTS, alertSource follows it
automatically - for a brand-new location and when editing an existing
one. Picking a non-self-paired weather source leaves the current
alert-source choice untouched rather than clearing it, so deliberately
mixed pairings (e.g. AccuWeather for weather, WMO for alerts) still
work.
Verified live on device: a new Japan location auto-pairs JMA for both;
switching an existing location's weather source to AccuWeather
auto-follows the alert-source tile before saving; switching back to a
non-self-paired source leaves the prior alert-source pick intact.
NWS is the recommended weather source for the US but had no alerts
capability, so US locations got zero recommended alert sources in the
Edit Location picker. NwsRepository now also implements AlertRepository
using the free, keyless /alerts/active endpoint on the same host
NwsRepository already talks to.
Addresses PranshulGG's review comment on #1065:
- restoreBackup() now rejects a backup with no default location instead
of silently importing a state the app never expects.
- New "Import a backup" option on the intro screen, reusing the same
restore path, so a fresh install can skip manual location setup.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA5SoK1dsP8uxkMi2qEGu
Closes#848. Lets users export their locations, units, weather block
layout, and app settings to a JSON file, and restore from one - the
old Flutter version had this and it was never ported to the Kotlin
rewrite. API keys are opt-in on export (off by default); import is a
full replace of everything except keys, which are left alone when the
file doesn't include any.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA5SoK1dsP8uxkMi2qEGu