77 lines
2.8 KiB
Dart
77 lines
2.8 KiB
Dart
import 'dart:ui' as ui;
|
|
|
|
import 'package:flutter/services.dart' show rootBundle;
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../api/photo_api.dart';
|
|
import '../core/storage/local_storage.dart';
|
|
import '../models/photo.dart';
|
|
import '../models/watermark.dart';
|
|
|
|
/// 水印设置(全局共享,改动即落盘)
|
|
///
|
|
/// 跟项目里其他 provider 不同的一点:这个**不涉及网络**,纯粹是设备本地的偏好,
|
|
/// 所以直接读写 [LocalStorage],没有 api / 没有 refresh 失效那一套。
|
|
///
|
|
/// 需要 `LocalStorage.instance.init()` 已经跑过(`main.dart` 启动时做了)。
|
|
class WatermarkSettingsNotifier extends Notifier<WatermarkSettings> {
|
|
@override
|
|
WatermarkSettings build() {
|
|
final raw = LocalStorage.instance.getWatermarkSettings();
|
|
if (raw == null) return WatermarkSettings.defaults;
|
|
// 存坏了就当没存过,用默认值兜住 —— 不能让一段脏 JSON 把页面打不开
|
|
try {
|
|
return WatermarkSettings.fromJson(raw);
|
|
} catch (_) {
|
|
return WatermarkSettings.defaults;
|
|
}
|
|
}
|
|
|
|
/// 整体替换并落盘。设置页里改开关/颜色走这个。
|
|
void update(WatermarkSettings next) {
|
|
state = next;
|
|
LocalStorage.instance.saveWatermarkSettings(next.toJson());
|
|
}
|
|
|
|
/// 拖动过程中更新位置 —— **只改内存,不落盘**。
|
|
/// 拖一次会产生几十上百个事件,每个都写 SharedPreferences 太浪费。
|
|
void updatePosition(double x, double y) {
|
|
state = state.copyWith(posX: x, posY: y);
|
|
}
|
|
|
|
/// 松手时落盘。
|
|
void persistPosition() {
|
|
LocalStorage.instance.saveWatermarkSettings(state.toJson());
|
|
}
|
|
|
|
/// 回到默认位置(左下角)
|
|
void resetPosition() {
|
|
update(state.copyWith(posX: null, posY: null));
|
|
}
|
|
}
|
|
|
|
final watermarkSettingsProvider =
|
|
NotifierProvider<WatermarkSettingsNotifier, WatermarkSettings>(
|
|
WatermarkSettingsNotifier.new,
|
|
);
|
|
|
|
/// 品牌角标用的相机图标(原「水印相机」项目那张,白色描边 + 透明底)。
|
|
///
|
|
/// 画布要的是 `ui.Image`,不是 widget 用的 `AssetImage`,所以这里自己解码一次。
|
|
/// 不加 autoDispose:就一张小图,加载一次全程复用。
|
|
final brandIconProvider = FutureProvider<ui.Image>((ref) async {
|
|
final data = await rootBundle.load('assets/images/watermark_camera.png');
|
|
final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
|
|
final frame = await codec.getNextFrame();
|
|
codec.dispose();
|
|
return frame.image;
|
|
});
|
|
|
|
/// 首页水印卡片用:只想知道「一共几张、最近一张什么时候」。
|
|
///
|
|
/// 和 `noteOverviewProvider` 一个思路 —— 只取 1 条拿 total,
|
|
/// 不为了一个数字把列表页那套分页状态挂到首页上。
|
|
final photoOverviewProvider = FutureProvider.autoDispose<PhotoPage>((ref) {
|
|
return ref.watch(photoApiProvider).list(page: 1, size: 1);
|
|
});
|