Add search cards

This commit is contained in:
Yoshi 2024-07-07 14:49:45 +03:00
parent 0d565752d5
commit aa125fcdc1
8 changed files with 271 additions and 168 deletions

View file

@ -472,7 +472,7 @@ class WeatherController extends GetxController {
return imagePath; return imagePath;
} }
void notlification(MainWeatherCache mainWeatherCache) async { void notification(MainWeatherCache mainWeatherCache) async {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
int startHour = timeConvert(timeStart).hour; int startHour = timeConvert(timeStart).hour;
int endHour = timeConvert(timeEnd).hour; int endHour = timeConvert(timeEnd).hour;
@ -483,20 +483,20 @@ class WeatherController extends GetxController {
if (notificationTime.isAfter(now) && if (notificationTime.isAfter(now) &&
notificationTime.hour >= startHour && notificationTime.hour >= startHour &&
notificationTime.hour <= endHour) { notificationTime.hour <= endHour) {
for (var j = 0; j < mainWeatherCache.timeDaily!.length; j++) { for (var j = 0; j < mainWeatherCache.timeDaily!.length; j++) {
if (mainWeatherCache.timeDaily![j].day == notificationTime.day) { if (mainWeatherCache.timeDaily![j].day == notificationTime.day) {
NotificationShow().showNotification( NotificationShow().showNotification(
UniqueKey().hashCode, UniqueKey().hashCode,
'$city: ${mainWeatherCache.temperature2M![i]}°', '$city: ${mainWeatherCache.temperature2M![i]}°',
'${StatusWeather().getText(mainWeatherCache.weathercode![i])} · ${StatusData().getTimeFormat(mainWeatherCache.time![i])}', '${StatusWeather().getText(mainWeatherCache.weathercode![i])} · ${StatusData().getTimeFormat(mainWeatherCache.time![i])}',
notificationTime, notificationTime,
StatusWeather().getImageNotification( StatusWeather().getImageNotification(
mainWeatherCache.weathercode![i], mainWeatherCache.weathercode![i],
mainWeatherCache.time![i], mainWeatherCache.time![i],
mainWeatherCache.sunrise![j], mainWeatherCache.sunrise![j],
mainWeatherCache.sunset![j], mainWeatherCache.sunset![j],
), ),
); );
} }
} }
} }
@ -508,7 +508,7 @@ class WeatherController extends GetxController {
final List<PendingNotificationRequest> pendingNotificationRequests = final List<PendingNotificationRequest> pendingNotificationRequests =
await flutterLocalNotificationsPlugin.pendingNotificationRequests(); await flutterLocalNotificationsPlugin.pendingNotificationRequests();
if (pendingNotificationRequests.isEmpty) { if (pendingNotificationRequests.isEmpty) {
notlification(_mainWeather.value); notification(_mainWeather.value);
} }
} }
} }

View file

