Skip to content

Commit

Permalink
0.0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed dawood committed Feb 18, 2022
1 parent d494090 commit fa38ca7
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 219 deletions.
16 changes: 8 additions & 8 deletions ready/example/lib/ready_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ class ReadyGridExample extends StatelessWidget {
}

class ReadyListCubit extends Cubit<ReadyListState<FakeItem>>
implements RemoteReadyListController<FakeItem> {
implements ReadyListController<FakeItem> {
ReadyListCubit(ReadyListState<FakeItem> initialState) : super(initialState);

@override
Future<ReadyListResponse<FakeItem>> loadData(
{ICancelToken? cancelToken,
required int skip,
required int pageSize}) async {
var list = await FakeRepo.asyncList(pageSize);
return ReadyListResponse.success(items: list, total: 100);
}
ListLoadingHandler<FakeItem>? get handler => DefaultListLoadingHandler(
loadData: (skip, pageSize, cancelToken) async {
var list = await FakeRepo.asyncList(pageSize);
return ReadyListResponse.success(items: list, total: 100);
},
controller: this,
);
}
17 changes: 9 additions & 8 deletions ready/example/lib/ready_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,15 @@ class ReadyListExample extends StatelessWidget {
}

class ReadyListCubit extends Cubit<ReadyListState<FakeItem>>
implements RemoteReadyListController<FakeItem> {
implements ReadyListController<FakeItem> {
ReadyListCubit(ReadyListState<FakeItem> initialState) : super(initialState);

@override
Future<ReadyListResponse<FakeItem>> loadData(
{ICancelToken? cancelToken,
required int skip,
required int pageSize}) async {
var list = await FakeRepo.asyncList(30, const Duration(seconds: 3));
return ReadyListResponse.success(items: list, total: 100);
}
ListLoadingHandler<FakeItem>? get handler => DefaultListLoadingHandler(
loadData: (skip, pageSize, cancelToken) async {
var list = await FakeRepo.asyncList(30, const Duration(seconds: 3));
return ReadyListResponse.success(items: list, total: 100);
},
controller: this,
);
}
18 changes: 9 additions & 9 deletions ready/example/lib/responsive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ResponsiveList extends StatelessWidget {
SearchFilter(
decoration: const InputDecoration(hintText: 'Search here'),
onChange: (String? value) {
controller.loadInitialData(16);
controller.handler?.loadInitialData(16);
},
),
],
Expand Down Expand Up @@ -75,15 +75,15 @@ class ResponsiveList extends StatelessWidget {
}

class ReadyListCubit extends Cubit<ReadyListState<FakeItem>>
implements RemoteReadyListController<FakeItem> {
implements ReadyListController<FakeItem> {
ReadyListCubit() : super(ReadyListState());

@override
Future<ReadyListResponse<FakeItem>> loadData(
{ICancelToken? cancelToken,
required int skip,
required int pageSize}) async {
var list = await FakeRepo.asyncList(pageSize);
return ReadyListResponse.success(items: list, total: 100);
}
ListLoadingHandler<FakeItem>? get handler => DefaultListLoadingHandler(
loadData: (skip, pageSize, cancelToken) async {
var list = await FakeRepo.asyncList(pageSize);
return ReadyListResponse.success(items: list, total: 100);
},
controller: this,
);
}
2 changes: 1 addition & 1 deletion ready/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.2"
version: "0.0.4"
sky_engine:
dependency: transitive
description: flutter
Expand Down
2 changes: 1 addition & 1 deletion ready/lib/src/controllers/controllers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ library controllers;
import 'dart:async';

import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:ready/ready.dart';

import '../enums.dart';

part 'loading_handler.dart';
part 'ready_list_controller.dart';
part 'ready_list_state.dart';

Expand Down
145 changes: 145 additions & 0 deletions ready/lib/src/controllers/loading_handler.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
part of controllers;

abstract class ListLoadingHandler<T> {
/// used to load initial data
Future loadInitialData(int pageSize);

///used to refresh data
Future refreshData(int pageSize);

/// used to load next data
Future nextData(int pageSize);
}

/// this is default handler for loading data into [ReadyListController]
class DefaultListLoadingHandler<T> extends ListLoadingHandler<T> {
final Future<ReadyListResponse<T>> Function(
int skip, int pageSize, ICancelToken? cancelToken) loadData;
final ICancelToken Function()? generateCancelToken;
final ReadyListController<T> controller;
DefaultListLoadingHandler({
required this.loadData,
required this.controller,
this.generateCancelToken,
});

ReadyListState<T> get state => controller.state;
Function(ReadyListState<T> state) get emit => controller.emit;

void _emitSuccess(_Success<T> result) {
state.whenOrNull(
initialLoading: (cancelToken) {
if (result.items.isEmpty) {
emit(state.empty());
} else {
emit(state.loaded(result.items, result.total));
}
},
refreshing: (items, total, cancelToken) {
if (result.items.isEmpty) {
emit(state.empty());
} else {
emit(state.loaded(result.items, result.total));
}
},
loadingNext: (items, total, cancelToken) {
emit(state.loaded([...items, ...result.items], result.total));
},
);
}

void _emitResults(
ReadyListResponse<T> result, ReadyListState<T> previousState) {
if (result is _Success<T>) {
_emitSuccess(result);
} else if (result is _Cancel<T>) {
emit(previousState);
} else if (result is _Error<T>) {
emit(state.error(result.error));
} else {
throw UnsupportedError('Unsupported response');
}
}

void _checkDuplicatedLoading() {
state.whenOrNull(
initialLoading: (cancelToken) {
if (cancelToken != null) {
throw Exception(
"You can not make multiple load you should cancel running one first");
}
},
loadingNext: (items, total, cancelToken) {
if (cancelToken != null) {
throw Exception(
"You can not make multiple load you should cancel running one first");
}
},
refreshing: (items, total, cancelToken) {
if (cancelToken != null) {
throw Exception(
"You can not make multiple load you should cancel running one first");
}
},
);
}

@override
Future loadInitialData(int pageSize) async {
_checkDuplicatedLoading();
var previousState = state;
var _cancelToken = generateCancelToken?.call();
emit(state.initialLoading(_cancelToken));
try {
var results = await loadData(0, pageSize, _cancelToken);
_emitResults(results, previousState);
} catch (e) {
emit(previousState);
rethrow;
}
}

@override
Future refreshData(int pageSize) async {
_checkDuplicatedLoading();
var previousState = state;
if (previousState.type != ListStateType.loaded) {
throw Exception(
"Refreshing must be called when state is Loaded try call loadInitial");
}
var _cancelToken = generateCancelToken?.call();

emit(state.refreshing(_cancelToken));
try {
var results = await loadData(0, pageSize, _cancelToken);
_emitResults(results, previousState);
} catch (e) {
emit(previousState);
rethrow;
}
}

@override
Future nextData(int pageSize) async {
_checkDuplicatedLoading();
var previousState = state;
if (previousState.type != ListStateType.loaded) {
throw Exception(
"Load next must be called when state is Loaded try call loadInitial");
}
if (previousState.items.length >= previousState.total) {
throw Exception("There is no data to load");
}
var _cancelToken = generateCancelToken?.call();

emit(state.loadingNext(_cancelToken));
try {
var results =
await loadData(previousState.items.length, pageSize, _cancelToken);
_emitResults(results, previousState);
} catch (e) {
emit(previousState);
rethrow;
}
}
}
Loading

0 comments on commit fa38ca7

Please sign in to comment.