69 lines
1.7 KiB
Dart
69 lines
1.7 KiB
Dart
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
|
|
import '../data/mock_news_repository.dart';
|
|
import '../data/news_models.dart';
|
|
|
|
final newsControllerProvider = StateNotifierProvider<NewsController, NewsState>(
|
|
(ref) => NewsController(ref.watch(mockNewsRepositoryProvider)),
|
|
);
|
|
|
|
class NewsState {
|
|
const NewsState({
|
|
required this.items,
|
|
required this.refreshedAt,
|
|
required this.hasMore,
|
|
required this.loadingMore,
|
|
});
|
|
|
|
final List<NewsItem> items;
|
|
final DateTime refreshedAt;
|
|
final bool hasMore;
|
|
final bool loadingMore;
|
|
}
|
|
|
|
class NewsController extends StateNotifier<NewsState> {
|
|
NewsController(this._repository)
|
|
: super(
|
|
NewsState(
|
|
items: _repository.loadFeed(),
|
|
refreshedAt: DateTime(2026, 6, 18, 16, 11),
|
|
hasMore: true,
|
|
loadingMore: false,
|
|
),
|
|
);
|
|
|
|
final MockNewsRepository _repository;
|
|
static const _pageSize = 3;
|
|
|
|
void refresh() {
|
|
final items = _repository.loadFeed(limit: _pageSize);
|
|
state = NewsState(
|
|
items: items,
|
|
refreshedAt: DateTime.now(),
|
|
hasMore: items.length == _pageSize,
|
|
loadingMore: false,
|
|
);
|
|
}
|
|
|
|
bool loadMore() {
|
|
if (state.loadingMore || !state.hasMore) return state.hasMore;
|
|
state = NewsState(
|
|
items: state.items,
|
|
refreshedAt: state.refreshedAt,
|
|
hasMore: state.hasMore,
|
|
loadingMore: true,
|
|
);
|
|
final next = _repository.loadFeed(
|
|
offset: state.items.length,
|
|
limit: _pageSize,
|
|
);
|
|
state = NewsState(
|
|
items: [...state.items, ...next],
|
|
refreshedAt: state.refreshedAt,
|
|
hasMore: next.length == _pageSize,
|
|
loadingMore: false,
|
|
);
|
|
return state.hasMore;
|
|
}
|
|
}
|