Skip to content

Instantly share code, notes, and snippets.

@locskot
Created June 15, 2021 06:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save locskot/aeef46b1357bd896250e701a772b495d to your computer and use it in GitHub Desktop.
Save locskot/aeef46b1357bd896250e701a772b495d to your computer and use it in GitHub Desktop.
example
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