Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 所有列表均添加无限列表 #117

Merged
merged 23 commits into from
Dec 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions lib/blocs/board/board_home/board_home_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,39 +1,53 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:smart_home/models/board.dart';
import 'package:smart_home/repositories/board_repository.dart';
import 'package:flutter/foundation.dart';
import 'package:smart_home/models/models.dart';
import 'package:smart_home/repositories/repositories.dart';

part 'board_home_event.dart';
part 'board_home_state.dart';

class BoardHomeBloc extends Bloc<BoardHomeEvent, BoardHomeState> {
final BoardRepository boardRepository;

BoardHomeBloc({@required this.boardRepository})
: super(BoardHomeInProgress());
BoardHomeBloc({
@required this.boardRepository,
}) : super(BoardHomeInProgress());

@override
Stream<BoardHomeState> mapEventToState(
BoardHomeEvent event,
) async* {
if (event is BoardHomeStarted) {
final currentState = state;
if (event is BoardHomeFetched) {
try {
final currentState = state;
if (currentState is! BoardHomeSuccess) {
// 如果需要刷新,则显示加载界面
// 因为需要请求网络最好提示用户
if (!event.cache) {
yield BoardHomeInProgress();
}
List<Topic> topics = await boardRepository.topics(cache: false);
yield BoardHomeSuccess(topics: topics);
} catch (e) {
yield BoardHomeFailure(e.message);
}
}
if (event is BoardHomeRefreshed) {
try {
yield BoardHomeInProgress();
List<Topic> topics = await boardRepository.topics(cache: false);
yield BoardHomeSuccess(topics: topics);
if (event.cache &&
currentState is BoardHomeSuccess &&
!currentState.hasReachedMax) {
// 如果不需要刷新,不是首次启动,或遇到错误,并且有下一页
// 则获取下一页
final results = await boardRepository.topics(
after: currentState.pageInfo.endCursor,
);
yield BoardHomeSuccess(
topics: currentState.topics + results.item1,
pageInfo: currentState.pageInfo.copyWith(results.item2),
);
} else {
// 其他情况根据设置看是否需要打开缓存,并获取第一页
final results = await boardRepository.topics(
cache: event.cache,
);
yield BoardHomeSuccess(
topics: results.item1,
pageInfo: results.item2,
);
}
} catch (e) {
yield BoardHomeFailure(e.message);
}
Expand Down
14 changes: 12 additions & 2 deletions lib/blocs/board/board_home/board_home_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ abstract class BoardHomeEvent extends Equatable {
List<Object> get props => [];
}

class BoardHomeStarted extends BoardHomeEvent {}
class BoardHomeFetched extends BoardHomeEvent {
final bool cache;

class BoardHomeRefreshed extends BoardHomeEvent {}
BoardHomeFetched({
this.cache = true,
});

@override
List<Object> get props => [cache];

@override
String toString() => 'BoardHomeFetched(cache: $cache)';
}
19 changes: 15 additions & 4 deletions lib/blocs/board/board_home/board_home_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ abstract class BoardHomeState extends Equatable {
List<Object> get props => [];
}

class BoardHomeInProgress extends BoardHomeState {}
class BoardHomeInProgress extends BoardHomeState {
@override
String toString() => 'BoardHomeInProgress';
}

class BoardHomeFailure extends BoardHomeState {
final String message;
Expand All @@ -16,18 +19,26 @@ class BoardHomeFailure extends BoardHomeState {

@override
List<Object> get props => [message];

@override
String toString() => 'BoardHomeFailure(message: $message)';
}

class BoardHomeSuccess extends BoardHomeState {
final List<Topic> topics;
final PageInfo pageInfo;

const BoardHomeSuccess({
this.topics,
@required this.topics,
@required this.pageInfo,
});

bool get hasReachedMax => !pageInfo.hasNextPage;

@override
List<Object> get props => [topics];
List<Object> get props => [topics, pageInfo];

@override
String toString() => 'BoardHomeSuccess { topics ${topics?.length ?? 0} }';
String toString() =>
'BoardHomeSuccess { topics: ${topics.length}, hasReachedMax: $hasReachedMax';
}
83 changes: 51 additions & 32 deletions lib/blocs/board/topic_detail/topic_detail_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,54 +1,73 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:smart_home/models/board.dart';
import 'package:smart_home/repositories/board_repository.dart';
import 'package:flutter/foundation.dart';
import 'package:smart_home/models/models.dart';
import 'package:smart_home/repositories/repositories.dart';
import 'package:tuple/tuple.dart';

part 'topic_detail_event.dart';
part 'topic_detail_state.dart';

class TopicDetailBloc extends Bloc<TopicDetailEvent, TopicDetailState> {
final BoardRepository boardRepository;
bool descending = false;

TopicDetailBloc({@required this.boardRepository})
: super(TopicDetailInProgress());
TopicDetailBloc({
@required this.boardRepository,
}) : super(TopicDetailInProgress());

@override
Stream<TopicDetailState> mapEventToState(
TopicDetailEvent event,
) async* {
if (event is TopicDetailChanged) {
try {
yield TopicDetailInProgress();
descending = event.descending;
final topicDetail = await boardRepository.topicDetail(
topicId: event.topicId,
descending: descending,
);
yield TopicDetailSuccess(
topic: topicDetail.item1, comments: topicDetail.item2);
} catch (e) {
yield TopicDetailFailure(
e.message,
topicId: event.topicId,
);
}
}
final currentState = state;
if (event is TopicDetailRefreshed && currentState is TopicDetailSuccess) {
if (event is TopicDetailFetched) {
try {
final topicDetail = await boardRepository.topicDetail(
topicId: currentState.topic.id,
descending: descending,
cache: false,
);
yield TopicDetailSuccess(
topic: topicDetail.item1, comments: topicDetail.item2);
// 如果需要刷新,则显示加载界面
// 因为需要请求网络最好提示用户
if (!event.cache) {
yield TopicDetailInProgress();
}
if (event.cache &&
currentState is TopicDetailSuccess &&
!currentState.hasReachedMax) {
// 如果不需要刷新,不是首次启动,或遇到错误,并且有下一页
// 则获取下一页
final results = await boardRepository.topicDetail(
topicId: event.topicId,
descending: event.descending,
after: currentState.pageInfo.endCursor,
);
yield TopicDetailSuccess(
topic: results.item1,
comments: currentState.comments + results.item2,
pageInfo: currentState.pageInfo.copyWith(results.item3),
);
} else {
// 其他情况根据设置看是否需要打开缓存,并获取第一页
Tuple3<Topic, List<Comment>, PageInfo> results;
if (currentState is TopicDetailSuccess) {
results = await boardRepository.topicDetail(
topicId: currentState.topic.id,
descending: event.descending,
cache: event.cache,
);
} else {
results = await boardRepository.topicDetail(
topicId: event.topicId,
descending: event.descending,
cache: event.cache,
);
}
yield TopicDetailSuccess(
topic: results.item1,
comments: results.item2,
pageInfo: results.item3,
);
}
} catch (e) {
yield TopicDetailFailure(
e.message,
topicId: currentState.topic.id,
topicId: event.topicId,
);
}
}
Expand Down
18 changes: 8 additions & 10 deletions lib/blocs/board/topic_detail/topic_detail_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,21 @@ abstract class TopicDetailEvent extends Equatable {
List<Object> get props => [];
}

class TopicDetailChanged extends TopicDetailEvent {
class TopicDetailFetched extends TopicDetailEvent {
final String topicId;
final bool descending;
final bool cache;

const TopicDetailChanged({
@required this.topicId,
const TopicDetailFetched({
this.topicId,
@required this.descending,
this.cache = true,
});

@override
String toString() =>
'TopicChanged { TopicId: $topicId, descending: $descending }';
}

class TopicDetailRefreshed extends TopicDetailEvent {
const TopicDetailRefreshed();
List<Object> get props => [topicId, descending, cache];

@override
String toString() => 'TopicRefreshed';
String toString() =>
'TopicDetailFetched(topicId: $topicId, descending: $descending, cache: $cache)';
}
20 changes: 18 additions & 2 deletions lib/blocs/board/topic_detail/topic_detail_state.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
part of 'topic_detail_bloc.dart';

abstract class TopicDetailState {
abstract class TopicDetailState extends Equatable {
const TopicDetailState();

@override
List<Object> get props => [];
}

class TopicDetailInProgress extends TopicDetailState {}
class TopicDetailInProgress extends TopicDetailState {
@override
String toString() => 'TopicDetailInProgress';
}

class TopicDetailFailure extends TopicDetailState {
final String message;
Expand All @@ -15,19 +21,29 @@ class TopicDetailFailure extends TopicDetailState {
@required this.topicId,
});

@override
List<Object> get props => [message, topicId];

@override
String toString() => 'TopicDetailFailure { message: $message }';
}

class TopicDetailSuccess extends TopicDetailState {
final Topic topic;
final List<Comment> comments;
final PageInfo pageInfo;

const TopicDetailSuccess({
@required this.topic,
@required this.comments,
@required this.pageInfo,
});

bool get hasReachedMax => !pageInfo.hasNextPage;

@override
List<Object> get props => [topic, comments, pageInfo];

@override
String toString() =>
'TopicDetailSuccess { Topic: ${topic.title}, Comments: ${comments.length} }';
Expand Down
42 changes: 30 additions & 12 deletions lib/blocs/storage/consumables/consumables_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:smart_home/models/models.dart';

import 'package:smart_home/models/storage.dart';
import 'package:smart_home/repositories/storage_repository.dart';
Expand All @@ -18,20 +20,36 @@ class ConsumablesBloc extends Bloc<ConsumablesEvent, ConsumablesState> {
Stream<ConsumablesState> mapEventToState(
ConsumablesEvent event,
) async* {
final currentState = state;
if (event is ConsumablesFetched) {
yield ConsumablesInProgress();
try {
final List<Item> results = await storageRepository.consumables();
yield ConsumablesSuccess(items: results);
} catch (e) {
yield ConsumablesFailure(e.message);
}
}
if (event is ConsumablesRefreshed) {
try {
final List<Item> results =
await storageRepository.consumables(cache: false);
yield ConsumablesSuccess(items: results);
// 如果需要刷新,则显示加载界面
// 因为需要请求网络最好提示用户
if (!event.cache) {
yield ConsumablesInProgress();
}
if (event.cache &&
currentState is ConsumablesSuccess &&
!currentState.hasReachedMax) {
// 如果不需要刷新,不是首次启动,或遇到错误,并且有下一页
// 则获取下一页
final results = await storageRepository.consumables(
after: currentState.pageInfo.endCursor,
);
yield ConsumablesSuccess(
items: currentState.items + results.item1,
pageInfo: currentState.pageInfo.copyWith(results.item2),
);
} else {
// 其他情况根据设置看是否需要打开缓存,并获取第一页s
final results = await storageRepository.consumables(
cache: event.cache,
);
yield ConsumablesSuccess(
items: results.item1,
pageInfo: results.item2,
);
}
} catch (e) {
yield ConsumablesFailure(e.message);
}
Expand Down
Loading