@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:iconsax/iconsax.dart'; import 'package:iconsax/iconsax.dart';
import 'package:rain/app/controller/controller.dart'; import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/modules/cards/view/info_weather_card.dart'; import 'package:rain/app/modules/cards/widgets/weather_card_list.dart';
import 'package:rain/app/modules/cards/widgets/weather_card_container.dart'; import 'package:rain/app/widgets/text_form.dart';
class ListWeatherCard extends StatefulWidget { class ListWeatherCard extends StatefulWidget {
const ListWeatherCard({super.key}); const ListWeatherCard({super.key});
@ -14,6 +14,19 @@ class ListWeatherCard extends StatefulWidget {
class _ListWeatherCardState extends State<ListWeatherCard> { class _ListWeatherCardState extends State<ListWeatherCard> {
final weatherController = Get.put(WeatherController()); final weatherController = Get.put(WeatherController());
TextEditingController searchTasks = TextEditingController();
String filter = '';
applyFilter(String value) async {
filter = value.toLowerCase();
setState(() {});
}
@override
void initState() {
super.initState();
applyFilter('');
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -49,87 +62,40 @@ class _ListWeatherCardState extends State<ListWeatherCard> {
), ),
), ),
) )
: ReorderableListView( : NestedScrollView(
onReorder: (oldIndex, newIndex) => physics: const NeverScrollableScrollPhysics(),
weatherController.reorder(oldIndex, newIndex), headerSliverBuilder: (context, innerBoxIsScrolled) {
children: [ return [
...weatherController.weatherCards.map( SliverToBoxAdapter(
(weatherCardList) => Dismissible( child: MyTextForm(
key: ValueKey(weatherCardList), labelText: 'search'.tr,
direction: DismissDirection.endToStart, type: TextInputType.text,
background: Container( icon: const Icon(
alignment: Alignment.centerRight, Iconsax.search_normal_1,
child: const Padding( size: 20,
padding: EdgeInsets.only(right: 15),
child: Icon(
Iconsax.trush_square,
color: Colors.red,
),
), ),
), controller: searchTasks,
confirmDismiss: (DismissDirection direction) async { margin: const EdgeInsets.symmetric(
return await showAdaptiveDialog( horizontal: 10, vertical: 5),
context: context, onChanged: applyFilter,
builder: (BuildContext context) { iconButton: searchTasks.text.isNotEmpty
return AlertDialog.adaptive( ? IconButton(
title: Text( onPressed: () {
'deletedCardWeather'.tr, searchTasks.clear();
style: textTheme.titleLarge, applyFilter('');
), },
content: Text( icon: const Icon(
'deletedCardWeatherQuery'.tr, Iconsax.close_circle,
style: titleMedium, color: Colors.grey,
), size: 20,
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text(
'cancel'.tr,
style: titleMedium?.copyWith(
color: Colors.blueAccent,
),
),
), ),
TextButton( )
onPressed: () => Get.back(result: true), : null,
child: Text(
'delete'.tr,
style: titleMedium?.copyWith(
color: Colors.red,
),
),
),
],
);
},
);
},
onDismissed: (DismissDirection direction) async {
await weatherController
.deleteCardWeather(weatherCardList);
},
child: GestureDetector(
onTap: () => Get.to(
() => InfoWeatherCard(
weatherCard: weatherCardList,
),
transition: Transition.downToUp,
),
child: WeatherCardContainer(
time: weatherCardList.time!,
timeDaily: weatherCardList.timeDaily!,
timeDay: weatherCardList.sunrise!,
timeNight: weatherCardList.sunset!,
weather: weatherCardList.weathercode!,
degree: weatherCardList.temperature2M!,
district: weatherCardList.district!,
city: weatherCardList.city!,
timezone: weatherCardList.timezone!,
),
), ),
), ),
), ];
], },
body: WeatherCardList(searchCity: filter),
), ),
), ),
); );

View file

@ -0,0 +1,115 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax/iconsax.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/modules/cards/view/info_weather_card.dart';
import 'package:rain/app/modules/cards/widgets/weather_card_container.dart';
class WeatherCardList extends StatefulWidget {
const WeatherCardList({
super.key,
required this.searchCity,
});
final String searchCity;
@override
State<WeatherCardList> createState() => _WeatherCardListState();
}
class _WeatherCardListState extends State<WeatherCardList> {
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleMedium = textTheme.titleMedium;
var weatherCards = weatherController.weatherCards
.where((weatherCard) => (widget.searchCity.isEmpty ||
weatherCard.city!.toLowerCase().contains(widget.searchCity)))
.toList()
.obs;
return ReorderableListView(
onReorder: (oldIndex, newIndex) =>
weatherController.reorder(oldIndex, newIndex),
children: [
...weatherCards.map(
(weatherCardList) => Dismissible(
key: ValueKey(weatherCardList),
direction: DismissDirection.endToStart,
background: Container(
alignment: Alignment.centerRight,
child: const Padding(
padding: EdgeInsets.only(right: 15),
child: Icon(
Iconsax.trush_square,
color: Colors.red,
),
),
),
confirmDismiss: (DismissDirection direction) async {
return await showAdaptiveDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog.adaptive(
title: Text(
'deletedCardWeather'.tr,
style: textTheme.titleLarge,
),
content: Text(
'deletedCardWeatherQuery'.tr,
style: titleMedium,
),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text(
'cancel'.tr,
style: titleMedium?.copyWith(
color: Colors.blueAccent,
),
),
),
TextButton(
onPressed: () => Get.back(result: true),
child: Text(
'delete'.tr,
style: titleMedium?.copyWith(
color: Colors.red,
),
),
),
],
);
},
);
},
onDismissed: (DismissDirection direction) async {
await weatherController.deleteCardWeather(weatherCardList);
},
child: GestureDetector(
onTap: () => Get.to(
() => InfoWeatherCard(
weatherCard: weatherCardList,
),
transition: Transition.downToUp,
),
child: WeatherCardContainer(
time: weatherCardList.time!,
timeDaily: weatherCardList.timeDaily!,
timeDay: weatherCardList.sunrise!,
timeNight: weatherCardList.sunset!,
weather: weatherCardList.weathercode!,
degree: weatherCardList.temperature2M!,
district: weatherCardList.district!,
city: weatherCardList.city!,
timezone: weatherCardList.timezone!,
),
),
),
),
],
);
}
}

