Files
xianyan/lib/features/home/providers/quick_card_provider.dart
Developer 9ea8d3d606 chore: 汇总批量提交的功能优化与bug修复
本次提交包含多项迭代优化和问题修复:
1. 新增缩略图图片组件、数字格式化工具类,补充多语言翻译类型与本地化支持
2. 优化底部导航栏主题色统一使用动态accent色值
3. 修复多处图表动画、路由跳转、API请求相关问题
4. 简化服务器公告文案,调整默认分屏状态为关闭
5. 新增安卓/iOS桌面快捷方式配置
6. 重构多处状态管理类使用SafeNotifierInit统一异常保护
7. 替换硬编码蓝色为主题色,更新版本号获取方式为动态读取
8. 优化缓存预加载逻辑,移除无用代码
9. 调整默认设置项,优化用户体验细节
2026-05-31 12:24:05 +08:00

260 lines
8.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// 闲言APP — 快速卡片创作状态管理
// 创建时间: 2026-04-26
// 更新时间: 2026-05-31
// 作用: QuickCardSheet 专用状态 — 扩展自 MiniEditor
// 上次更新: 增加showWeather/locationText/usernameText/weatherText字段完善空壳功能
// ============================================================
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:xianyan/core/theme/app_colors.dart';
import 'package:xianyan/editor/models/editor_models.dart';
enum BarStyle { none, top, bottom, both }
enum CardPresetStyle {
none,
frostedGlass,
liquidGlass,
gradient,
meteor,
pureWhite,
}
enum ExportFormat { png, jpg }
class QuickCardState {
const QuickCardState({
required this.text,
this.fontSize = 28.0,
this.textColor = Colors.white,
this.fontFamily = 'Inter',
this.colorDepth = 0.5,
this.cardRatio = CanvasAspectRatio.ratio4_3,
this.barStyle = BarStyle.both,
this.background = const BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [LightColors.primary, LightColors.primaryDark],
gradientBegin: Alignment.topLeft,
gradientEnd: Alignment.bottomRight,
),
this.pinyinEnabled = true,
this.hapticEnabled = false,
this.autoPlayEnabled = false,
this.alwaysOnEnabled = false,
this.soundEnabled = false,
this.ttsEnabled = false,
this.appNameEnabled = true,
this.exportFormat = ExportFormat.png,
this.qrCodeEnabled = false,
this.presetStyle = CardPresetStyle.none,
this.textOffset = Offset.zero,
this.showTime = false,
this.showLocation = false,
this.showUsername = false,
this.showWeather = false,
this.locationText = '未知',
this.usernameText = '匿名',
this.weatherText = '',
this.autoPlayProgress = 1.0,
});
final String text;
final double fontSize;
final Color textColor;
final String fontFamily;
final double colorDepth;
final CanvasAspectRatio cardRatio;
final BarStyle barStyle;
final BackgroundLayer background;
final bool pinyinEnabled;
final bool hapticEnabled;
final bool autoPlayEnabled;
final bool alwaysOnEnabled;
final bool soundEnabled;
final bool ttsEnabled;
final bool appNameEnabled;
final ExportFormat exportFormat;
final bool qrCodeEnabled;
final CardPresetStyle presetStyle;
final Offset textOffset;
final bool showTime;
final bool showLocation;
final bool showUsername;
final bool showWeather;
final String locationText;
final String usernameText;
final String weatherText;
final double autoPlayProgress;
bool get hasBottomInfo =>
showTime || showLocation || showUsername || showWeather;
QuickCardState copyWith({
String? text,
double? fontSize,
Color? textColor,
String? fontFamily,
double? colorDepth,
CanvasAspectRatio? cardRatio,
BarStyle? barStyle,
BackgroundLayer? background,
bool? pinyinEnabled,
bool? hapticEnabled,
bool? autoPlayEnabled,
bool? alwaysOnEnabled,
bool? soundEnabled,
bool? ttsEnabled,
bool? appNameEnabled,
ExportFormat? exportFormat,
bool? qrCodeEnabled,
CardPresetStyle? presetStyle,
Offset? textOffset,
bool? showTime,
bool? showLocation,
bool? showUsername,
bool? showWeather,
String? locationText,
String? usernameText,
String? weatherText,
double? autoPlayProgress,
}) {
return QuickCardState(
text: text ?? this.text,
fontSize: fontSize ?? this.fontSize,
textColor: textColor ?? this.textColor,
fontFamily: fontFamily ?? this.fontFamily,
colorDepth: colorDepth ?? this.colorDepth,
cardRatio: cardRatio ?? this.cardRatio,
barStyle: barStyle ?? this.barStyle,
background: background ?? this.background,
pinyinEnabled: pinyinEnabled ?? this.pinyinEnabled,
hapticEnabled: hapticEnabled ?? this.hapticEnabled,
autoPlayEnabled: autoPlayEnabled ?? this.autoPlayEnabled,
alwaysOnEnabled: alwaysOnEnabled ?? this.alwaysOnEnabled,
soundEnabled: soundEnabled ?? this.soundEnabled,
ttsEnabled: ttsEnabled ?? this.ttsEnabled,
appNameEnabled: appNameEnabled ?? this.appNameEnabled,
exportFormat: exportFormat ?? this.exportFormat,
qrCodeEnabled: qrCodeEnabled ?? this.qrCodeEnabled,
presetStyle: presetStyle ?? this.presetStyle,
textOffset: textOffset ?? this.textOffset,
showTime: showTime ?? this.showTime,
showLocation: showLocation ?? this.showLocation,
showUsername: showUsername ?? this.showUsername,
showWeather: showWeather ?? this.showWeather,
locationText: locationText ?? this.locationText,
usernameText: usernameText ?? this.usernameText,
weatherText: weatherText ?? this.weatherText,
autoPlayProgress: autoPlayProgress ?? this.autoPlayProgress,
);
}
}
// ─── StateNotifier ───
class QuickCardNotifier extends Notifier<QuickCardState> {
@override
QuickCardState build() => const QuickCardState(text: '在此输入文字');
void updateText(String text) => state = state.copyWith(text: text);
void updateFontSize(double size) => state = state.copyWith(fontSize: size);
void updateTextColor(Color color) => state = state.copyWith(textColor: color);
void updateFontFamily(String family) =>
state = state.copyWith(fontFamily: family);
void updateColorDepth(double depth) =>
state = state.copyWith(colorDepth: depth);
void updateCardRatio(CanvasAspectRatio ratio) =>
state = state.copyWith(cardRatio: ratio);
void updateBarStyle(BarStyle style) =>
state = state.copyWith(barStyle: style);
void updateBackground(BackgroundLayer bg) =>
state = state.copyWith(background: bg);
void updateTextOffset(Offset offset) =>
state = state.copyWith(textOffset: offset);
void togglePinyin(bool v) => state = state.copyWith(pinyinEnabled: v);
void toggleHaptic(bool v) => state = state.copyWith(hapticEnabled: v);
void toggleAutoPlay(bool v) => state = state.copyWith(autoPlayEnabled: v);
void toggleAlwaysOn(bool v) => state = state.copyWith(alwaysOnEnabled: v);
void toggleSound(bool v) => state = state.copyWith(soundEnabled: v);
void toggleTts(bool v) => state = state.copyWith(ttsEnabled: v);
void toggleAppName(bool v) => state = state.copyWith(appNameEnabled: v);
void toggleQrCode(bool v) => state = state.copyWith(qrCodeEnabled: v);
void toggleShowTime(bool v) => state = state.copyWith(showTime: v);
void toggleShowLocation(bool v) => state = state.copyWith(showLocation: v);
void toggleShowUsername(bool v) => state = state.copyWith(showUsername: v);
void setExportFormat(ExportFormat f) =>
state = state.copyWith(exportFormat: f);
void applyPreset(CardPresetStyle preset) {
switch (preset) {
case CardPresetStyle.frostedGlass:
state = state.copyWith(
presetStyle: preset,
background: const BackgroundLayer(solidColor: Color(0xFF2C2C2E)),
textColor: Colors.white,
colorDepth: 0.3,
barStyle: BarStyle.both,
);
case CardPresetStyle.liquidGlass:
state = state.copyWith(
presetStyle: preset,
background: const BackgroundLayer(
type: BackgroundType.gradient,
gradientBegin: Alignment.topLeft,
gradientEnd: Alignment.bottomRight,
),
textColor: Colors.white,
colorDepth: 0.5,
barStyle: BarStyle.both,
);
case CardPresetStyle.gradient:
state = state.copyWith(
presetStyle: preset,
background: const BackgroundLayer(
type: BackgroundType.gradient,
gradientBegin: Alignment.topLeft,
gradientEnd: Alignment.bottomRight,
),
textColor: Colors.white,
colorDepth: 0.7,
barStyle: BarStyle.bottom,
);
case CardPresetStyle.meteor:
state = state.copyWith(
presetStyle: preset,
background: const BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [
Color(0xFF0f0c29),
Color(0xFF302b63),
Color(0xFF24243e),
],
),
textColor: const Color(0xFFE0E0FF),
colorDepth: 0.8,
barStyle: BarStyle.none,
);
case CardPresetStyle.pureWhite:
state = state.copyWith(
presetStyle: preset,
background: const BackgroundLayer(solidColor: Color(0xFFF8F8FA)),
textColor: const Color(0xFF1A1A2E),
colorDepth: 0.0,
barStyle: BarStyle.bottom,
);
case CardPresetStyle.none:
break;
}
}
}
// ─── Provider ───
final quickCardProvider = NotifierProvider<QuickCardNotifier, QuickCardState>(
QuickCardNotifier.new,
);