Files
xianyan/lib/features/template/wallpaper_provider.dart
Developer f91be94e9c refactor: 完成项目架构重构,统一模块导入路径
- 清理大量废弃的 barrel 导出文件,移除冗余的中间导出层
- 修复所有相对路径导入错误,统一调整为扁平化模块引用
- 更新多平台 pubspec 版本号与依赖库版本
- 补充后端功能问题管理后台与脚本工具
- 调整部分页面的快捷方式文案适配新功能
- 更新部分翻译覆盖率与API文档
2026-06-12 08:53:57 +08:00

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,
);