Skip to content

Commit 0dd8b12

Browse files
committed
fix: chart
1 parent a48ccab commit 0dd8b12

7 files changed

Lines changed: 536 additions & 298 deletions

File tree

lib/app/new_home/_models/home_model.dart

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ class HomeModel extends ChangeNotifier {
2828
RealtimeWeather? _weather;
2929
List<History> _alerts = const [];
3030
Map<String, dynamic>? _forecast;
31-
bool _isLoading = false;
32-
Object? _error;
3331
Timer? _autoRefreshTimer;
3432

3533
/// Creates a [HomeModel] backed by [settingsLocation].
@@ -44,58 +42,35 @@ class HomeModel extends ChangeNotifier {
4442
if (_temporaryCode == null) _doRefresh();
4543
}
4644

47-
Future<void> _doRefresh() async {
48-
final code = _temporaryCode ?? _settingsLocation.code;
49-
double? lat;
50-
double? lon;
51-
52-
if (code != null) {
53-
final loc = Global.location[code];
54-
if (loc != null) {
55-
lat = loc.lat;
56-
lon = loc.lng;
57-
}
45+
/// Runs [task] and logs failures under [tag]; returns `null` on error.
46+
static Future<T?> _safe<T>(String tag, Future<T> Function() task) async {
47+
try {
48+
return await task();
49+
} catch (e) {
50+
TalkerManager.instance.error('HomeModel $tag', e);
51+
return null;
5852
}
53+
}
5954

60-
lat ??= _settingsLocation.coordinates?.latitude;
61-
lon ??= _settingsLocation.coordinates?.longitude;
62-
55+
Future<void> _doRefresh() async {
56+
final code = _temporaryCode ?? _settingsLocation.code;
57+
final loc = code != null ? Global.location[code] : null;
58+
final lat = loc?.lat ?? _settingsLocation.coordinates?.latitude;
59+
final lon = loc?.lng ?? _settingsLocation.coordinates?.longitude;
6360
if (lat == null || lon == null) return;
6461

65-
_isLoading = true;
66-
notifyListeners();
67-
6862
// Fetch weather + alerts + forecast in parallel.
6963
final results = await Future.wait<Object?>([
70-
Global.api.getWeatherRealtimeByCoords(lat, lon).then<Object?>((v) => v).catchError((e) {
71-
TalkerManager.instance.error('HomeModel weather', e);
72-
return null;
73-
}),
74-
code == null
75-
? Future<Object?>.value(null)
76-
: Global.api.getRealtimeRegion(code).then<Object?>((v) => v).catchError((e) {
77-
TalkerManager.instance.error('HomeModel alerts', e);
78-
return null;
79-
}),
80-
code == null
81-
? Future<Object?>.value(null)
82-
: Global.api.getWeatherForecast(code).then<Object?>((v) => v).catchError((e) {
83-
TalkerManager.instance.error('HomeModel forecast', e);
84-
return null;
85-
}),
64+
_safe('weather', () => Global.api.getWeatherRealtimeByCoords(lat, lon)),
65+
if (code != null) _safe('alerts', () => Global.api.getRealtimeRegion(code)) else Future.value(null),
66+
if (code != null) _safe('forecast', () => Global.api.getWeatherForecast(code)) else Future.value(null),
8667
]);
8768

88-
final weather = results[0];
89-
final alerts = results[1];
90-
final forecast = results[2];
91-
92-
_weather = weather is RealtimeWeather ? weather : _weather;
93-
_alerts = alerts is List<History>
94-
? alerts.sorted((a, b) => b.time.send.compareTo(a.time.send))
69+
if (results[0] is RealtimeWeather) _weather = results[0] as RealtimeWeather;
70+
_alerts = results[1] is List<History>
71+
? (results[1]! as List<History>).sorted((a, b) => b.time.send.compareTo(a.time.send))
9572
: const [];
96-
_forecast = forecast is Map<String, dynamic> ? forecast : _forecast;
97-
_error = (weather == null && _weather == null) ? Exception('weather fetch failed') : null;
98-
_isLoading = false;
73+
if (results[2] is Map<String, dynamic>) _forecast = results[2] as Map<String, dynamic>;
9974
notifyListeners();
10075
}
10176

@@ -112,12 +87,6 @@ class HomeModel extends ChangeNotifier {
11287
/// The 24-hour weather forecast for the active location, or `null` if missing.
11388
Map<String, dynamic>? get forecast => _forecast;
11489

115-
/// Whether a weather fetch is currently in progress.
116-
bool get isLoading => _isLoading;
117-
118-
/// The error from the last failed fetch, or `null` when the last fetch succeeded.
119-
Object? get error => _error;
120-
12190
/// The currently active temporary location code, or `null` when unset.
12291
String? get temporaryCode => _temporaryCode;
12392

lib/app/new_home/_models/weather_params.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ double windWeight(RealtimeWeatherData? d) {
5656
return (d.wind.beaufort / 8.0).clamp(0.0, 1.0);
5757
}
5858

59+
/// Time-of-day salutation for the given [hour] (0–23, local time).
60+
///
61+
/// Used in both the top-of-page [Greeting] and the [AssistantHint] hint text.
62+
String greetingForHour(int hour) => switch (hour) {
63+
< 6 => '夜深了',
64+
< 12 => '早安',
65+
< 18 => '午安',
66+
_ => '晚安',
67+
};
68+
5969
/// Solar phase in `[0, 1]` across the visible window from 5am to 7pm.
6070
///
6171
/// `0.0` ≈ sunrise at the eastern edge, `0.5` ≈ noon overhead,

lib/app/new_home/_widgets/assistant_hint.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
library;
33

44
import 'package:dpip/app/new_home/_models/home_model.dart';
5+
import 'package:dpip/app/new_home/_models/weather_params.dart';
56
import 'package:dpip/utils/extensions/build_context.dart';
67
import 'package:flutter/material.dart';
78
import 'package:material_symbols_icons/material_symbols_icons.dart';
@@ -59,14 +60,7 @@ class AssistantHint extends StatelessWidget {
5960
}
6061

6162
String _buildHintText(double temperature, String weather) {
62-
final hour = DateTime.now().hour;
63-
64-
final greeting = switch (hour) {
65-
< 6 => '夜深了',
66-
< 12 => '早安',
67-
< 18 => '午安',
68-
_ => '晚安',
69-
};
63+
final greeting = greetingForHour(DateTime.now().hour);
7064

7165
final tempComment = switch (temperature) {
7266
< 10 => '天氣寒冷,注意保暖。',

0 commit comments

Comments
 (0)