Skip to content

Commit

Permalink
feat: flutter upgrade and add location autocomplete (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier authored Feb 18, 2025
1 parent dfee70b commit 848b76f
Show file tree
Hide file tree
Showing 19 changed files with 388 additions and 182 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches: [master]

env:
FLUTTER_VERSION: '3.27.4'
FLUTTER_VERSION: '3.29.0'

jobs:
analyze:
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release

on:
push:
branches:
- master
workflow_dispatch:

jobs:
release:
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
release-type: dart
2 changes: 1 addition & 1 deletion .github/workflows/snap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
workflow_dispatch:

env:
FLUTTER_VERSION: "3.27.4"
FLUTTER_VERSION: "3.29.0"

jobs:
build_and_release_linux_snap_edge_amd64:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand Down
3 changes: 3 additions & 0 deletions devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
125 changes: 86 additions & 39 deletions lib/app/side_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,41 @@ import '../extensions/build_context_x.dart';
import '../weather/view/city_search_field.dart';
import '../weather/weather_model.dart';

class SideBar extends StatelessWidget with WatchItMixin {
class SideBar extends StatefulWidget with WatchItStatefulWidgetMixin {
const SideBar({super.key, this.onSelected});

final VoidCallback? onSelected;

@override
State<SideBar> createState() => _SideBarState();
}

class _SideBarState extends State<SideBar> {
@override
Widget build(BuildContext context) {
final theme = context.theme;

final model = di<WeatherModel>();

final favLocationsLength =
watchPropertyValue((WeatherModel m) => m.favLocations.length);
final favLocations = watchPropertyValue((WeatherModel m) => m.favLocations);
final lastLocation = watchPropertyValue((WeatherModel m) => m.lastLocation);
final currentLocation =
watchPropertyValue((WeatherModel m) => m.lastLocation);

final listView = ListView.builder(
itemCount: favLocationsLength,
itemBuilder: (context, index) {
final location = favLocations.elementAt(index);
return Stack(
alignment: Alignment.centerRight,
children: [
YaruMasterTile(
onTap: () {
model.loadWeather(cityName: location);
onSelected?.call();
},
selected: lastLocation == location,
title: Text(
favLocations.elementAt(index),
),
),
if (favLocationsLength > 1 && lastLocation == location)
Positioned(
right: 20,
child: SizedBox.square(
dimension: 30,
child: IconButton(
padding: EdgeInsets.zero,
onPressed: () {
model.removeFavLocation(location).then(
(value) => model.loadWeather(
cityName: favLocations.lastOrNull,
),
);
},
icon: const Icon(
YaruIcons.window_close,
),
),
),
),
],
final selected = currentLocation == favLocations.elementAt(index);
return Tile(
selected: selected,
location: favLocations.elementAt(index),
onClear: favLocationsLength > 1
? () => di<WeatherModel>().loadWeather(
cityName: selected
? favLocations.elementAtOrNull(index - 1)
: currentLocation,
)
: null,
onSelected: widget.onSelected,
);
},
);
Expand Down Expand Up @@ -89,3 +70,69 @@ class SideBar extends StatelessWidget with WatchItMixin {
);
}
}

class Tile extends StatefulWidget {
const Tile({
super.key,
required this.location,
required this.onSelected,
required this.onClear,
required this.selected,
});

final String location;
final VoidCallback? onSelected;
final bool selected;
final Function()? onClear;

@override
State<Tile> createState() => _TileState();
}

class _TileState extends State<Tile> {
bool _hovered = false;

@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => setState(() => _hovered = true),
onExit: (_) => setState(() => _hovered = false),
child: Stack(
alignment: Alignment.centerRight,
children: [
Tooltip(
message: widget.location,
child: YaruMasterTile(
onTap: () {
di<WeatherModel>().loadWeather(cityName: widget.location);
widget.onSelected?.call();
},
selected: widget.selected,
title: Text(
widget.location,
),
),
),
if (widget.onClear != null && (_hovered || widget.selected))
Positioned(
right: 20,
child: SizedBox.square(
dimension: 30,
child: IconButton(
padding: EdgeInsets.zero,
onPressed: () {
di<WeatherModel>().removeFavLocation(widget.location).then(
(_) => widget.onClear?.call(),
);
},
icon: const Icon(
YaruIcons.window_close,
),
),
),
),
],
),
);
}
}
Loading

0 comments on commit 848b76f

Please sign in to comment.