本次提交涵盖多项功能优化与重构: 1. 重构pro_image_editor依赖为官方托管版本,移除本地包引用 2. 拆分角色表情枚举至独立文件,优化代码复用性 3. 新增壁纸收藏、预加载、健康检测服务与本地存储支持 4. 完善API响应类型安全检查与排行榜服务能力 5. 新增应用锁设置路由与页面支持 6. 优化路由跳转使用常量路径替代硬编码字符串 7. 新增阅读报告分享功能与设置变更日志服务 8. 修复多处类型转换与空指针风险问题 9. 调整API超时时间优化网络请求表现 10. 统一文件头格式与部分UI组件样式
152 lines
4.9 KiB
Dart
152 lines
4.9 KiB
Dart
/// ============================================================
|
||
/// 闲言APP — 桌面小部件状态管理
|
||
/// 创建时间: 2026-05-19
|
||
/// 更新时间: 2026-05-24
|
||
/// 作用: 管理小部件安装状态、数据推送和交互
|
||
/// 上次更新: requestPinWidget返回PinWidgetResult枚举,鸿蒙端直接返回unsupported
|
||
/// ============================================================
|
||
|
||
import 'dart:ui';
|
||
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:home_widget/home_widget.dart';
|
||
import 'package:xianyan/core/utils/platform/platform_utils.dart' as pu;
|
||
|
||
import '../../../core/services/data/home_widget_service.dart';
|
||
import '../../../core/utils/logger.dart';
|
||
import '../models/widget_type.dart';
|
||
|
||
enum PinWidgetResult { success, unsupported, failed }
|
||
|
||
class WidgetState {
|
||
final Set<WidgetType> installedWidgets;
|
||
final bool isLoading;
|
||
final String? error;
|
||
|
||
const WidgetState({
|
||
this.installedWidgets = const {},
|
||
this.isLoading = false,
|
||
this.error,
|
||
});
|
||
|
||
WidgetState copyWith({
|
||
Set<WidgetType>? installedWidgets,
|
||
bool? isLoading,
|
||
String? error,
|
||
}) => WidgetState(
|
||
installedWidgets: installedWidgets ?? this.installedWidgets,
|
||
isLoading: isLoading ?? this.isLoading,
|
||
error: error,
|
||
);
|
||
}
|
||
|
||
class WidgetNotifier extends Notifier<WidgetState> {
|
||
@override
|
||
WidgetState build() => const WidgetState();
|
||
|
||
Future<void> loadInstalledWidgets() async {
|
||
state = state.copyWith(isLoading: true);
|
||
try {
|
||
final widgets = await HomeWidget.getInstalledWidgets();
|
||
final installed = <WidgetType>{};
|
||
|
||
for (final w in widgets) {
|
||
final kind = w.iOSKind ?? w.androidClassName ?? '';
|
||
for (final type in WidgetType.values) {
|
||
if (kind.contains(type.androidProviderName) ||
|
||
kind.contains(type.iosWidgetKind) ||
|
||
kind.contains(type.ohosFormName)) {
|
||
installed.add(type);
|
||
}
|
||
}
|
||
}
|
||
|
||
state = state.copyWith(installedWidgets: installed, isLoading: false);
|
||
Log.i('WidgetNotifier: 已安装 ${installed.length} 个小部件');
|
||
} catch (e) {
|
||
Log.e('WidgetNotifier: 加载小部件失败', e);
|
||
state = state.copyWith(isLoading: false, error: e.toString());
|
||
}
|
||
}
|
||
|
||
Future<void> addWidget(WidgetType type) async {
|
||
try {
|
||
final service = HomeWidgetService.instance;
|
||
await service.init();
|
||
await service.updateWidget(type);
|
||
final isDark =
|
||
PlatformDispatcher.instance.platformBrightness == Brightness.dark;
|
||
await service.pushThemeMode(isDark);
|
||
final newInstalled = {...state.installedWidgets, type};
|
||
state = state.copyWith(installedWidgets: newInstalled);
|
||
Log.i('WidgetNotifier: 添加小部件 ${type.title}');
|
||
} catch (e) {
|
||
Log.e('WidgetNotifier: 添加小部件失败', e);
|
||
state = state.copyWith(error: e.toString());
|
||
}
|
||
}
|
||
|
||
Future<void> removeWidget(WidgetType type) async {
|
||
final newInstalled = {...state.installedWidgets}..remove(type);
|
||
state = state.copyWith(installedWidgets: newInstalled);
|
||
Log.i('WidgetNotifier: 移除小部件 ${type.title}');
|
||
}
|
||
|
||
Future<PinWidgetResult> requestPinWidget(WidgetType type) async {
|
||
if (pu.isOhos) {
|
||
Log.w('WidgetNotifier: 鸿蒙端不支持快捷添加');
|
||
return PinWidgetResult.unsupported;
|
||
}
|
||
|
||
try {
|
||
await HomeWidget.requestPinWidget(
|
||
qualifiedAndroidName: type.qualifiedAndroidName,
|
||
androidName: type.androidProviderName,
|
||
);
|
||
Log.i('WidgetNotifier: 请求固定小部件 ${type.title}');
|
||
return PinWidgetResult.success;
|
||
} on PlatformException catch (e) {
|
||
Log.e('WidgetNotifier: 请求固定小部件 PlatformException', e);
|
||
if (e.code == 'not_supported' || e.code == 'ACTION_APPWIDGET_BIND') {
|
||
return PinWidgetResult.unsupported;
|
||
}
|
||
return PinWidgetResult.failed;
|
||
} catch (e) {
|
||
Log.e('WidgetNotifier: 请求固定小部件失败', e);
|
||
return PinWidgetResult.failed;
|
||
}
|
||
}
|
||
|
||
Future<void> pushDataToWidget(WidgetType type) async {
|
||
try {
|
||
final service = HomeWidgetService.instance;
|
||
await service.init();
|
||
await service.updateWidget(type);
|
||
Log.i('WidgetNotifier: 推送数据到小部件 ${type.title}');
|
||
} catch (e) {
|
||
Log.e('WidgetNotifier: 推送数据失败', e);
|
||
}
|
||
}
|
||
|
||
Future<void> pushThemeToAllWidgets() async {
|
||
try {
|
||
final service = HomeWidgetService.instance;
|
||
await service.init();
|
||
final isDark =
|
||
PlatformDispatcher.instance.platformBrightness == Brightness.dark;
|
||
await service.pushThemeMode(isDark);
|
||
for (final type in WidgetType.values) {
|
||
await service.updateWidget(type);
|
||
}
|
||
Log.i('WidgetNotifier: 已推送主题到所有小部件');
|
||
} catch (e) {
|
||
Log.e('WidgetNotifier: 推送主题失败', e);
|
||
}
|
||
}
|
||
}
|
||
|
||
final widgetProvider = NotifierProvider<WidgetNotifier, WidgetState>(
|
||
WidgetNotifier.new,
|
||
);
|