165 lines
4.9 KiB
Dart
165 lines
4.9 KiB
Dart
import 'package:ebroker/Ui/screens/home/Widgets/property_horizontal_card.dart';
|
|
import 'package:ebroker/Ui/screens/widgets/AnimatedRoutes/blur_page_route.dart';
|
|
import 'package:ebroker/Ui/screens/widgets/Erros/something_went_wrong.dart';
|
|
import 'package:ebroker/utils/Extensions/extensions.dart';
|
|
import 'package:ebroker/utils/helper_utils.dart';
|
|
import 'package:ebroker/utils/ui_utils.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import '../../../app/routes.dart';
|
|
import '../../../data/model/property_model.dart';
|
|
|
|
///In this file https://dart.dev/language/generics generic types are used For more info you can see this
|
|
|
|
///This [PropertySuccessStateWireframe] this will force class to have properties list
|
|
|
|
abstract class PropertySuccessStateWireframe {
|
|
abstract List<PropertyModel> properties;
|
|
abstract bool isLoadingMore;
|
|
}
|
|
|
|
///this will force class to have error field
|
|
abstract class PropertyErrorStateWireframe {
|
|
dynamic error;
|
|
}
|
|
|
|
///This implementation is for cubit this will force property cubit to implement this methods.
|
|
abstract class PropertyCubitWireframe {
|
|
void fetch();
|
|
bool hasMoreData();
|
|
void fetchMore();
|
|
}
|
|
|
|
class ViewAllScreen<T extends StateStreamable<C>, C> extends StatefulWidget {
|
|
final String title;
|
|
final StateMap map;
|
|
ViewAllScreen({
|
|
Key? key,
|
|
required this.title,
|
|
required this.map,
|
|
}) : super(key: key) {
|
|
assert(T is! PropertyErrorStateWireframe,
|
|
"Please Extend PropertyErrorStateWireframe in cubit");
|
|
}
|
|
|
|
void open(BuildContext context) {
|
|
Navigator.push(context, BlurredRouter(
|
|
builder: (context) {
|
|
return ViewAllScreen<T, C>(title: title, map: map);
|
|
},
|
|
));
|
|
}
|
|
|
|
@override
|
|
_ViewAllScreenState<T, C> createState() => _ViewAllScreenState<T, C>();
|
|
}
|
|
|
|
class _ViewAllScreenState<T extends StateStreamable<C>, C>
|
|
extends State<ViewAllScreen> {
|
|
final ScrollController _pageScrollListener = ScrollController();
|
|
|
|
@override
|
|
void initState() {
|
|
_pageScrollListener.addListener(onPageEnd);
|
|
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_pageScrollListener.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
bool isSubtype<S, T>() => <S>[] is List<T>;
|
|
void onPageEnd() {
|
|
///This is extension which will check if we reached end or not
|
|
if (_pageScrollListener.isEndReached()) {
|
|
if (isSubtype<T, PropertyCubitWireframe>()) {
|
|
if (read<T>().hasMoreData()) {
|
|
read<T>().fetchMore();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dynamic read<X>() {
|
|
return context.read<X>();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: context.color.primaryColor,
|
|
// appBar: AppBar(
|
|
// backgroundColor: context.color.secondaryColor,
|
|
// elevation: 0,
|
|
// iconTheme: IconThemeData(color: context.color.teritoryColor),
|
|
// title: Text(
|
|
// widget.title,
|
|
// ).color(context.color.teritoryColor).size(context.font.large),
|
|
// ),
|
|
appBar: UiUtils.buildAppBar(context,
|
|
title: widget.title, showBackButton: true),
|
|
// body: Container(),
|
|
body: BlocBuilder<T, C>(builder: (context, state) {
|
|
return widget.map._buildState(state, _pageScrollListener);
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
|
|
///From generic type we are getting state so we can return ui according to that state
|
|
class StateMap<INITIAL, PROGRESS, SUCCESS extends PropertySuccessStateWireframe,
|
|
FAIL extends PropertyErrorStateWireframe> {
|
|
Widget _buildState(dynamic state, ScrollController controller) {
|
|
if (state is INITIAL) {
|
|
return Container();
|
|
}
|
|
if (state is PROGRESS) {
|
|
return Center(child: UiUtils.progress());
|
|
}
|
|
if (state is FAIL) {
|
|
return const SomethingWentWrong();
|
|
}
|
|
|
|
if (state is SUCCESS) {
|
|
return Column(
|
|
children: [
|
|
Expanded(
|
|
child: ScrollConfiguration(
|
|
behavior: RemoveGlow(),
|
|
child: ListView.builder(
|
|
controller: controller,
|
|
padding: const EdgeInsets.all(20),
|
|
itemBuilder: (context, index) {
|
|
PropertyModel model = state.properties[index];
|
|
return GestureDetector(
|
|
onTap: () {
|
|
HelperUtils.goToNextPage(
|
|
Routes.propertyDetails,
|
|
context,
|
|
false,
|
|
args: {
|
|
'propertyData': model,
|
|
'propertiesList': state.properties,
|
|
'fromMyProperty': false,
|
|
},
|
|
);
|
|
},
|
|
child: PropertyHorizontalCard(property: model));
|
|
},
|
|
itemCount: state.properties.length,
|
|
),
|
|
),
|
|
),
|
|
if (state.isLoadingMore) UiUtils.progress()
|
|
],
|
|
);
|
|
}
|
|
|
|
return Container();
|
|
}
|
|
}
|