View file

@ -266,7 +266,7 @@ class _SettingsPageState extends State<SettingsPage> {
isar.settings.putSync(settings); isar.settings.putSync(settings);
}); });
if (value) { if (value) {
weatherController.notlification( weatherController.notification(
weatherController.mainWeather); weatherController.mainWeather);
} else { } else {
flutterLocalNotificationsPlugin.cancelAll(); flutterLocalNotificationsPlugin.cancelAll();
@ -297,7 +297,7 @@ class _SettingsPageState extends State<SettingsPage> {
newTimeRange: int.parse(newValue!)); newTimeRange: int.parse(newValue!));
if (settings.notifications) { if (settings.notifications) {
flutterLocalNotificationsPlugin.cancelAll(); flutterLocalNotificationsPlugin.cancelAll();
weatherController.notlification( weatherController.notification(
weatherController.mainWeather); weatherController.mainWeather);
} }
}, },
@ -352,7 +352,7 @@ class _SettingsPageState extends State<SettingsPage> {
timeStartPicker.format(context)); timeStartPicker.format(context));
if (settings.notifications) { if (settings.notifications) {
flutterLocalNotificationsPlugin.cancelAll(); flutterLocalNotificationsPlugin.cancelAll();
weatherController.notlification( weatherController.notification(
weatherController.mainWeather); weatherController.mainWeather);
} }
} }
@ -408,7 +408,7 @@ class _SettingsPageState extends State<SettingsPage> {
timeEndPicker.format(context)); timeEndPicker.format(context));
if (settings.notifications) { if (settings.notifications) {
flutterLocalNotificationsPlugin.cancelAll(); flutterLocalNotificationsPlugin.cancelAll();
weatherController.notlification( weatherController.notification(
weatherController.mainWeather); weatherController.mainWeather);
} }
} }

View file

@ -13,6 +13,7 @@ class MyTextForm extends StatelessWidget {
this.validator, this.validator,
this.elevation, this.elevation,
this.focusNode, this.focusNode,
this.onChanged,
}); });
final String labelText; final String labelText;
final TextInputType type; final TextInputType type;
@ -23,6 +24,7 @@ class MyTextForm extends StatelessWidget {
final String? Function(String?)? validator; final String? Function(String?)? validator;
final double? elevation; final double? elevation;
final FocusNode? focusNode; final FocusNode? focusNode;
final Function(String)? onChanged;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -44,6 +46,7 @@ class MyTextForm extends StatelessWidget {
labelText: labelText, labelText: labelText,
), ),
validator: validator, validator: validator,
onChanged: onChanged,
), ),
); );
} }

View file

