From 74cce8a70f07fd86d9334468753067dc44a23462 Mon Sep 17 00:00:00 2001 From: Frederik Feichtmeier Date: Mon, 10 Feb 2025 18:23:18 +0100 Subject: [PATCH] chore: update flutter, remove custom settings, build snap on github (#14) * chore: update flutter and remove custom settings * chore: build snap on github --- .github/workflows/ci.yml | 4 +- .github/workflows/snap.yaml | 61 +++ README.md | 15 + analysis_options.yaml | 7 +- l10n.yaml | 2 +- lib/app/app.dart | 133 ++++++ lib/{src => }/app/app_model.dart | 0 lib/{src => }/app/offline_page.dart | 2 +- lib/{src => }/app/side_bar.dart | 6 +- lib/{src => extensions}/build_context_x.dart | 0 lib/{ => extensions}/string_x.dart | 0 lib/{src => }/l10n/app_de.arb | 0 lib/{src => }/l10n/app_en.arb | 0 lib/{src => }/l10n/l10n.dart | 0 lib/locations/locations_service.dart | 46 ++ lib/main.dart | 24 +- lib/register_dependencies.dart | 61 +++ lib/settings/settings_model.dart | 38 ++ lib/settings/settings_service.dart | 47 +++ lib/src/app/app.dart | 102 ----- lib/src/locations/locations_service.dart | 69 --- lib/utils.dart | 233 ---------- lib/weather.dart | 2 +- lib/{src => }/weather/theme_x.dart | 2 +- .../weather/view/city_search_field.dart | 8 +- .../weather/view/daily_bar_chart.dart | 10 +- lib/{src => }/weather/view/error_view.dart | 6 +- .../weather/view/hourly_line_chart.dart | 15 +- lib/{src => }/weather/view/now_tile.dart | 6 +- lib/{src => }/weather/view/weather_page.dart | 2 +- lib/{src => }/weather/weather_data_x.dart | 0 lib/{src => }/weather/weather_model.dart | 26 +- lib/{src => }/weather/weekday.dart | 0 linux/flutter/generated_plugin_registrant.cc | 12 +- linux/flutter/generated_plugins.cmake | 3 +- macos/Flutter/GeneratedPluginRegistrant.swift | 8 +- pubspec.lock | 398 +++++++++++++----- pubspec.yaml | 20 +- snap/snapcraft.yaml | 6 +- 39 files changed, 786 insertions(+), 588 deletions(-) create mode 100644 .github/workflows/snap.yaml create mode 100644 lib/app/app.dart rename lib/{src => }/app/app_model.dart (100%) rename lib/{src => }/app/offline_page.dart (97%) rename lib/{src => }/app/side_bar.dart (95%) rename lib/{src => extensions}/build_context_x.dart (100%) rename lib/{ => extensions}/string_x.dart (100%) rename lib/{src => }/l10n/app_de.arb (100%) rename lib/{src => }/l10n/app_en.arb (100%) rename lib/{src => }/l10n/l10n.dart (100%) create mode 100644 lib/locations/locations_service.dart create mode 100644 lib/register_dependencies.dart create mode 100644 lib/settings/settings_model.dart create mode 100644 lib/settings/settings_service.dart delete mode 100644 lib/src/app/app.dart delete mode 100644 lib/src/locations/locations_service.dart delete mode 100644 lib/utils.dart rename lib/{src => }/weather/theme_x.dart (86%) rename lib/{src => }/weather/view/city_search_field.dart (93%) rename lib/{src => }/weather/view/daily_bar_chart.dart (96%) rename lib/{src => }/weather/view/error_view.dart (96%) rename lib/{src => }/weather/view/hourly_line_chart.dart (94%) rename lib/{src => }/weather/view/now_tile.dart (96%) rename lib/{src => }/weather/view/weather_page.dart (98%) rename lib/{src => }/weather/weather_data_x.dart (100%) rename lib/{src => }/weather/weather_model.dart (91%) rename lib/{src => }/weather/weekday.dart (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b95854..34c70d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ on: branches: [master] env: - FLUTTER_VERSION: '3.19.x' + FLUTTER_VERSION: '3.27.4' jobs: analyze: @@ -49,6 +49,6 @@ jobs: channel: 'stable' flutter-version: ${{env.FLUTTER_VERSION}} - run: sudo apt update - - run: sudo apt install -y clang cmake curl libgtk-3-dev ninja-build pkg-config unzip libunwind-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libmpv-dev + - run: sudo apt install -y clang cmake curl libgtk-3-dev ninja-build pkg-config unzip libunwind-dev libsecret-1-dev - run: flutter pub get - run: flutter build linux -v \ No newline at end of file diff --git a/.github/workflows/snap.yaml b/.github/workflows/snap.yaml new file mode 100644 index 0000000..4b2dbf7 --- /dev/null +++ b/.github/workflows/snap.yaml @@ -0,0 +1,61 @@ +name: Create Snap Package + +on: + push: + branches: + - master + workflow_dispatch: + +env: + FLUTTER_VERSION: "3.27.4" + +jobs: + build_and_release_linux_snap_edge_amd64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - uses: subosito/flutter-action@v2 + with: + channel: "stable" + flutter-version: ${{env.FLUTTER_VERSION}} + - run: sudo apt update + - run: sudo apt install -y clang cmake curl libgtk-3-dev ninja-build pkg-config unzip libunwind-dev libsecret-1-dev + - run: flutter pub get + - uses: snapcore/action-build@v1 + env: + API_KEY: ${{ secrets.API_KEY }} + id: build + - uses: snapcore/action-publish@v1 + if: steps.build.outcome == 'success' + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.STORE_LOGIN }} + with: + snap: ${{ steps.build.outputs.snap }} + release: edge + + build_and_release_linux_snap_edge_arm64: + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 5 + - uses: subosito/flutter-action@v2 + with: + channel: "main" + flutter-version: ${{env.FLUTTER_VERSION}} + - run: sudo apt update + - run: sudo apt install -y clang cmake curl libgtk-3-dev ninja-build pkg-config unzip libunwind-dev libsecret-1-dev + - run: flutter pub get + - uses: snapcore/action-build@v1 + id: build + env: + API_KEY: ${{ secrets.API_KEY }} + - uses: snapcore/action-publish@v1 + if: steps.build.outcome == 'success' + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.STORE_LOGIN }} + with: + snap: ${{ steps.build.outputs.snap }} + release: edge diff --git a/README.md b/README.md index 89cf0a7..f350b75 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,13 @@ Requires an api key from [openweathermap](https://openweathermap.org) which you need to create yourself (free tier) in your own account. + ## Build +### Install libsecret + +`sudo apt install libsecret-1-dev` + ### Install Flutter
@@ -22,3 +27,13 @@ sudo apt -y install git curl cmake meson make clang libgtk-3-dev pkg-config && m ```
+ +### Run the app + +For the first run or after every `flutter clean`, the app needs to be started with your API_KEY: + +`flutter run --dart-define=API_KEY=YOUR_API_KEY_HERE_WITHOUT_QUOTES` + +any other times you can use + +`flutter run` diff --git a/analysis_options.yaml b/analysis_options.yaml index 90633ee..1ee12d1 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -10,4 +10,9 @@ linter: require_trailing_commas: true use_super_parameters: true close_sinks: true - prefer_relative_imports: true \ No newline at end of file + prefer_relative_imports: true + sort_pub_dependencies: true + unnecessary_parenthesis: true + unnecessary_await_in_return: true + unnecessary_late: true + unnecessary_breaks: true \ No newline at end of file diff --git a/l10n.yaml b/l10n.yaml index 03f4a93..c3dc2f3 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -1,4 +1,4 @@ -arb-dir: lib/src/l10n +arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: app_localizations.dart nullable-getter: false diff --git a/lib/app/app.dart b/lib/app/app.dart new file mode 100644 index 0000000..4de2044 --- /dev/null +++ b/lib/app/app.dart @@ -0,0 +1,133 @@ +import 'dart:io'; +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:flutter_weather_bg_null_safety/bg/weather_bg.dart'; +import 'package:watch_it/watch_it.dart'; +import 'package:yaru/yaru.dart'; + +import '../constants.dart'; +import '../weather.dart'; +import '../extensions/build_context_x.dart'; +import '../l10n/l10n.dart'; +import '../weather/weather_model.dart'; +import 'side_bar.dart'; + +class App extends StatelessWidget { + const App({super.key}); + + @override + Widget build(BuildContext context) => MaterialApp( + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: supportedLocales, + onGenerateTitle: (context) => 'MusicPod', + debugShowCheckedModeBanner: false, + theme: yaruLight, + darkTheme: yaruDark.copyWith( + tabBarTheme: TabBarTheme.of(context).copyWith( + labelColor: Colors.white, + unselectedLabelColor: Colors.white.withValues( + alpha: 0.8, + ), + ), + ), + home: const _StartPage(), + scrollBehavior: const MaterialScrollBehavior().copyWith( + dragDevices: { + PointerDeviceKind.mouse, + PointerDeviceKind.touch, + PointerDeviceKind.stylus, + PointerDeviceKind.unknown, + PointerDeviceKind.trackpad, + }, + ), + ); +} + +class _StartPage extends StatefulWidget { + const _StartPage(); + + @override + State<_StartPage> createState() => _StartPageState(); +} + +class _StartPageState extends State<_StartPage> { + late final Future _allReady; + + @override + void initState() { + super.initState(); + _allReady = di.allReady(); + } + + @override + Widget build(BuildContext context) => FutureBuilder( + future: _allReady, + builder: (context, snapshot) => + snapshot.hasData ? const _AppPage() : const _LoadingPage(), + ); +} + +class _LoadingPage extends StatelessWidget { + const _LoadingPage(); + + @override + Widget build(BuildContext context) => const Scaffold( + appBar: YaruWindowTitleBar( + border: BorderSide.none, + backgroundColor: Colors.transparent, + ), + body: Center( + child: YaruCircularProgressIndicator(), + ), + ); +} + +class _AppPage extends StatefulWidget with WatchItStatefulWidgetMixin { + const _AppPage(); + + @override + State<_AppPage> createState() => _AppPageState(); +} + +class _AppPageState extends State<_AppPage> { + @override + void initState() { + di().loadWeather(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final weatherType = watchPropertyValue((WeatherModel m) => m.weatherType); + + return LayoutBuilder( + builder: (context, constraints) { + var list = [ + if (constraints.maxWidth > kBreakPoint) const SideBar(), + Expanded( + child: WeatherPage( + showDrawer: constraints.maxWidth < kBreakPoint, + ), + ), + ]; + return Stack( + alignment: Alignment.center, + children: [ + Opacity( + opacity: Platform.isMacOS ? (context.light ? 1 : 0.6) : 0.7, + child: WeatherBg( + weatherType: weatherType, + width: constraints.maxWidth, + height: constraints.maxHeight, + ), + ), + Row( + children: Platform.isMacOS ? list.reversed.toList() : list, + ), + ], + ); + }, + ); + } +} diff --git a/lib/src/app/app_model.dart b/lib/app/app_model.dart similarity index 100% rename from lib/src/app/app_model.dart rename to lib/app/app_model.dart diff --git a/lib/src/app/offline_page.dart b/lib/app/offline_page.dart similarity index 97% rename from lib/src/app/offline_page.dart rename to lib/app/offline_page.dart index 8707eea..c432c77 100644 --- a/lib/src/app/offline_page.dart +++ b/lib/app/offline_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:yaru/yaru.dart'; -import '../build_context_x.dart'; +import '../extensions/build_context_x.dart'; import '../l10n/l10n.dart'; class OfflinePage extends StatelessWidget { diff --git a/lib/src/app/side_bar.dart b/lib/app/side_bar.dart similarity index 95% rename from lib/src/app/side_bar.dart rename to lib/app/side_bar.dart index 59aa2c1..497ce27 100644 --- a/lib/src/app/side_bar.dart +++ b/lib/app/side_bar.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../constants.dart'; -import '../build_context_x.dart'; +import '../constants.dart'; +import '../extensions/build_context_x.dart'; import '../weather/view/city_search_field.dart'; import '../weather/weather_model.dart'; @@ -66,7 +66,7 @@ class SideBar extends StatelessWidget with WatchItMixin { ); return Material( - color: theme.colorScheme.surface.withOpacity(0.4), + color: theme.colorScheme.surface.withValues(alpha: 0.4), child: SizedBox( width: kPaneWidth, child: Column( diff --git a/lib/src/build_context_x.dart b/lib/extensions/build_context_x.dart similarity index 100% rename from lib/src/build_context_x.dart rename to lib/extensions/build_context_x.dart diff --git a/lib/string_x.dart b/lib/extensions/string_x.dart similarity index 100% rename from lib/string_x.dart rename to lib/extensions/string_x.dart diff --git a/lib/src/l10n/app_de.arb b/lib/l10n/app_de.arb similarity index 100% rename from lib/src/l10n/app_de.arb rename to lib/l10n/app_de.arb diff --git a/lib/src/l10n/app_en.arb b/lib/l10n/app_en.arb similarity index 100% rename from lib/src/l10n/app_en.arb rename to lib/l10n/app_en.arb diff --git a/lib/src/l10n/l10n.dart b/lib/l10n/l10n.dart similarity index 100% rename from lib/src/l10n/l10n.dart rename to lib/l10n/l10n.dart diff --git a/lib/locations/locations_service.dart b/lib/locations/locations_service.dart new file mode 100644 index 0000000..9916dc2 --- /dev/null +++ b/lib/locations/locations_service.dart @@ -0,0 +1,46 @@ +import 'dart:async'; + +import '../settings/settings_service.dart'; + +class LocationsService { + LocationsService({ + required SettingsService settingsService, + }) : _settingsService = settingsService; + final SettingsService _settingsService; + + String? get lastLocation => + _settingsService.getString(key: SettingKeys.lastLocation); + void setLastLocation(String? value) { + if (value == null) return; + _settingsService.setString(key: SettingKeys.lastLocation, value: value); + } + + Set get favLocations => + _settingsService + .getStrings(key: SettingKeys.favoriteLocations) + ?.toSet() ?? + {}; + bool isFavLocation(String value) => favLocations.contains(value); + + void addFavLocation(String name) { + if (favLocations.contains(name)) return; + final favs = Set.from(favLocations); + favs.add(name); + _settingsService.setStrings( + key: SettingKeys.favoriteLocations, + value: favs.toList(), + ); + } + + Future removeFavLocation(String name) async { + if (!favLocations.contains(name)) return; + final favs = Set.from(favLocations); + favs.remove(name); + _settingsService.setStrings( + key: SettingKeys.favoriteLocations, + value: favs.toList(), + ); + } + + Stream get propertiesChanged => _settingsService.propertiesChanged; +} diff --git a/lib/main.dart b/lib/main.dart index ffe9698..0189cc0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,31 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:open_weather_client/open_weather.dart'; -import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import 'src/app/app.dart'; -import 'src/app/app_model.dart'; -import 'src/locations/locations_service.dart'; -import 'src/weather/weather_model.dart'; +import 'app/app.dart'; +import 'register_dependencies.dart'; Future main() async { await YaruWindowTitleBar.ensureInitialized(); - final locationsService = LocationsService(); - await locationsService.init(); - di.registerSingleton( - locationsService, - dispose: (s) => s.dispose(), - ); - di.registerSingleton(AppModel()); - - di.registerLazySingleton( - () => WeatherModel( - locationsService: locationsService, - openWeather: OpenWeather(apiKey: locationsService.apiKey ?? ''), - ), - dispose: (s) => s.dispose(), - ); + registerDependencies(); runApp(const App()); } diff --git a/lib/register_dependencies.dart b/lib/register_dependencies.dart new file mode 100644 index 0000000..f09dc50 --- /dev/null +++ b/lib/register_dependencies.dart @@ -0,0 +1,61 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:open_weather_client/open_weather.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:watch_it/watch_it.dart'; + +import 'app/app_model.dart'; +import 'locations/locations_service.dart'; +import 'settings/settings_service.dart'; +import 'weather/weather_model.dart'; + +void registerDependencies() { + di + ..registerSingletonAsync( + () async { + const flutterSecureStorage = FlutterSecureStorage( + aOptions: AndroidOptions(encryptedSharedPreferences: true), + ); + + const apiKey = String.fromEnvironment('API_KEY', defaultValue: ''); + + if (apiKey.isNotEmpty) { + flutterSecureStorage.write(key: SettingKeys.apiKey, value: apiKey); + } + return flutterSecureStorage; + }, + ) + ..registerSingletonAsync( + () async => SharedPreferences.getInstance(), + ) + ..registerSingletonWithDependencies( + () => SettingsService( + sharedPreferences: di(), + flutterSecureStorage: di(), + ), + dependsOn: [FlutterSecureStorage, SharedPreferences], + dispose: (s) => s.dispose(), + ) + ..registerSingletonWithDependencies( + () => LocationsService( + settingsService: di(), + ), + dependsOn: [SettingsService], + ) + ..registerSingletonAsync( + () async => OpenWeather( + apiKey: + await di().read(key: SettingKeys.apiKey) ?? + '', + ), + dependsOn: [SettingsService], + ) + ..registerSingletonWithDependencies( + () => WeatherModel( + locationsService: di(), + openWeather: di(), + ), + dependsOn: [OpenWeather], + dispose: (s) => s.dispose(), + ) + ..registerLazySingleton(AppModel.new); +} diff --git a/lib/settings/settings_model.dart b/lib/settings/settings_model.dart new file mode 100644 index 0000000..1b39efa --- /dev/null +++ b/lib/settings/settings_model.dart @@ -0,0 +1,38 @@ +import 'dart:async'; + +import 'package:safe_change_notifier/safe_change_notifier.dart'; + +import 'settings_service.dart'; + +class SettingsModel extends SafeChangeNotifier { + SettingsModel({ + required SettingsService service, + }) : _service = service; + + final SettingsService _service; + + StreamSubscription? _propertiesChangedSub; + + String? getString({required String key}) => _service.getString(key: key); + Future getStringSecure({required String key}) => + _service.getStringSecure(key: key); + void setString({ + required String key, + required String value, + bool secure = false, + }) async => + _service.setString( + key: key, + value: value, + secure: secure, + ); + + void init() => _propertiesChangedSub ??= + _service.propertiesChanged.listen((_) => notifyListeners()); + + @override + Future dispose() async { + await _propertiesChangedSub?.cancel(); + super.dispose(); + } +} diff --git a/lib/settings/settings_service.dart b/lib/settings/settings_service.dart new file mode 100644 index 0000000..c0ffce2 --- /dev/null +++ b/lib/settings/settings_service.dart @@ -0,0 +1,47 @@ +import 'dart:async'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class SettingsService { + SettingsService({ + required SharedPreferences sharedPreferences, + required FlutterSecureStorage flutterSecureStorage, + }) : _preferences = sharedPreferences, + _flutterSecureStorage = flutterSecureStorage; + + final SharedPreferences _preferences; + final FlutterSecureStorage _flutterSecureStorage; + final _propertiesChangedController = StreamController.broadcast(); + Stream get propertiesChanged => _propertiesChangedController.stream; + void notify(bool saved) { + if (saved) _propertiesChangedController.add(true); + } + + String? getString({required String key}) => _preferences.getString(key); + Future getStringSecure({required String key}) => + _flutterSecureStorage.read(key: key); + void setString({ + required String key, + required String value, + bool secure = false, + }) => + secure + ? _flutterSecureStorage + .write(key: key, value: value) + .then((_) => _propertiesChangedController.add(true)) + : _preferences.setString(key, value).then(notify); + + List? getStrings({required String key}) => + _preferences.getStringList(key); + void setStrings({required String key, required List value}) => + _preferences.setStringList(key, value).then(notify); + + Future dispose() async => _propertiesChangedController.close(); +} + +class SettingKeys { + static const String apiKey = 'apiKey'; + static const favoriteLocations = 'favoriteLocations'; + static const lastLocation = 'lastLocation'; +} diff --git a/lib/src/app/app.dart b/lib/src/app/app.dart deleted file mode 100644 index a1f4e5d..0000000 --- a/lib/src/app/app.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'dart:io'; -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:flutter_weather_bg_null_safety/bg/weather_bg.dart'; -import 'package:watch_it/watch_it.dart'; -import 'package:yaru/yaru.dart'; - -import '../../constants.dart'; -import '../../weather.dart'; -import '../build_context_x.dart'; -import '../l10n/l10n.dart'; -import '../weather/weather_model.dart'; -import 'side_bar.dart'; - -class App extends StatelessWidget { - const App({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: supportedLocales, - onGenerateTitle: (context) => 'MusicPod', - debugShowCheckedModeBanner: false, - theme: yaruLight, - darkTheme: yaruDark.copyWith( - tabBarTheme: TabBarTheme.of(context).copyWith( - labelColor: Colors.white, - unselectedLabelColor: Colors.white.withOpacity( - 0.8, - ), - ), - ), - home: const AppPage(), - scrollBehavior: const MaterialScrollBehavior().copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.stylus, - PointerDeviceKind.unknown, - PointerDeviceKind.trackpad, - }, - ), - ); - } -} - -class AppPage extends StatefulWidget with WatchItStatefulWidgetMixin { - const AppPage({super.key}); - - @override - State createState() => _AppPageState(); -} - -class _AppPageState extends State { - @override - void initState() { - YaruWindow.of(context).onClose( - () async { - await di.reset(); - return true; - }, - ); - di().loadWeather(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - final weatherType = watchPropertyValue((WeatherModel m) => m.weatherType); - - return LayoutBuilder( - builder: (context, constraints) { - var list = [ - if (constraints.maxWidth > kBreakPoint) const SideBar(), - Expanded( - child: WeatherPage( - showDrawer: constraints.maxWidth < kBreakPoint, - ), - ), - ]; - return Stack( - alignment: Alignment.center, - children: [ - Opacity( - opacity: Platform.isMacOS ? (context.light ? 1 : 0.6) : 0.7, - child: WeatherBg( - weatherType: weatherType, - width: constraints.maxWidth, - height: constraints.maxHeight, - ), - ), - Row( - children: Platform.isMacOS ? list.reversed.toList() : list, - ), - ], - ); - }, - ); - } -} diff --git a/lib/src/locations/locations_service.dart b/lib/src/locations/locations_service.dart deleted file mode 100644 index e7bbe29..0000000 --- a/lib/src/locations/locations_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'dart:async'; - -import '../../constants.dart'; -import '../../utils.dart'; - -class LocationsService { - String? _apiKey; - String? get apiKey => _apiKey; - Future setApiKey(String? value) { - if (value == _apiKey) return Future.value(); - return writeSetting(kApiKey, value).then((_) { - _apiKey = value; - _apiKeyController.add(true); - }); - } - - final _apiKeyController = StreamController.broadcast(); - Stream get apiKeyChanged => _apiKeyController.stream; - - String? _lastLocation; - String? get lastLocation => _lastLocation; - void setLastLocation(String? value) { - if (value == _lastLocation) return; - writeAppState(kLastLocation, value).then((_) { - _lastLocation = value; - _lastLocationController.add(true); - }); - } - - final _lastLocationController = StreamController.broadcast(); - Stream get lastLocationChanged => _lastLocationController.stream; - - Set _favLocations = {}; - Set get favLocations => _favLocations; - bool isFavLocation(String value) => _favLocations.contains(value); - final _favLocationsController = StreamController.broadcast(); - Stream get favLocationsChanged => _favLocationsController.stream; - - void addFavLocation(String name) { - if (favLocations.contains(name)) return; - _favLocations.add(name); - writeStringIterable( - iterable: _favLocations, - filename: kFavLocationsFileName, - ).then((_) => _favLocationsController.add(true)); - } - - Future removeFavLocation(String name) async { - if (!favLocations.contains(name)) return; - _favLocations.remove(name); - return writeStringIterable( - iterable: _favLocations, - filename: kFavLocationsFileName, - ).then((_) => _favLocationsController.add(true)); - } - - Future init() async { - _apiKey = (await readSetting(kApiKey)) as String?; - _lastLocation = (await readAppState(kLastLocation)) as String?; - _favLocations = Set.from( - (await readStringIterable(filename: kFavLocationsFileName) ?? {}), - ); - } - - Future dispose() async { - await _favLocationsController.close(); - await _lastLocationController.close(); - } -} diff --git a/lib/utils.dart b/lib/utils.dart deleted file mode 100644 index 8fb5722..0000000 --- a/lib/utils.dart +++ /dev/null @@ -1,233 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:path_provider/path_provider.dart'; -import 'package:xdg_directories/xdg_directories.dart'; - -import 'constants.dart'; - -String formatTime(Duration duration) { - String twoDigits(int n) => n.toString().padLeft(2, '0'); - final hours = twoDigits(duration.inHours); - final minutes = twoDigits(duration.inMinutes.remainder(60)); - final seconds = twoDigits(duration.inSeconds.remainder(60)); - - return [if (duration.inHours > 0) hours, minutes, seconds].join(':'); -} - -String? _workingDir; -Future getWorkingDir() async { - if (_workingDir != null) return Future.value(_workingDir!); - if (Platform.isLinux) { - final workingDir = p.join(configHome.path, kAppName); - if (!Directory(workingDir).existsSync()) { - await Directory(workingDir).create(); - } - _workingDir = workingDir; - return workingDir; - } else if (Platform.isMacOS || Platform.isIOS) { - final libDirPath = (await getLibraryDirectory()).path; - final workingDirPath = p.join(libDirPath, kAppName); - if (!Directory(workingDirPath).existsSync()) { - await Directory(workingDirPath).create(); - } - _workingDir = workingDirPath; - return workingDirPath; - } else { - final docDirPath = (await getApplicationSupportDirectory()).path; - final workingDirPath = p.join(docDirPath, kAppName); - if (!Directory(workingDirPath).existsSync()) { - Directory(workingDirPath).createSync(); - } - _workingDir = workingDirPath; - return workingDirPath; - } -} - -Future getMusicDir() async { - if (Platform.isLinux) { - return getUserDirectory('MUSIC')?.path; - } - return null; -} - -Future getDownloadsDir() async { - String? path; - if (Platform.isLinux) { - path = getUserDirectory('DOWNLOAD')?.path; - } else if (Platform.isMacOS || Platform.isIOS || Platform.isWindows) { - path = (await getDownloadsDirectory())?.path; - } - if (path != null) { - return p.join(path, 'musicpod'); - } - return null; -} - -Future writeAppState(String key, dynamic value) async => - await writeSetting(key, value, kAppStateFileName); - -Future writeSetting( - String? key, - dynamic value, [ - String filename = kSettingsFileName, -]) async { - if (key == null || value == null) return; - final oldSettings = await getSettings(filename); - if (oldSettings.containsKey(key)) { - oldSettings.update(key, (v) => value); - } else { - oldSettings.putIfAbsent(key, () => value); - } - final jsonStr = jsonEncode(oldSettings); - - final workingDir = await getWorkingDir(); - - final file = File(p.join(workingDir, filename)); - - if (!file.existsSync()) { - file.create(); - } - - await file.writeAsString(jsonStr); -} - -Future readAppState(String key) => readSetting(key, kAppStateFileName); - -Future readSetting( - dynamic key, [ - String filename = kSettingsFileName, -]) async { - if (key == null) return null; - final oldSettings = await getSettings(filename); - return oldSettings[key]; -} - -Future> getSettings([ - String filename = kSettingsFileName, -]) async { - final workingDir = await getWorkingDir(); - - final file = File(p.join(workingDir, filename)); - - if (file.existsSync()) { - final jsonStr = await file.readAsString(); - - final map = jsonDecode(jsonStr) as Map; - - final m = map.map( - (key, value) => MapEntry( - key, - value, - ), - ); - - return m; - } else { - return {}; - } -} - -Future writeStringIterable({ - required Iterable iterable, - required String filename, -}) async { - final workingDir = await getWorkingDir(); - final file = File('$workingDir/$filename'); - if (!file.existsSync()) { - file.create(); - } - await file.writeAsString(iterable.join('\n')); -} - -Future?> readStringIterable({ - required String filename, -}) async { - final workingDir = await getWorkingDir(); - final file = File(p.join(workingDir, filename)); - - if (!file.existsSync()) return Future.value(null); - - final content = await file.readAsLines(); - - return content; -} - -Future writeJsonToFile(Map json, String fileName) async { - final jsonStr = jsonEncode(json); - - final workingDir = await getWorkingDir(); - - final file = File(p.join(workingDir, fileName)); - - if (!file.existsSync()) { - file.createSync(); - } - - await file.writeAsString(jsonStr); -} - -Future> readStringMap(String fileName) async { - final workingDir = await getWorkingDir(); - - try { - final file = File(p.join(workingDir, fileName)); - - if (file.existsSync()) { - final jsonStr = await file.readAsString(); - - final map = jsonDecode(jsonStr) as Map; - - final m = map.map( - (key, value) => MapEntry( - key, - value as String, - ), - ); - - return m; - } else { - return {}; - } - } on Exception catch (_) { - return {}; - } -} - -Future writeStringMap(Map map, String fileName) async { - final dynamicMap = map.map( - (key, value) => MapEntry( - key, - value as dynamic, - ), - ); - - final jsonStr = jsonEncode(dynamicMap); - - final workingDir = await getWorkingDir(); - - final file = File(p.join(workingDir, fileName)); - - if (!file.existsSync()) { - file.createSync(); - } - - await file.writeAsString(jsonStr); -} - -Duration? parseDuration(String? durationAsString) { - if (durationAsString == null || durationAsString == 'null') return null; - int hours = 0; - int minutes = 0; - int micros; - List parts = durationAsString.split(':'); - if (parts.length > 2) { - hours = int.parse(parts[parts.length - 3]); - } - if (parts.length > 1) { - minutes = int.parse(parts[parts.length - 2]); - } - micros = (double.parse(parts[parts.length - 1]) * 1000000).round(); - return Duration(hours: hours, minutes: minutes, microseconds: micros); -} diff --git a/lib/weather.dart b/lib/weather.dart index a175e35..620e91f 100644 --- a/lib/weather.dart +++ b/lib/weather.dart @@ -1 +1 @@ -export 'src/weather/view/weather_page.dart'; +export 'weather/view/weather_page.dart'; diff --git a/lib/src/weather/theme_x.dart b/lib/weather/theme_x.dart similarity index 86% rename from lib/src/weather/theme_x.dart rename to lib/weather/theme_x.dart index 8564a9f..043bdca 100644 --- a/lib/src/weather/theme_x.dart +++ b/lib/weather/theme_x.dart @@ -9,7 +9,7 @@ extension ThemeX on ThemeData { shadows: [ if (!light) Shadow( - color: Colors.black.withOpacity(light ? 1 : 0.8), + color: Colors.black.withValues(alpha: light ? 1 : 0.8), offset: const Offset(0, 0), blurRadius: light ? 2 : 3, ), diff --git a/lib/src/weather/view/city_search_field.dart b/lib/weather/view/city_search_field.dart similarity index 93% rename from lib/src/weather/view/city_search_field.dart rename to lib/weather/view/city_search_field.dart index 538b608..2e78f7a 100644 --- a/lib/src/weather/view/city_search_field.dart +++ b/lib/weather/view/city_search_field.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../../string_x.dart'; -import '../../build_context_x.dart'; +import '../../extensions/string_x.dart'; +import '../../extensions/build_context_x.dart'; import '../../l10n/l10n.dart'; import '../weather_model.dart'; @@ -56,7 +56,7 @@ class _CitySearchFieldState extends State { .bodyMedium ?.copyWith(fontWeight: FontWeight.w500), decoration: InputDecoration( - fillColor: theme.colorScheme.onSurface.withOpacity(0.2), + fillColor: theme.colorScheme.onSurface.withValues(alpha: 0.2), prefixIcon: Icon( YaruIcons.search, size: 15, @@ -83,7 +83,7 @@ class _CitySearchFieldState extends State { minWidth: 20, maxWidth: 20, ), - suffixIcon: (loading) + suffixIcon: loading ? Padding( padding: const EdgeInsets.only(right: 8), child: SizedBox.square( diff --git a/lib/src/weather/view/daily_bar_chart.dart b/lib/weather/view/daily_bar_chart.dart similarity index 96% rename from lib/src/weather/view/daily_bar_chart.dart rename to lib/weather/view/daily_bar_chart.dart index ef367b8..5283c10 100644 --- a/lib/src/weather/view/daily_bar_chart.dart +++ b/lib/weather/view/daily_bar_chart.dart @@ -7,8 +7,8 @@ import 'package:open_weather_client/models/weather_data.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../../constants.dart'; -import '../../build_context_x.dart'; +import '../../constants.dart'; +import '../../extensions/build_context_x.dart'; import '../weather_data_x.dart'; import '../weather_model.dart'; import 'error_view.dart'; @@ -28,7 +28,7 @@ class DailyBarChart extends StatelessWidget with WatchItMixin { margin: kPagePadding, decoration: BoxDecoration( borderRadius: BorderRadius.circular(kYaruContainerRadius), - color: context.theme.colorScheme.surface.withOpacity(0.3), + color: context.theme.colorScheme.surface.withValues(alpha: 0.3), ), width: context.mq.size.width, child: (error != null) @@ -74,7 +74,7 @@ class DailyBarChart extends StatelessWidget with WatchItMixin { reservedSize: 30, getTitlesWidget: (value, meta) { return SideTitleWidget( - axisSide: meta.axisSide, + meta: meta, child: Text( '${data[value.toInt()].temperature.tempMin.toInt()} °', style: TextStyle( @@ -97,7 +97,7 @@ class DailyBarChart extends StatelessWidget with WatchItMixin { reservedSize: 150, getTitlesWidget: (value, meta) { return SideTitleWidget( - axisSide: meta.axisSide, + meta: meta, child: Column( children: [ Flexible( diff --git a/lib/src/weather/view/error_view.dart b/lib/weather/view/error_view.dart similarity index 96% rename from lib/src/weather/view/error_view.dart rename to lib/weather/view/error_view.dart index ff55458..8c1e22a 100644 --- a/lib/src/weather/view/error_view.dart +++ b/lib/weather/view/error_view.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../../string_x.dart'; +import '../../extensions/string_x.dart'; import '../../app/offline_page.dart'; -import '../../build_context_x.dart'; +import '../../extensions/build_context_x.dart'; import '../../l10n/l10n.dart'; import '../weather_model.dart'; import 'city_search_field.dart'; @@ -108,7 +108,7 @@ class _ErrorViewState extends State { borderSide: BorderSide.none, ), fillColor: context.theme.colorScheme.surface - .withOpacity(0.3), + .withValues(alpha: 0.3), label: Text(context.l10n.openWeatherApiKey), ), ), diff --git a/lib/src/weather/view/hourly_line_chart.dart b/lib/weather/view/hourly_line_chart.dart similarity index 94% rename from lib/src/weather/view/hourly_line_chart.dart rename to lib/weather/view/hourly_line_chart.dart index 535262f..8870c05 100644 --- a/lib/src/weather/view/hourly_line_chart.dart +++ b/lib/weather/view/hourly_line_chart.dart @@ -5,8 +5,8 @@ import 'package:open_weather_client/models/weather_data.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../../constants.dart'; -import '../../build_context_x.dart'; +import '../../constants.dart'; +import '../../extensions/build_context_x.dart'; import '../../l10n/l10n.dart'; import '../weather_data_x.dart'; import '../weather_model.dart'; @@ -58,7 +58,7 @@ class _HourlyLineChartState extends State { height: mq.size.height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(kYaruContainerRadius), - color: context.theme.colorScheme.surface.withOpacity(0.3), + color: context.theme.colorScheme.surface.withValues(alpha: 0.3), ), child: error != null ? ErrorView(error: error) @@ -134,7 +134,7 @@ class _HourlyLineChartState extends State { final weekday = forecast[value.toInt()].getWeekDay(context); return SideTitleWidget( fitInside: SideTitleFitInsideData.fromTitleMeta(meta), - axisSide: meta.axisSide, + meta: meta, child: Column( children: [ Text( @@ -164,7 +164,8 @@ class _HourlyLineChartState extends State { required List forecast, required WeatherData data, }) { - final outlineColor = context.theme.colorScheme.onSurface.withOpacity(0.2); + final outlineColor = + context.theme.colorScheme.onSurface.withValues(alpha: 0.2); return LineChartData( gridData: FlGridData( @@ -219,7 +220,7 @@ class _HourlyLineChartState extends State { borderData: FlBorderData( show: false, border: Border.all( - color: context.theme.colorScheme.onSurface.withOpacity(0.2), + color: context.theme.colorScheme.onSurface.withValues(alpha: 0.2), ), ), minX: 0, @@ -253,7 +254,7 @@ class _HourlyLineChartState extends State { show: true, gradient: LinearGradient( colors: gradientColors - .map((color) => color.withOpacity(0.3)) + .map((color) => color.withValues(alpha: 0.3)) .toList(), ), ), diff --git a/lib/src/weather/view/now_tile.dart b/lib/weather/view/now_tile.dart similarity index 96% rename from lib/src/weather/view/now_tile.dart rename to lib/weather/view/now_tile.dart index 0228802..c7cfc13 100644 --- a/lib/src/weather/view/now_tile.dart +++ b/lib/weather/view/now_tile.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import 'package:open_weather_client/models/weather_data.dart'; import 'package:yaru/constants.dart'; -import '../../../constants.dart'; -import '../../../string_x.dart'; -import '../../build_context_x.dart'; +import '../../constants.dart'; +import '../../extensions/string_x.dart'; +import '../../extensions/build_context_x.dart'; import '../../l10n/l10n.dart'; import '../theme_x.dart'; import '../weather_data_x.dart'; diff --git a/lib/src/weather/view/weather_page.dart b/lib/weather/view/weather_page.dart similarity index 98% rename from lib/src/weather/view/weather_page.dart rename to lib/weather/view/weather_page.dart index fae8e09..1ffefbf 100644 --- a/lib/src/weather/view/weather_page.dart +++ b/lib/weather/view/weather_page.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:watch_it/watch_it.dart'; import 'package:yaru/yaru.dart'; -import '../../../constants.dart'; +import '../../constants.dart'; import '../../app/app_model.dart'; import '../../app/side_bar.dart'; import '../../l10n/l10n.dart'; diff --git a/lib/src/weather/weather_data_x.dart b/lib/weather/weather_data_x.dart similarity index 100% rename from lib/src/weather/weather_data_x.dart rename to lib/weather/weather_data_x.dart diff --git a/lib/src/weather/weather_model.dart b/lib/weather/weather_model.dart similarity index 91% rename from lib/src/weather/weather_model.dart rename to lib/weather/weather_model.dart index e5cfc99..b826684 100644 --- a/lib/src/weather/weather_model.dart +++ b/lib/weather/weather_model.dart @@ -7,6 +7,7 @@ import 'package:flutter_weather_bg_null_safety/utils/weather_type.dart'; import 'package:open_weather_client/models/temperature.dart'; import 'package:open_weather_client/open_weather.dart'; import 'package:safe_change_notifier/safe_change_notifier.dart'; +import 'package:watch_it/watch_it.dart'; import '../locations/locations_service.dart'; import 'weather_data_x.dart'; @@ -21,16 +22,15 @@ class WeatherModel extends SafeChangeNotifier { OpenWeather _openWeather; void setApiKeyAndLoadWeather(String apiKey) { - _locationsService.setApiKey(apiKey).then((_) { - _openWeather = OpenWeather(apiKey: apiKey); - loadWeather(); - }); + di + ..unregister() + ..registerSingleton(OpenWeather(apiKey: apiKey)); + _openWeather = di(); + loadWeather(); } final LocationsService _locationsService; - StreamSubscription? _apiKeyChangedSub; - StreamSubscription? _lastLocationChangedSub; - StreamSubscription? _favLocationsChangedSub; + StreamSubscription? _propertiesChangedSub; String? get lastLocation => _locationsService.lastLocation; Set get favLocations => _locationsService.favLocations; @@ -65,12 +65,8 @@ class WeatherModel extends SafeChangeNotifier { cityName ??= lastLocation ?? ''; - _apiKeyChangedSub = - _locationsService.apiKeyChanged.listen((_) => notifyListeners()); - _lastLocationChangedSub ??= - _locationsService.lastLocationChanged.listen((_) => notifyListeners()); - _favLocationsChangedSub ??= - _locationsService.favLocationsChanged.listen((_) => notifyListeners()); + _propertiesChangedSub = + _locationsService.propertiesChanged.listen((_) => notifyListeners()); _weatherData = await loadWeatherFromCityName(cityName); _locationsService.setLastLocation(cityName); @@ -90,9 +86,7 @@ class WeatherModel extends SafeChangeNotifier { @override Future dispose() async { super.dispose(); - await _apiKeyChangedSub?.cancel(); - await _lastLocationChangedSub?.cancel(); - await _favLocationsChangedSub?.cancel(); + await _propertiesChangedSub?.cancel(); } Future loadWeatherFromCityName(String cityName) async { diff --git a/lib/src/weather/weekday.dart b/lib/weather/weekday.dart similarity index 100% rename from lib/src/weather/weekday.dart rename to lib/weather/weekday.dart diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index a5cabf6..975557d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,22 +6,26 @@ #include "generated_plugin_registrant.h" +#include #include #include -#include +#include #include #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); + flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); g_autoptr(FlPluginRegistrar) gtk_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); gtk_plugin_register_with_registrar(gtk_registrar); g_autoptr(FlPluginRegistrar) handy_window_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "HandyWindowPlugin"); handy_window_plugin_register_with_registrar(handy_window_registrar); - g_autoptr(FlPluginRegistrar) screen_retriever_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin"); - screen_retriever_plugin_register_with_registrar(screen_retriever_registrar); + g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin"); + screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar); g_autoptr(FlPluginRegistrar) window_manager_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); window_manager_plugin_register_with_registrar(window_manager_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 002359f..676bef0 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,9 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + flutter_secure_storage_linux gtk handy_window - screen_retriever + screen_retriever_linux window_manager yaru_window_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 3e13b0f..2bcd62e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,16 @@ import FlutterMacOS import Foundation +import flutter_secure_storage_macos import path_provider_foundation -import screen_retriever +import screen_retriever_macos +import shared_preferences_foundation import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) + ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 2b6ad46..ff79938 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,26 +13,42 @@ packages: dependency: transitive description: name: animated_vector - sha256: e15c6596549ca6e2e7491c11fbe168a1dead87475a828a4bc81cf104feca0432 + sha256: f1beb10e6fcfd8bd15abb788e20345def786d1c7391d7c1426bb2a1f2adf2132 url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.2" animated_vector_annotations: dependency: transitive description: name: animated_vector_annotations - sha256: baa6b4ed98407220f2c9634f7da3cfa5eedb46798e090466f441e666e2f7c8c0 + sha256: "07c1ea603a2096f7eb6f1c2b8f16c3c330c680843ea78b7782a3217c3c53f979" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.2" archive: dependency: transitive description: name: archive - sha256: "0763b45fa9294197a2885c8567927e2830ade852e5c896fd4ab7e0e348d0f373" + sha256: "6199c74e3db4fbfbd04f66d739e72fe11c8a8957d5f219f1f4482dbde6420b5a" url: "https://pub.dev" source: hosted - version: "3.5.0" + version: "4.0.2" + args: + dependency: transitive + description: + name: args + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + url: "https://pub.dev" + source: hosted + version: "2.6.0" + assorted_layout_widgets: + dependency: transitive + description: + name: assorted_layout_widgets + sha256: "86eacbd25f7dd14a8182003935b07d94205ae4b0e6bedee03bde1404746bb7a9" + url: "https://pub.dev" + source: hosted + version: "10.7.0" async: dependency: transitive description: @@ -69,26 +85,34 @@ packages: dependency: "direct main" description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.0" crypto: dependency: transitive description: name: crypto - sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "0.7.11" equatable: dependency: transitive description: name: equatable - sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.0.7" fake_async: dependency: transitive description: @@ -101,18 +125,26 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" fl_chart: dependency: "direct main" description: name: fl_chart - sha256: "2b7c1f5d867da9a054661641c8f499c55c47c39acccb97b3bc673f5fa9a39e74" + sha256: "5276944c6ffc975ae796569a826c38a62d2abcf264e26b88fa6f482e107f4237" url: "https://pub.dev" source: hosted - version: "0.67.0" + version: "0.70.2" flutter: dependency: "direct main" description: flutter @@ -122,15 +154,63 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "5.0.0" flutter_localizations: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + url: "https://pub.dev" + source: hosted + version: "9.2.4" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: bf7404619d7ab5c0a1151d7c4e802edad8f33535abfbeff2f9e1fe1274e2d705 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + url: "https://pub.dev" + source: hosted + version: "3.1.2" flutter_test: dependency: "direct dev" description: flutter @@ -154,18 +234,26 @@ packages: dependency: transitive description: name: functional_listener - sha256: "026d1bd4f66367f11d9ec9f1f1ddb42b89e4484b356972c76d983266cf82f33f" + sha256: c096db771b4ce7ba0f886cc4a761044b11e8276a7bc24cfc812dc4b2bc6f5b16 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "4.1.0" get_it: dependency: transitive description: name: get_it - sha256: d85128a5dae4ea777324730dc65edd9c9f43155c109d5cc0a69cab74139fbac1 + sha256: f126a3e286b7f5b578bf436d5592968706c4c1de28a228b870ce375d9f743103 + url: "https://pub.dev" + source: hosted + version: "8.0.3" + gsettings: + dependency: transitive + description: + name: gsettings + sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c" url: "https://pub.dev" source: hosted - version: "7.7.0" + version: "0.2.8" gtk: dependency: transitive description: @@ -186,26 +274,26 @@ packages: dependency: transitive description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" image: dependency: transitive description: name: image - sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" + sha256: "8346ad4b5173924b5ddddab782fc7d8a6300178c8b1dc427775405a01701c4a6" url: "https://pub.dev" source: hosted - version: "4.1.7" + version: "4.5.2" intl: dependency: "direct main" description: @@ -214,6 +302,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" json_annotation: dependency: transitive description: @@ -226,42 +322,42 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.7" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.8" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "5.1.1" lottie: dependency: transitive description: name: lottie - sha256: ce2bb2605753915080e4ee47f036a64228c88dc7f56f7bc1dbe912d75b55b1e2 + sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.3.1" matcher: dependency: transitive description: @@ -274,26 +370,34 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + matrix4_transform: + dependency: transitive + description: + name: matrix4_transform + sha256: "1346e53517e3081d3e8362377be97e285e2bd348855c177eae2a18aa965cafa0" url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "4.0.1" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.15.0" open_weather_client: dependency: "direct main" description: name: open_weather_client - sha256: ce85b18d617a89f02857e3e512c148fd9857aa239c4fcdd3c412cd605bce1cc7 + sha256: "7c21cb574c27ea2ff327c353741eb02b18cdc8d18ffc2eb5482d92bcd5968304" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" path: dependency: "direct main" description: @@ -306,34 +410,34 @@ packages: dependency: transitive description: name: path_parsing - sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.1.0" path_provider: dependency: "direct main" description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d + sha256: "4adf4fd5423ec60a29506c76581bc05854c55e3a0b72d35bb28d661c9686edf2" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.2.15" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -354,10 +458,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" petitparser: dependency: transitive description: @@ -370,10 +474,18 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.6" + platform_linux: + dependency: transitive + description: + name: platform_linux + sha256: "856cfc9871e3ff3df6926991729d24bba9b70d0229ae377fa08b562344baaaa8" + url: "https://pub.dev" + source: hosted + version: "0.1.2" plugin_platform_interface: dependency: transitive description: @@ -382,27 +494,123 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + posix: + dependency: transitive + description: + name: posix + sha256: a0117dc2167805aa9125b82eee515cc891819bac2f538c83646d355b16f58b9a + url: "https://pub.dev" + source: hosted + version: "6.0.1" safe_change_notifier: dependency: "direct main" description: name: safe_change_notifier - sha256: "8d0645ec2706f580912c38de488439ddb491be48247826927b7bc2e54ea8f7af" + sha256: e7cce266bfede647355866fa3bd054feda57c220d2383f4203f28d4dcdb3b82e url: "https://pub.dev" source: hosted - version: "0.3.2" + version: "0.4.0" screen_retriever: dependency: transitive description: name: screen_retriever - sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" + sha256: "570dbc8e4f70bac451e0efc9c9bb19fa2d6799a11e6ef04f946d7886d2e23d0c" + url: "https://pub.dev" + source: hosted + version: "0.2.0" + screen_retriever_linux: + dependency: transitive + description: + name: screen_retriever_linux + sha256: f7f8120c92ef0784e58491ab664d01efda79a922b025ff286e29aa123ea3dd18 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + screen_retriever_macos: + dependency: transitive + description: + name: screen_retriever_macos + sha256: "71f956e65c97315dd661d71f828708bd97b6d358e776f1a30d5aa7d22d78a149" url: "https://pub.dev" source: hosted - version: "0.1.9" + version: "0.2.0" + screen_retriever_platform_interface: + dependency: transitive + description: + name: screen_retriever_platform_interface + sha256: ee197f4581ff0d5608587819af40490748e1e39e648d7680ecf95c05197240c0 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + screen_retriever_windows: + dependency: transitive + description: + name: screen_retriever_windows + sha256: "449ee257f03ca98a57288ee526a301a430a344a161f9202b4fcc38576716fe13" + url: "https://pub.dev" + source: hosted + version: "0.2.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "688ee90fbfb6989c980254a56cb26ebe9bb30a3a2dff439a78894211f73de67a" + url: "https://pub.dev" + source: hosted + version: "2.5.1" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "650584dcc0a39856f369782874e562efd002a9c94aec032412c9eb81419cce1f" + url: "https://pub.dev" + source: hosted + version: "2.4.4" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: @@ -415,10 +623,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" state_notifier: dependency: transitive description: @@ -439,10 +647,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" term_glyph: dependency: transitive description: @@ -455,10 +663,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.3" transparent_image: dependency: transitive description: @@ -471,10 +679,10 @@ packages: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" vector_math: dependency: transitive description: @@ -487,50 +695,50 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.3.0" watch_it: dependency: "direct main" description: name: watch_it - sha256: "9dc3f552d31f6ae121b0de794ab3cdea5d93627fe69337876ebe4b41bfc3729d" + sha256: "8ce7e442a65ef81db155dc505594f1856660fa5dd068471a1fe9c5eeaced9b93" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.6.2" web: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.0" win32: dependency: transitive description: name: win32 - sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb" + sha256: daf97c9d80197ed7b619040e86c8ab9a9dad285e7671ee7390f9180cc828a51e url: "https://pub.dev" source: hosted - version: "5.5.0" + version: "5.10.1" window_manager: dependency: transitive description: name: window_manager - sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494 + sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059" url: "https://pub.dev" source: hosted - version: "0.3.8" + version: "0.4.3" xdg_directories: dependency: "direct main" description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" xml: dependency: transitive description: @@ -543,50 +751,50 @@ packages: dependency: "direct main" description: name: yaru - sha256: e868965bcfbca568f54916e3f59a636a8a6ee39f2e102df8844061cd78a8d20e + sha256: f149399d81ecd3d20bfcc79afd5ddd9bcd7e4c901d5e602a8577fe59c71c8617 url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "7.0.0" yaru_window: dependency: transitive description: name: yaru_window - sha256: c9d16f78962652ad71aa160ab0a1e2e5924359439303394f980fd00eefc905eb + sha256: bc2a1df3c6f33477b47f84bf0a9325df411dbb7bd483ac88e5bc1c019d2f2560 url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" yaru_window_linux: dependency: transitive description: name: yaru_window_linux - sha256: "3676355492eba0461f03acf1b7420f7885982d1bffe113fccdca9415fbe39f5d" + sha256: "46a1a0743dfd45794cdaf8c5b3a48771ab73632b50a693f59c83b07988e96689" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" yaru_window_manager: dependency: transitive description: name: yaru_window_manager - sha256: "2d358263d19ae6598df21d6d8c0d25e75c79a82f459b63b0013a13e395c48b23" + sha256: b36c909fa082a7cb6e2f259d4357e16f08d3d8ab086685b81d1916e457100d1e url: "https://pub.dev" source: hosted - version: "0.1.2" + version: "0.1.2+1" yaru_window_platform_interface: dependency: transitive description: name: yaru_window_platform_interface - sha256: e9f8cd34e207d7f7b771ae70dee347ed974cee06b981819c4181b3e474e52254 + sha256: "93493d7e17a9e887ffa94c518bc5a4b3eb5425c009446e3294c689cb1a87b7e1" url: "https://pub.dev" source: hosted - version: "0.1.2" + version: "0.1.2+1" yaru_window_web: dependency: transitive description: name: yaru_window_web - sha256: "3ff30758a330d7626d54643df0cca6c179782f401aba7752da9cc0d60c9a6f74" + sha256: "31468aeb515f72d5eeddcd62773094a4f48fee96f7f0494f8ce53ad3b38054f1" url: "https://pub.dev" source: hosted - version: "0.0.3" + version: "0.0.3+1" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.19.5" + dart: ">=3.6.0 <4.0.0" + flutter: ">=3.27.4" diff --git a/pubspec.yaml b/pubspec.yaml index 7ed2d39..22ab91e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,17 +7,18 @@ version: 1.0.0+1 environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.19.5" + flutter: ">=3.27.4" dependencies: animated_emoji: ^3.1.0 - collection: ^1.16.0 - fl_chart: ^0.67.0 + collection: ^1.19.0 + fl_chart: ^0.70.2 flutter: sdk: flutter flutter_localizations: sdk: flutter + flutter_secure_storage: ^9.2.4 flutter_weather_bg_null_safety: git: url: https://github.com/Feichtmeier/flutter_weather_bg_null_safety @@ -25,16 +26,17 @@ dependencies: handy_window: ^0.4.0 intl: ^0.19.0 - open_weather_client: ^2.3.2 + open_weather_client: ^2.4.1 path: ^1.9.0 - path_provider: ^2.1.3 - safe_change_notifier: ^0.3.0 - watch_it: ^1.4.1 + path_provider: ^2.1.5 + safe_change_notifier: ^0.4.0 + shared_preferences: ^2.5.1 + watch_it: ^1.6.2 xdg_directories: ^1.0.4 - yaru: ^4.1.0 + yaru: ^7.0.0 dev_dependencies: - flutter_lints: ^3.0.1 + flutter_lints: ^5.0.0 flutter_test: sdk: flutter diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 6e1e23f..9fb149a 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -21,7 +21,7 @@ architectures: parts: flutter-git: source: https://github.com/flutter/flutter.git - source-tag: 3.19.5 + source-tag: 3.27.4 plugin: nil override-build: | mkdir -p $CRAFT_PART_INSTALL/usr/bin @@ -45,10 +45,10 @@ parts: after: [flutter-git] override-build: | - set -eux + set -eu flutter doctor flutter pub get - flutter build linux --release -v + flutter build linux --release -v --dart-define=API_KEY="$API_KEY" mkdir -p $CRAFT_PART_INSTALL/bin/ cp -r build/linux/*/release/bundle/* $CRAFT_PART_INSTALL/bin/