- 清理大量废弃的 barrel 导出文件,移除冗余的中间导出层 - 修复所有相对路径导入错误,统一调整为扁平化模块引用 - 更新多平台 pubspec 版本号与依赖库版本 - 补充后端功能问题管理后台与脚本工具 - 调整部分页面的快捷方式文案适配新功能 - 更新部分翻译覆盖率与API文档
174 lines
5.1 KiB
Dart
174 lines
5.1 KiB
Dart
/// ============================================================
|
|
/// 闲言APP — 壁纸模板状态管理
|
|
/// 创建时间: 2026-05-01
|
|
/// 更新时间: 2026-05-01
|
|
/// 作用: 壁纸图库状态 — 来源/分类/分页/搜索
|
|
/// 上次更新: 初始创建
|
|
/// ============================================================
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../core/utils/logger.dart';
|
|
import 'models/template_models.dart';
|
|
import 'services/wallpaper_service.dart';
|
|
|
|
// ============================================================
|
|
// State
|
|
// ============================================================
|
|
|
|
class WallpaperState {
|
|
const WallpaperState({
|
|
this.items = const [],
|
|
this.currentSource = WallpaperSource.unsplash,
|
|
this.currentCategory = WallpaperCategory.all,
|
|
this.currentPage = 1,
|
|
this.totalPages = 1,
|
|
this.hasNext = false,
|
|
this.isLoading = true,
|
|
this.searchQuery,
|
|
});
|
|
|
|
final List<WallpaperItem> items;
|
|
final WallpaperSource currentSource;
|
|
final WallpaperCategory currentCategory;
|
|
final int currentPage;
|
|
final int totalPages;
|
|
final bool hasNext;
|
|
final bool isLoading;
|
|
final String? searchQuery;
|
|
|
|
WallpaperState copyWith({
|
|
List<WallpaperItem>? items,
|
|
WallpaperSource? currentSource,
|
|
WallpaperCategory? currentCategory,
|
|
int? currentPage,
|
|
int? totalPages,
|
|
bool? hasNext,
|
|
bool? isLoading,
|
|
String? searchQuery,
|
|
bool clearSearch = false,
|
|
}) => WallpaperState(
|
|
items: items ?? this.items,
|
|
currentSource: currentSource ?? this.currentSource,
|
|
currentCategory: currentCategory ?? this.currentCategory,
|
|
currentPage: currentPage ?? this.currentPage,
|
|
totalPages: totalPages ?? this.totalPages,
|
|
hasNext: hasNext ?? this.hasNext,
|
|
isLoading: isLoading ?? this.isLoading,
|
|
searchQuery: clearSearch ? null : (searchQuery ?? this.searchQuery),
|
|
);
|
|
}
|
|
|
|
// ============================================================
|
|
// Notifier
|
|
// ============================================================
|
|
|
|
class WallpaperNotifier extends Notifier<WallpaperState> {
|
|
Timer? _debounce;
|
|
|
|
@override
|
|
WallpaperState build() {
|
|
ref.onDispose(() { _debounce?.cancel(); });
|
|
Future.microtask(() {
|
|
loadWallpapers().catchError((Object e) { Log.e('WallpaperNotifier.loadWallpapers 失败', e); });
|
|
}).catchError((_) {});
|
|
return const WallpaperState();
|
|
}
|
|
|
|
WallpaperNotifier();
|
|
|
|
Future<void> loadWallpapers({bool refresh = false}) async {
|
|
if (refresh) {
|
|
state = state.copyWith(currentPage: 1, clearSearch: true);
|
|
}
|
|
state = state.copyWith(isLoading: true);
|
|
|
|
try {
|
|
final result = await WallpaperService.fetchWallpapers(
|
|
source: state.currentSource,
|
|
page: refresh ? 1 : state.currentPage,
|
|
category: state.currentCategory,
|
|
search: state.searchQuery,
|
|
);
|
|
|
|
final newItems = refresh
|
|
? result.items
|
|
: [...state.items, ...result.items];
|
|
|
|
state = state.copyWith(
|
|
items: newItems,
|
|
currentPage: result.currentPage,
|
|
totalPages: result.totalPages,
|
|
hasNext: result.hasNext,
|
|
isLoading: false,
|
|
);
|
|
Log.i('壁纸加载成功: ${result.items.length} 张 (共${result.totalPages}页)');
|
|
} catch (e) {
|
|
Log.e('壁纸加载失败', e);
|
|
state = state.copyWith(isLoading: false);
|
|
}
|
|
}
|
|
|
|
Future<void> loadMore() async {
|
|
if (state.isLoading || !state.hasNext) return;
|
|
final nextPage = state.currentPage + 1;
|
|
state = state.copyWith(isLoading: true);
|
|
try {
|
|
final result = await WallpaperService.fetchWallpapers(
|
|
source: state.currentSource,
|
|
page: nextPage,
|
|
category: state.currentCategory,
|
|
search: state.searchQuery,
|
|
);
|
|
state = state.copyWith(
|
|
items: [...state.items, ...result.items],
|
|
currentPage: result.currentPage,
|
|
totalPages: result.totalPages,
|
|
hasNext: result.hasNext,
|
|
isLoading: false,
|
|
);
|
|
} catch (e) {
|
|
Log.e('加载更多壁纸失败', e);
|
|
state = state.copyWith(isLoading: false);
|
|
}
|
|
}
|
|
|
|
void setSource(WallpaperSource source) {
|
|
if (source == state.currentSource) return;
|
|
state = state.copyWith(currentSource: source, items: []);
|
|
loadWallpapers(refresh: true);
|
|
}
|
|
|
|
void setCategory(WallpaperCategory category) {
|
|
if (category == state.currentCategory) return;
|
|
state = state.copyWith(currentCategory: category, items: []);
|
|
loadWallpapers(refresh: true);
|
|
}
|
|
|
|
void search(String query) {
|
|
if (query == state.searchQuery) return;
|
|
_debounce?.cancel();
|
|
state = state.copyWith(searchQuery: query);
|
|
_debounce = Timer(const Duration(milliseconds: 300), () {
|
|
loadWallpapers(refresh: true);
|
|
});
|
|
}
|
|
|
|
void clearSearch() {
|
|
if (state.searchQuery == null) return;
|
|
_debounce?.cancel();
|
|
state = state.copyWith(clearSearch: true);
|
|
loadWallpapers(refresh: true);
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// Provider
|
|
// ============================================================
|
|
|
|
final wallpaperProvider = NotifierProvider<WallpaperNotifier, WallpaperState>(
|
|
WallpaperNotifier.new,
|
|
);
|