@ -284,54 +284,57 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DynamicColorBuilder( return GestureDetector(
builder: (lightColorScheme, darkColorScheme) { onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
final lightMaterialTheme = child: DynamicColorBuilder(
lightTheme(lightColorScheme?.surface, lightColorScheme); builder: (lightColorScheme, darkColorScheme) {
final darkMaterialTheme = final lightMaterialTheme =
darkTheme(darkColorScheme?.surface, darkColorScheme); lightTheme(lightColorScheme?.surface, lightColorScheme);
final darkMaterialThemeOled = darkTheme(oledColor, darkColorScheme); final darkMaterialTheme =
darkTheme(darkColorScheme?.surface, darkColorScheme);
final darkMaterialThemeOled = darkTheme(oledColor, darkColorScheme);
return GetMaterialApp( return GetMaterialApp(
themeMode: themeController.theme, themeMode: themeController.theme,
theme: materialColor theme: materialColor
? lightColorScheme != null ? lightColorScheme != null
? lightMaterialTheme ? lightMaterialTheme
: lightTheme(lightColor, colorSchemeLight) : lightTheme(lightColor, colorSchemeLight)
: lightTheme(lightColor, colorSchemeLight), : lightTheme(lightColor, colorSchemeLight),
darkTheme: amoledTheme darkTheme: amoledTheme
? materialColor ? materialColor
? darkColorScheme != null ? darkColorScheme != null
? darkMaterialThemeOled ? darkMaterialThemeOled
: darkTheme(oledColor, colorSchemeDark) : darkTheme(oledColor, colorSchemeDark)
: darkTheme(oledColor, colorSchemeDark) : darkTheme(oledColor, colorSchemeDark)
: materialColor : materialColor
? darkColorScheme != null ? darkColorScheme != null
? darkMaterialTheme ? darkMaterialTheme
: darkTheme(darkColor, colorSchemeDark) : darkTheme(darkColor, colorSchemeDark)
: darkTheme(darkColor, colorSchemeDark), : darkTheme(darkColor, colorSchemeDark),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
], ],
translations: Translation(), translations: Translation(),
locale: locale, locale: locale,
fallbackLocale: const Locale('en', 'US'), fallbackLocale: const Locale('en', 'US'),
supportedLocales: supportedLocales:
appLanguages.map((e) => e['locale'] as Locale).toList(), appLanguages.map((e) => e['locale'] as Locale).toList(),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: settings.onboard home: settings.onboard
? (locationCache.city == null) || ? (locationCache.city == null) ||
(locationCache.district == null) || (locationCache.district == null) ||
(locationCache.lat == null) || (locationCache.lat == null) ||
(locationCache.lon == null) (locationCache.lon == null)
? const SelectGeolocation(isStart: true) ? const SelectGeolocation(isStart: true)
: const HomePage() : const HomePage()
: const OnBording(), : const OnBording(),
title: 'Rain', title: 'Rain',
); );
}, },
),
); );
} }
} }

View file

