fix:对比原型增加功能交互
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import '../models/models.dart';
|
||||
import '../repositories/user_state_repository.dart';
|
||||
import 'app_interaction_state.dart';
|
||||
import 'report_query.dart';
|
||||
|
||||
class RecommendTopicController extends StateNotifier<String> {
|
||||
RecommendTopicController() : super('全部');
|
||||
|
||||
void select(String topic) {
|
||||
state = topic;
|
||||
}
|
||||
}
|
||||
|
||||
class ReportFilterController extends StateNotifier<ReportQuery> {
|
||||
ReportFilterController() : super(const ReportQuery());
|
||||
|
||||
void setSearch(String value) {
|
||||
state = state.copyWith(search: value);
|
||||
}
|
||||
|
||||
void setTopic(String? topic) {
|
||||
state = state.copyWith(topic: topic);
|
||||
}
|
||||
|
||||
void setInstitution(String? institutionId) {
|
||||
state = state.copyWith(institutionId: institutionId);
|
||||
}
|
||||
|
||||
void toggleAudio() {
|
||||
state = state.copyWith(hasAudio: !state.hasAudio);
|
||||
}
|
||||
|
||||
void setSort(ReportSort sort) {
|
||||
state = state.copyWith(sort: sort);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
state = const ReportQuery();
|
||||
}
|
||||
}
|
||||
|
||||
class AuthController extends StateNotifier<AuthState> {
|
||||
AuthController(this._repository) : super(const AuthState()) {
|
||||
_load();
|
||||
}
|
||||
|
||||
final UserStateRepository _repository;
|
||||
|
||||
Future<void> _load() async {
|
||||
state = state.copyWith(loggedIn: await _repository.isLoggedIn());
|
||||
}
|
||||
|
||||
void requireLogin(PendingLoginAction action) {
|
||||
if (state.loggedIn) return;
|
||||
state = state.copyWith(pendingAction: action);
|
||||
}
|
||||
|
||||
Future<PendingLoginAction?> login(LoginMethod method) async {
|
||||
final pending = state.pendingAction;
|
||||
await _repository.login(method);
|
||||
state = const AuthState(loggedIn: true);
|
||||
return pending;
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await _repository.logout();
|
||||
state = const AuthState();
|
||||
}
|
||||
|
||||
void clearPending() {
|
||||
state = state.copyWith(pendingAction: null);
|
||||
}
|
||||
}
|
||||
|
||||
class ProfileController extends StateNotifier<ProfileState> {
|
||||
ProfileController(this._repository) : super(const ProfileState()) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
final UserStateRepository _repository;
|
||||
|
||||
Future<void> refresh() async {
|
||||
state = ProfileState(
|
||||
favorites: await _repository.getFavorites(),
|
||||
savedListens: await _repository.getSavedListens(),
|
||||
history: await _repository.getHistory(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> toggleFavorite(String reportId) async {
|
||||
await _repository.toggleFavorite(reportId);
|
||||
await refresh();
|
||||
}
|
||||
|
||||
Future<void> toggleSavedListen(String reportId) async {
|
||||
await _repository.toggleSavedListen(reportId);
|
||||
await refresh();
|
||||
}
|
||||
|
||||
Future<void> addHistory(String reportId) async {
|
||||
await _repository.addHistory(reportId);
|
||||
await refresh();
|
||||
}
|
||||
}
|
||||
|
||||
class DetailNavigationController extends StateNotifier<DetailNavigationState> {
|
||||
DetailNavigationController() : super(const DetailNavigationState());
|
||||
|
||||
void rememberTabScroll(AppTab tab, double scrollTop) {
|
||||
state = state.copyWith(tabScroll: {...state.tabScroll, tab: scrollTop});
|
||||
}
|
||||
|
||||
void push(DetailStackEntry entry, {required AppTab originTab}) {
|
||||
final stack = [...state.stack, entry];
|
||||
state = state.copyWith(originTab: originTab, stack: stack);
|
||||
}
|
||||
|
||||
void updateCurrentScroll(double scrollTop) {
|
||||
if (state.stack.isEmpty) return;
|
||||
final stack = [...state.stack];
|
||||
stack[stack.length - 1] = stack.last.copyWith(scrollTop: scrollTop);
|
||||
state = state.copyWith(stack: stack);
|
||||
}
|
||||
|
||||
DetailStackEntry? pop() {
|
||||
if (state.stack.isEmpty) return null;
|
||||
final stack = [...state.stack]..removeLast();
|
||||
state = state.copyWith(stack: stack);
|
||||
return stack.isEmpty ? null : stack.last;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
state = const DetailNavigationState();
|
||||
}
|
||||
}
|
||||
|
||||
class SheetController extends StateNotifier<SheetState> {
|
||||
SheetController() : super(const SheetState.hidden());
|
||||
|
||||
void show(SheetIntent intent) {
|
||||
state = SheetState.visible(intent);
|
||||
}
|
||||
|
||||
void hide() {
|
||||
state = const SheetState.hidden();
|
||||
}
|
||||
}
|
||||
|
||||
class ProfileListBuilder {
|
||||
const ProfileListBuilder(this.reports);
|
||||
|
||||
final List<ReportCardModel> reports;
|
||||
|
||||
List<ReportCardModel> byIds(Iterable<String> ids) {
|
||||
final byId = {for (final report in reports) report.id: report};
|
||||
return ids.map((id) => byId[id]).whereType<ReportCardModel>().toList();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user