Rain/lib/app/modules/cards/widgets/create_card_weather.dart

294 lines
12 KiB
Dart
Raw Normal View History

2023-06-17 20:57:57 +03:00
import 'package:flutter/material.dart';
import 'package:get/get.dart';
2024-08-12 21:03:35 +03:00
import 'package:iconsax_plus/iconsax_plus.dart';
2023-06-17 20:57:57 +03:00
import 'package:rain/app/api/api.dart';
2024-08-02 22:52:33 +03:00
import 'package:rain/app/api/city_api.dart';
2023-06-17 20:57:57 +03:00
import 'package:rain/app/controller/controller.dart';
2024-07-24 23:07:35 +03:00
import 'package:rain/app/widgets/button.dart';
2023-06-17 20:57:57 +03:00
import 'package:rain/app/widgets/text_form.dart';
2023-08-03 20:52:20 +03:00
import 'package:rain/main.dart';
2023-06-17 20:57:57 +03:00
class CreateWeatherCard extends StatefulWidget {
const CreateWeatherCard({super.key});
@override
State<CreateWeatherCard> createState() => _CreateWeatherCardState();
}
class _CreateWeatherCardState extends State<CreateWeatherCard>
with SingleTickerProviderStateMixin {
2023-06-17 20:57:57 +03:00
bool isLoading = false;
final formKey = GlobalKey<FormState>();
2023-08-03 20:52:20 +03:00
final _focusNode = FocusNode();
2023-09-01 20:18:40 +03:00
final weatherController = Get.put(WeatherController());
2023-08-03 20:52:20 +03:00
final _controller = TextEditingController();
final _controllerLat = TextEditingController();
final _controllerLon = TextEditingController();
final _controllerCity = TextEditingController();
final _controllerDistrict = TextEditingController();
2023-06-17 20:57:57 +03:00
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_animation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_animationController.dispose();
_controller.dispose();
_controllerLat.dispose();
_controllerLon.dispose();
_controllerCity.dispose();
_controllerDistrict.dispose();
super.dispose();
}
void textTrim(TextEditingController value) {
2023-06-17 20:57:57 +03:00
value.text = value.text.trim();
2023-09-24 18:52:15 +03:00
while (value.text.contains(' ')) {
value.text = value.text.replaceAll(' ', ' ');
2023-06-17 20:57:57 +03:00
}
}
void fillController(Result selection) {
2023-06-17 20:57:57 +03:00
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
@override
Widget build(BuildContext context) {
const kTextFieldElevation = 4.0;
bool showButton = _controllerLon.text.isNotEmpty &&
_controllerLat.text.isNotEmpty &&
_controllerCity.text.isNotEmpty &&
_controllerDistrict.text.isNotEmpty;
if (showButton) {
_animationController.forward();
} else {
_animationController.reverse();
}
2024-07-09 23:03:40 +03:00
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Form(
key: formKey,
child: SingleChildScrollView(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 14, bottom: 7),
2024-07-24 23:07:35 +03:00
child: Text(
'create'.tr,
style: context.textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.bold),
2024-07-24 23:07:35 +03:00
textAlign: TextAlign.center,
2024-07-09 23:03:40 +03:00
),
2023-06-17 20:57:57 +03:00
),
2024-07-09 23:03:40 +03:00
RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return MyTextForm(
elevation: kTextFieldElevation,
labelText: 'search'.tr,
type: TextInputType.text,
2024-08-12 21:03:35 +03:00
icon: const Icon(IconsaxPlusLinear.global_search),
2024-07-09 23:03:40 +03:00
controller: _controller,
2024-07-24 23:07:35 +03:00
margin: const EdgeInsets.only(
left: 10, right: 10, top: 10),
2024-07-09 23:03:40 +03:00
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getCity(textEditingValue.text, locale);
},
2024-07-24 23:07:35 +03:00
onSelected: (Result selection) =>
fillController(selection),
2024-07-09 23:03:40 +03:00
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
2024-07-24 23:07:35 +03:00
final Result option =
options.elementAt(index);
2024-07-09 23:03:40 +03:00
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
2023-07-10 21:33:43 +03:00
),
2024-07-09 23:03:40 +03:00
);
},
),
2023-07-10 21:33:43 +03:00
),
),
2024-07-09 23:03:40 +03:00
);
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
2024-08-12 21:03:35 +03:00
icon: const Icon(IconsaxPlusLinear.location),
2024-07-24 23:07:35 +03:00
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
2024-07-09 23:03:40 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 || numericValue > 90) {
return 'validate90'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
2024-08-12 21:03:35 +03:00
icon: const Icon(IconsaxPlusLinear.location),
2024-07-24 23:07:35 +03:00
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
2024-07-09 23:03:40 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 || numericValue > 180) {
return 'validate180'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
2024-08-12 21:03:35 +03:00
icon: const Icon(IconsaxPlusLinear.building_3),
2024-07-24 23:07:35 +03:00
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
2024-07-09 23:03:40 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
2024-08-12 21:03:35 +03:00
icon: const Icon(IconsaxPlusLinear.global),
2024-07-24 23:07:35 +03:00
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
2024-07-09 23:03:40 +03:00
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
2024-07-24 23:07:35 +03:00
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
child: SizeTransition(
sizeFactor: _animation,
axisAlignment: -1.0,
2024-07-24 23:07:35 +03:00
child: MyTextButton(
buttonName: 'done'.tr,
onPressed: () async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await weatherController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
},
),
),
),
2024-07-09 23:03:40 +03:00
],
),
2023-06-17 20:57:57 +03:00
),
2024-07-09 23:03:40 +03:00
if (isLoading)
const Center(
child: CircularProgressIndicator(),
),
],
),
2023-06-17 20:57:57 +03:00
),
),
);
}
}