Created
June 15, 2021 06:08
-
-
Save locskot/aeef46b1357bd896250e701a772b495d to your computer and use it in GitHub Desktop.
example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:components/api/graphql_api.dart'; | |
import 'package:components/base/base_circular_loading.dart'; | |
import 'package:components/base/show_bottom_sheet.dart'; | |
import 'package:components/events/event_sender.dart'; | |
import 'package:components/rect/field/const.dart'; | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; | |
import 'package:provider/provider.dart'; | |
import '../../../app/utils/view_model_provider.dart'; | |
import '../../../main.dart'; | |
import '../model/pharmacy.dart'; | |
import '../viewmodel/pharmacy_viewmodel.dart'; | |
import 'new_search.dart'; | |
const String labelText = 'Preferred pharmacy'; | |
abstract class PharmacyViewBase extends StatefulWidget { | |
final Function(Pharmacy) onChanged; | |
final Function() onExit; | |
final Pharmacy pharmacy; | |
const PharmacyViewBase({ | |
@required this.onChanged, | |
@required this.onExit, | |
this.pharmacy, | |
}); | |
} | |
abstract class PharmacyViewBaseState extends State<PharmacyViewBase> { | |
void onTap(); | |
final graphqlAPI = locator<GraphqlAPI>(); | |
final eventSender = locator<EventSender>(); | |
TextEditingController searchController; | |
PharmacyViewModel pharmacyViewModel; | |
@override | |
void initState() { | |
super.initState(); | |
pharmacyViewModel = ViewModelProvider.getOrCreate( | |
key: pharmacyKey, | |
create: () => PharmacyViewModel.create( | |
graphqlAPI, | |
eventSender, | |
), | |
); | |
pharmacyViewModel.startUIListening((event) async { | |
switch (event) { | |
case PharmacyViewEvent.onSelected: | |
widget.onExit.call(); | |
break; | |
} | |
}); | |
pharmacyViewModel.pharmacyIsPressed = false; | |
pharmacyViewModel.pressedPharmacy = widget.pharmacy; | |
pharmacyViewModel.loadPharmacy(); | |
} | |
@override | |
void dispose() { | |
pharmacyViewModel.stopUIListening(); | |
searchController?.clear(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return ChangeNotifierProvider.value( | |
value: pharmacyViewModel, | |
child: Consumer<PharmacyViewModel>( | |
builder: (context, _, __) { | |
return InkWell( | |
child: Container(), | |
onTap: onTap, | |
); | |
}, | |
), | |
); | |
} | |
Widget buildContent() { | |
if (pharmacyViewModel.loading && pharmacyViewModel.items.isEmpty) { | |
return Container( | |
alignment: Alignment.center, | |
margin: const EdgeInsets.only(top: 32), | |
child: BaseCircularLoading(), | |
); | |
} | |
if (searchController == null) { | |
searchController = TextEditingController()..text = pharmacyViewModel.search ?? ''; | |
} | |
return Column( | |
children: [ | |
Container( | |
margin: const EdgeInsets.only(top: 12, left: 8, right: 8, bottom: 6), | |
child: NewSearchCard( | |
hintText: 'Search pharmacy', | |
onChanged: pharmacyViewModel.onSearch, | |
), | |
), | |
if (pharmacyViewModel.searchResult.isEmpty) | |
Container( | |
alignment: Alignment.center, | |
margin: const EdgeInsets.only(top: 32), | |
child: Text('Nothing found'), | |
) | |
else | |
Expanded( | |
child: Scrollbar( | |
child: Scaffold( | |
body: ListView.builder( | |
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, | |
itemCount: pharmacyViewModel.searchResult.length, | |
itemBuilder: (context, index) { | |
final pharmacy = pharmacyViewModel.searchResult[index]; | |
final selected = pharmacy == pharmacyViewModel.pressedPharmacy; | |
return Material( | |
color: Colors.transparent, | |
child: Container( | |
child: ListTile( | |
dense: true, | |
onTap: () { | |
pharmacyViewModel.onSelected(pharmacy); | |
widget.onChanged(pharmacy); | |
}, | |
title: Text( | |
pharmacy.name, | |
style: const TextStyle( | |
color: Colors.black, | |
fontSize: 16, | |
), | |
), | |
subtitle: Text( | |
pharmacy.address, | |
style: const TextStyle( | |
color: Colors.black, | |
fontSize: 14, | |
), | |
), | |
trailing: Icon( | |
Icons.check_circle_outline_rounded, | |
color: selected ? AppColors.themeFirstColor : Colors.white, | |
), | |
), | |
), | |
); | |
}, | |
), | |
floatingActionButton: KeyboardVisibilityProvider( | |
child: Builder( | |
builder: (context) { | |
final isKeyboardVisible = KeyboardVisibilityProvider.isKeyboardVisible(context); | |
if (isKeyboardVisible) { | |
return Container(); | |
} else { | |
return FloatingActionButton( | |
mini: true, | |
backgroundColor: Colors.white, | |
child: Icon( | |
Icons.exit_to_app_rounded, | |
color: AppColors.themeFirstColor, | |
), | |
onPressed: () { | |
Navigator.pop(context); | |
}, | |
); | |
} | |
}, | |
), | |
), | |
), | |
), | |
), | |
], | |
); | |
} | |
} | |
class PharmacyBottomSheet extends PharmacyViewBase { | |
final Function(Pharmacy) onChanged; | |
final Function() onExit; | |
final Pharmacy pharmacy; | |
const PharmacyBottomSheet({ | |
@required this.onChanged, | |
@required this.onExit, | |
this.pharmacy, | |
}) : super(onChanged: onChanged, onExit: onExit, pharmacy: pharmacy); | |
@override | |
State<StatefulWidget> createState() => PharmacyBottomSheetState(); | |
} | |
class PharmacyBottomSheetState extends PharmacyViewBaseState { | |
@override | |
void onTap() { | |
showQuickBottomSheet( | |
context: context, | |
child: ChangeNotifierProvider.value( | |
value: pharmacyViewModel, | |
child: Consumer<PharmacyViewModel>(builder: (context, _, __) { | |
return Material( | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.all( | |
Radius.circular(20), | |
), | |
), | |
// color: Colors.white, | |
child: buildContent(), | |
); | |
}), | |
), | |
); | |
} | |
} | |
class PharmacyDialog extends PharmacyViewBase { | |
final Function(Pharmacy) onChanged; | |
final Function() onExit; | |
final Pharmacy pharmacy; | |
const PharmacyDialog({ | |
@required this.onChanged, | |
@required this.onExit, | |
this.pharmacy, | |
}) : super(onChanged: onChanged, onExit: onExit, pharmacy: pharmacy); | |
@override | |
State<StatefulWidget> createState() => PharmacyDialogState(); | |
} | |
class PharmacyDialogState extends PharmacyViewBaseState { | |
@override | |
void onTap() { | |
showDialog( | |
context: context, | |
builder: (context) { | |
return Dialog( | |
child: ChangeNotifierProvider.value( | |
value: pharmacyViewModel, | |
child: Consumer<PharmacyViewModel>(builder: (context, _, __) { | |
return Material( | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.all( | |
Radius.circular(20), | |
), | |
), | |
// color: Colors.white, | |
child: Material( | |
child: buildContent(), | |
), | |
); | |
}), | |
), | |
); | |
}, | |
); | |
} | |
} | |
class PharmacySideSheet extends PharmacyViewBase { | |
final Function(Pharmacy) onChanged; | |
final Function() onExit; | |
final Pharmacy pharmacy; | |
const PharmacySideSheet({ | |
@required this.onChanged, | |
@required this.onExit, | |
this.pharmacy, | |
}) : super(onChanged: onChanged, onExit: onExit, pharmacy: pharmacy); | |
@override | |
State<StatefulWidget> createState() => PharmacySideSheetState(); | |
} | |
class PharmacySideSheetState extends PharmacyViewBaseState { | |
@override | |
void onTap() { | |
showGeneralDialog( | |
barrierLabel: "Barrier", | |
barrierDismissible: true, | |
barrierColor: Colors.black.withOpacity(0.5), | |
transitionDuration: Duration(milliseconds: 300), | |
context: context, | |
pageBuilder: (context, animation1, animation2) { | |
return Align( | |
alignment: (true ? Alignment.centerRight : Alignment.centerLeft), | |
child: Container( | |
width: MediaQuery.of(context).size.width * 0.7, | |
decoration: BoxDecoration( | |
color: Colors.white, | |
), | |
child: buildContent(), | |
), | |
); | |
}, | |
transitionBuilder: (context, animation1, animation2, child) { | |
return SlideTransition( | |
position: Tween(begin: Offset((true ? 1 : -1), 0), end: Offset(0, 0)).animate(animation1), | |
child: child, | |
); | |
}, | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment