Skip to content

Commit cbd080a

Browse files
authored
Add forecast (#7)
1 parent dc5d290 commit cbd080a

File tree

10 files changed

+214
-122
lines changed

10 files changed

+214
-122
lines changed

lib/constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ const kAppStateFileName = 'appstate.json';
55
const kSettingsFileName = 'settings.json';
66
const kFavLocationsFileName = 'favlocations.json';
77
const kLastLocation = 'lastLocation';
8+
9+
const kPaneWidth = 240.0;

lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:watch_it/watch_it.dart';
99
import 'package:yaru/yaru.dart';
1010

1111
import 'src/app/app.dart';
12+
import 'src/app/app_model.dart';
1213
import 'src/locations/locations_service.dart';
1314
import 'src/weather/weather_model.dart';
1415

@@ -23,6 +24,7 @@ Future<void> main() async {
2324
LocationsService(),
2425
dispose: (s) => s.dispose(),
2526
);
27+
di.registerSingleton(AppModel());
2628
final weatherModel = WeatherModel(
2729
locationsService: di<LocationsService>(),
2830
openWeather: di<OpenWeather>(),

lib/src/app/app.dart

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
44
import 'package:watch_it/watch_it.dart';
55
import 'package:yaru/yaru.dart';
66

7+
import '../../constants.dart';
78
import '../../weather.dart';
89
import '../weather/view/city_search_field.dart';
910
import '../weather/weather_model.dart';
@@ -46,6 +47,7 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin {
4647
controller: YaruPageController(
4748
length: favLocationsLength == 0 ? 1 : favLocationsLength,
4849
),
50+
layoutDelegate: const YaruMasterFixedPaneDelegate(paneWidth: kPaneWidth),
4951
tileBuilder: (context, index, selected, availableWidth) {
5052
final location = favLocations.elementAt(index);
5153
return YaruMasterTile(
@@ -56,17 +58,20 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin {
5658
favLocations.elementAt(index),
5759
),
5860
trailing: favLocationsLength > 1
59-
? IconButton(
60-
padding: EdgeInsets.zero,
61-
onPressed: () {
62-
model.removeFavLocation(location).then(
63-
(value) => model.init(
64-
cityName: favLocations.lastOrNull,
65-
),
66-
);
67-
},
68-
icon: const Icon(
69-
YaruIcons.window_close,
61+
? Center(
62+
widthFactor: 0.1,
63+
child: IconButton(
64+
padding: EdgeInsets.zero,
65+
onPressed: () {
66+
model.removeFavLocation(location).then(
67+
(value) => model.init(
68+
cityName: favLocations.lastOrNull,
69+
),
70+
);
71+
},
72+
icon: const Icon(
73+
YaruIcons.window_close,
74+
),
7075
),
7176
)
7277
: null,
@@ -79,21 +84,7 @@ class MasterDetailPage extends StatelessWidget with WatchItMixin {
7984
backgroundColor: YaruMasterDetailTheme.of(context).sideBarColor,
8085
border: BorderSide.none,
8186
style: YaruTitleBarStyle.undecorated,
82-
leading: Center(
83-
child: YaruIconButton(
84-
padding: EdgeInsets.zero,
85-
icon: const Icon(
86-
Icons.location_on,
87-
size: 16,
88-
),
89-
onPressed: () => model.init(cityName: null),
90-
),
91-
),
92-
titleSpacing: 0,
93-
title: const Padding(
94-
padding: EdgeInsets.only(right: 15),
95-
child: CitySearchField(),
96-
),
87+
title: const CitySearchField(),
9788
),
9889
);
9990
}

lib/src/app/app_model.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import 'package:safe_change_notifier/safe_change_notifier.dart';
2+
3+
class AppModel extends SafeChangeNotifier {
4+
int _tabIndex = 0;
5+
int get tabIndex => _tabIndex;
6+
set tabIndex(int value) {
7+
if (value == _tabIndex) return;
8+
_tabIndex = value;
9+
notifyListeners();
10+
}
11+
}

lib/src/weather/view/city_search_field.dart

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import '../weather_model.dart';
21
import 'package:flutter/material.dart';
32
import 'package:watch_it/watch_it.dart';
4-
import 'package:yaru/icons.dart';
3+
import 'package:yaru/yaru.dart';
4+
5+
import '../weather_model.dart';
56

67
class CitySearchField extends StatefulWidget {
78
const CitySearchField({
@@ -33,19 +34,46 @@ class _CitySearchFieldState extends State<CitySearchField> {
3334
var textField = TextField(
3435
onSubmitted: (value) => model.init(cityName: _controller.text),
3536
controller: _controller,
37+
onTap: () {
38+
_controller.selection = TextSelection(
39+
baseOffset: 0,
40+
extentOffset: _controller.value.text.length,
41+
);
42+
},
3643
style: Theme.of(context)
3744
.textTheme
3845
.bodyMedium
3946
?.copyWith(fontWeight: FontWeight.w500),
40-
decoration: const InputDecoration(
41-
prefixIcon: Icon(
47+
decoration: InputDecoration(
48+
prefixIcon: const Icon(
4249
YaruIcons.search,
4350
size: 15,
4451
),
45-
prefixIconConstraints: BoxConstraints(minWidth: 35, minHeight: 30),
46-
contentPadding: EdgeInsets.all(8),
52+
prefixIconConstraints:
53+
const BoxConstraints(minWidth: 35, minHeight: 30),
4754
filled: true,
4855
hintText: 'Cityname',
56+
suffixIconConstraints: const BoxConstraints(
57+
maxHeight: kYaruTitleBarItemHeight,
58+
minHeight: kYaruTitleBarItemHeight,
59+
minWidth: kYaruTitleBarItemHeight,
60+
maxWidth: kYaruTitleBarItemHeight,
61+
),
62+
suffixIcon: ClipRRect(
63+
borderRadius: const BorderRadius.only(
64+
topRight: Radius.circular(kYaruButtonRadius),
65+
bottomRight: Radius.circular(kYaruButtonRadius),
66+
),
67+
child: Material(
68+
color: Colors.transparent,
69+
child: InkWell(
70+
child: const Icon(
71+
YaruIcons.location,
72+
),
73+
onTap: () => model.init(cityName: null),
74+
),
75+
),
76+
),
4977
),
5078
);
5179
return textField;

lib/src/weather/view/forecast_tile.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_weather_bg_null_safety/bg/weather_bg.dart';
33
import 'package:flutter_weather_bg_null_safety/flutter_weather_bg.dart';
44
import 'package:open_weather_client/models/weather_data.dart';
5+
import '../../../build_context_x.dart';
56
import '../weather_utils.dart';
67
import '../../../string_x.dart';
78
import '../weather_data_x.dart';
89

910
class ForecastTile extends StatefulWidget {
10-
final List<WeatherData> data;
1111
final WeatherData selectedData;
1212
final String? cityName;
1313
final double fontSize;
@@ -31,7 +31,6 @@ class ForecastTile extends StatefulWidget {
3131
required this.padding,
3232
this.time,
3333
this.borderRadius = const BorderRadius.all(Radius.circular(10)),
34-
required this.data,
3534
});
3635

3736
@override
@@ -41,8 +40,8 @@ class ForecastTile extends StatefulWidget {
4140
class _ForecastTileState extends State<ForecastTile> {
4241
@override
4342
Widget build(BuildContext context) {
44-
final theme = Theme.of(context);
45-
final light = theme.brightness == Brightness.light;
43+
final theme = context.theme;
44+
final light = context.light;
4645
final style = theme.textTheme.headlineSmall?.copyWith(
4746
color: Colors.white,
4847
fontSize: 20,
@@ -120,7 +119,7 @@ class _ForecastTileState extends State<ForecastTile> {
120119
child: Stack(
121120
children: [
122121
Opacity(
123-
opacity: light ? 1 : 0.4,
122+
opacity: light ? 1 : 0.6,
124123
child: ClipRRect(
125124
borderRadius: widget.borderRadius,
126125
child: WeatherBg(

lib/src/weather/view/today_tile.dart

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,19 @@ class TodayTile extends StatelessWidget {
9595
],
9696
),
9797
if (cityName != null)
98-
Text(
99-
cityName!,
100-
style: style,
101-
)
102-
else if (position != null)
10398
SizedBox(
104-
width: 300,
99+
width: width,
105100
child: Text(
106-
position ?? '',
101+
cityName!,
107102
style: style,
108103
textAlign: TextAlign.center,
109104
),
105+
)
106+
else if (position != null)
107+
Text(
108+
position ?? '',
109+
style: style,
110+
textAlign: TextAlign.center,
110111
),
111112
];
112113

lib/src/weather/weather_model.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class WeatherModel extends SafeChangeNotifier {
121121
}
122122

123123
List<WeatherData>? _fiveDaysForCast;
124-
List<WeatherData> todayForeCast() {
124+
List<WeatherData> get todayForeCast {
125125
if (_fiveDaysForCast == null) return [];
126126

127127
final foreCast = _fiveDaysForCast!;

0 commit comments

Comments
 (0)