@ -237,10 +237,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: dio name: dio
sha256: "11e40df547d418cc0c4900a9318b26304e665da6fa4755399a9ff9efd09034b5" sha256: e17f6b3097b8c51b72c74c9f071a605c47bcc8893839bd66732457a5ebe73714
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.4.3+1" version: "5.5.0+1"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "36c5b2d79eb17cdae41e974b7a8284fec631651d2a6f39a8a2ff22327e90aeac"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
dynamic_color: dynamic_color:
dependency: "direct main" dependency: "direct main"
description: description:
@ -322,10 +330,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_local_notifications name: flutter_local_notifications
sha256: "40e6fbd2da7dcc7ed78432c5cdab1559674b4af035fddbfb2f9a8f9c2112fcef" sha256: "0a9068149f0225e81642b03562e99776106edbd967816ee68bc16310d457c60e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "17.1.2" version: "17.2.1+1"
flutter_local_notifications_linux: flutter_local_notifications_linux:
dependency: transitive dependency: transitive
description: description:
@ -338,10 +346,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_local_notifications_platform_interface name: flutter_local_notifications_platform_interface
sha256: "340abf67df238f7f0ef58f4a26d2a83e1ab74c77ab03cd2b2d5018ac64db30b7" sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.1.0" version: "7.2.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -364,10 +372,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_timezone name: flutter_timezone
sha256: "06b35132c98fa188db3c4b654b7e1af7ccd01dfe12a004d58be423357605fb24" sha256: b7448ff8a9e1350606727e40b3f314aa798a6a1cc07127eba58f09b98a66f03f
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.8" version: "2.0.0"
flutter_web_plugins: flutter_web_plugins:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -385,10 +393,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: freezed_annotation name: freezed_annotation
sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d sha256: f54946fdb1fa7b01f780841937b1a80783a20b393485f3f6cdf336fd6f4705f2
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.2"
frontend_server_client: frontend_server_client:
dependency: transitive dependency: transitive
description: description:
@ -569,10 +577,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: internet_connection_checker_plus name: internet_connection_checker_plus
sha256: "45d33532937eb931a14fb1f885c4b0ade6332983ba98349920fca0a23751d7c9" sha256: "116a5473ef8b3eadc4f07257d2719885aec1626c54fb043c47e3deda659dbabb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.2" version: "2.5.0"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
@ -617,10 +625,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: js name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.1" version: "0.6.7"
js_interop:
dependency: transitive
description:
name: js_interop
sha256: "7ec859c296958ccea34dc770504bd3ff4ae52fdd9e7eeb2bacc7081ad476a1f5"
url: "https://pub.dev"
source: hosted
version: "0.0.1"
json_annotation: json_annotation:
dependency: "direct main" dependency: "direct main"
description: description:
@ -990,10 +1006,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: timezone name: timezone
sha256: a6ccda4a69a442098b602c44e61a1e2b4bf6f5516e875bbf0f427d5df14745d5 sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.9.3" version: "0.9.4"
timing: timing:
dependency: transitive dependency: transitive
description: description:

View file

@ -14,14 +14,14 @@ dependencies:
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
get: ^4.6.6 get: ^4.6.6
dio: ^5.4.3+1 dio: ^5.5.0+1
intl: ^0.19.0 intl: ^0.19.0
isar: isar:
version: ^3.1.7 version: ^3.1.7
hosted: https://pub.isar-community.dev/ hosted: https://pub.isar-community.dev/
shimmer: ^3.0.0 shimmer: ^3.0.0
iconsax: ^0.0.8 iconsax: ^0.0.8
timezone: ^0.9.3 timezone: ^0.9.4
geocoding: ^3.0.0 geocoding: ^3.0.0
geolocator: ^12.0.0 geolocator: ^12.0.0
home_widget: ^0.6.0 home_widget: ^0.6.0
@ -32,10 +32,10 @@ dependencies:
dynamic_color: ^1.7.0 dynamic_color: ^1.7.0
path_provider: ^2.1.3 path_provider: ^2.1.3
json_annotation: ^4.9.0 json_annotation: ^4.9.0
flutter_timezone: ^1.0.8 flutter_timezone: ^2.0.0
package_info_plus: ^8.0.0 package_info_plus: ^8.0.0
connectivity_plus: ^6.0.3 connectivity_plus: ^6.0.3
freezed_annotation: ^2.4.1 freezed_annotation: ^2.4.2
isar_flutter_libs: isar_flutter_libs:
version: ^3.1.7 version: ^3.1.7
hosted: https://pub.isar-community.dev/ hosted: https://pub.isar-community.dev/
@ -43,8 +43,8 @@ dependencies:
lat_lng_to_timezone: ^0.2.0 lat_lng_to_timezone: ^0.2.0
flutter_hsvcolor_picker: ^1.5.1 flutter_hsvcolor_picker: ^1.5.1
scrollable_positioned_list: ^0.3.8 scrollable_positioned_list: ^0.3.8
flutter_local_notifications: ^17.1.2 flutter_local_notifications: ^17.2.1+1
internet_connection_checker_plus: ^2.4.2 internet_connection_checker_plus: ^2.5.0
# Uncomment this for publishing FLOSS variant # Uncomment this for publishing FLOSS variant
# dependency_overrides: # dependency_overrides: