feat(todo): the weather: a forecast on days, tasks tied to it, the days that fit (ADR 0033, D40)

A task can need weather: dry, sunny, calm and a temperature range (not
freezing, warm, or from and to as typed), set from Weather in its
details (a chip beside Priority, then a row of its own once it needs
any) and kept in its sealed payload (`weather`, schema stays 1).
Where its day's forecast misses any of it, its row carries a mark and
its details say what is missing; nothing moves and its reminder stays.
Its date picker lists the coming days the forecast fits, at its time or
from 8:00 to 20:00 without one.

The forecast is for the place set in Settings' new Weather card, kept in
the sealed settings; else, for a task with a place, its first place. The
device's location is never read for it. `ForecastCubit` asks the
instance for each place (`InstanceWeather`, rounded to about a
kilometre) as it comes, as the app opens, hourly and on a pull, and
holds the answers in memory alone. With a place in Settings, each day's
heading in Today and Upcoming shows its sky and temperatures, the 3-day
grid its icon. Settings says where the instance gives no forecasts, and
credits Open-Meteo as its licence asks.

Whats-New: A task can need dry, sunny, calm or mild weather: it is marked when the forecast doesn't fit, and its date picker shows the days that do; days show the forecast for the place set in Settings.
Whats-New-De: Eine Aufgabe kann trockenes, sonniges, windstilles oder mildes Wetter brauchen: Sie wird markiert, wenn die Vorhersage nicht passt, und ihre Datumsauswahl zeigt die passenden Tage; die Tage zeigen die Vorhersage für den Ort aus den Einstellungen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-10 14:51:52 +01:00
commit 8502fb38f0
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2559,6 +2559,174 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'From {project}\'s calendar'**
String eventFromCalendar(String project);
/// A task's weather it needs, in its details and the sheet choosing it (ADR 0033, D40).
///
/// In en, this message translates to:
/// **'Weather'**
String get weatherTitle;
/// A task needs no rain or snow over its hours (D40).
///
/// In en, this message translates to:
/// **'Dry'**
String get weatherNeedDry;
/// A task needs a clear or partly cloudy sky (D40).
///
/// In en, this message translates to:
/// **'Sunny'**
String get weatherNeedSunny;
/// A task needs little wind (D40).
///
/// In en, this message translates to:
/// **'Calm'**
String get weatherNeedCalm;
/// The temperatures a task needs (D40).
///
/// In en, this message translates to:
/// **'Temperature'**
String get weatherTemperature;
/// No temperature needed (D40).
///
/// In en, this message translates to:
/// **'Any'**
String get weatherAnyTemperature;
/// From 1 °C on (D40).
///
/// In en, this message translates to:
/// **'Not freezing'**
String get weatherNotFreezing;
/// From 18 °C on (D40).
///
/// In en, this message translates to:
/// **'Warm'**
String get weatherWarm;
/// Temperatures typed (D40).
///
/// In en, this message translates to:
/// **'From … to …'**
String get weatherOwnRange;
/// The lowest temperature typed, in °C (D40).
///
/// In en, this message translates to:
/// **'From'**
String get weatherFromLabel;
/// The highest temperature typed, in °C (D40).
///
/// In en, this message translates to:
/// **'To'**
String get weatherToLabel;
/// A task needs at least this temperature (D40).
///
/// In en, this message translates to:
/// **'from {degrees} °C'**
String weatherFrom(String degrees);
/// A task needs at most this temperature (D40).
///
/// In en, this message translates to:
/// **'up to {degrees} °C'**
String weatherUpTo(String degrees);
/// A range of temperatures (D40).
///
/// In en, this message translates to:
/// **'{low}–{high} °C'**
String weatherBetween(String low, String high);
/// Closes the sheet of a task's weather, keeping what was chosen (D40).
///
/// In en, this message translates to:
/// **'Done'**
String get weatherDone;
/// Under a task's weather where its day's forecast gives what it needs (D40).
///
/// In en, this message translates to:
/// **'The forecast fits'**
String get weatherFits;
/// Under a task's weather, and its row's mark, where its day's forecast doesn't give what it needs (D40).
///
/// In en, this message translates to:
/// **'The forecast doesn\'t fit: {missed}'**
String weatherDoesNotFit(String missed);
/// What of the weather a task needs its forecast misses (D40).
///
/// In en, this message translates to:
/// **'{need, select, dry{rain} sunny{clouds} temperature{temperature} calm{wind} other{weather}}'**
String weatherMiss(String need);
/// A day's sky by its forecast, from Open-Meteo's weather code (D40).
///
/// In en, this message translates to:
/// **'{conditions, select, clear{Clear} partlyCloudy{Partly cloudy} cloudy{Overcast} fog{Fog} drizzle{Drizzle} rain{Rain} freezingRain{Freezing rain} snow{Snow} rainShowers{Showers} snowShowers{Snow showers} thunderstorm{Thunderstorm} other{Weather}}'**
String weatherConditions(String conditions);
/// The date picker's days whose forecast gives what the task needs (D40).
///
/// In en, this message translates to:
/// **'Days the weather fits'**
String get weatherFittingDays;
/// The date picker, where no day of the forecast fits (D40).
///
/// In en, this message translates to:
/// **'No day of the forecast fits'**
String get weatherNoFittingDay;
/// Settings' group of the forecast (D40).
///
/// In en, this message translates to:
/// **'Weather'**
String get weatherSettings;
/// Settings: the place days' forecasts and tasks' weather are for (D40).
///
/// In en, this message translates to:
/// **'Place of the forecast'**
String get weatherPlace;
/// Settings, where no place is set (D40).
///
/// In en, this message translates to:
/// **'None: each task\'s own place'**
String get weatherPlaceNone;
/// Settings, below the place of the forecast (D40).
///
/// In en, this message translates to:
/// **'Days show this place\'s forecast, and tasks tied to the weather are judged by it. Your device\'s location is never used for it.'**
String get weatherPlaceHelp;
/// Settings: takes the place of the forecast away (D40).
///
/// In en, this message translates to:
/// **'Remove the place'**
String get weatherPlaceRemove;
/// Settings, where the instance's operator switched the weather off (D40).
///
/// In en, this message translates to:
/// **'This instance gives no forecasts.'**
String get weatherOff;
/// The credit Open-Meteo's licence asks for next to its data (D40).
///
/// In en, this message translates to:
/// **'Weather data by Open-Meteo.com'**
String get weatherBy;
}
class _AppLocalizationsDelegate