mirror of
https://github.com/ZhuJHua/moodiary.git
synced 2026-04-05 16:31:45 +08:00
refactor: streamline theme management and dynamic color support
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:moodiary/pages/home/setting/setting_logic.dart';
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
import 'package:moodiary/utils/theme_util.dart';
|
||||
import 'package:refreshed/refreshed.dart';
|
||||
|
||||
import 'color_dialog_state.dart';
|
||||
|
||||
class ColorDialogLogic extends GetxController {
|
||||
final ColorDialogState state = ColorDialogState();
|
||||
|
||||
late SettingLogic settingLogic = Bind.find<SettingLogic>();
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
//如果支持系统颜色,获取系统颜色
|
||||
if (state.supportDynamic) {
|
||||
state.systemColor = Color(PrefUtil.getValue<int>('systemColor')!);
|
||||
update();
|
||||
}
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
//更改主题色
|
||||
Future<void> changeSeedColor(index) async {
|
||||
await PrefUtil.setValue<int>('color', index);
|
||||
state.currentColor = index;
|
||||
settingLogic.state.color = index;
|
||||
update();
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.light));
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.dark));
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
|
||||
class ColorDialogState {
|
||||
bool supportDynamic = PrefUtil.getValue<bool>('supportDynamicColor')!;
|
||||
int currentColor = PrefUtil.getValue<int>('color')!;
|
||||
|
||||
Color? systemColor;
|
||||
|
||||
ColorDialogState();
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:moodiary/common/values/colors.dart';
|
||||
import 'package:moodiary/main.dart';
|
||||
import 'package:refreshed/refreshed.dart';
|
||||
|
||||
import 'color_dialog_logic.dart';
|
||||
|
||||
class ColorDialogComponent extends StatelessWidget {
|
||||
const ColorDialogComponent({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final logic = Get.put(ColorDialogLogic());
|
||||
final state = Bind.find<ColorDialogLogic>().state;
|
||||
|
||||
List<Widget> buildColorList() {
|
||||
return List.generate(AppColor.themeColorList.length, (index) {
|
||||
return SimpleDialogOption(
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
spacing: 10.0,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.circle,
|
||||
color: AppColor.themeColorList[index],
|
||||
),
|
||||
Text(AppColor.colorName(index)),
|
||||
if (state.currentColor == index) ...[const Icon(Icons.check)]
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
logic.changeSeedColor(index);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget buildSystemColor() {
|
||||
return SimpleDialogOption(
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
spacing: 10.0,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.circle,
|
||||
color: state.systemColor,
|
||||
),
|
||||
Text(l10n.colorNameSystem),
|
||||
if (state.currentColor == -1) ...[const Icon(Icons.check)]
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
logic.changeSeedColor(-1);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return GetBuilder<ColorDialogLogic>(
|
||||
assignId: true,
|
||||
builder: (_) {
|
||||
return SimpleDialog(
|
||||
title: Text(l10n.settingColor),
|
||||
children: [
|
||||
if (state.supportDynamic) ...[buildSystemColor()],
|
||||
...buildColorList()
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:moodiary/pages/home/setting/setting_logic.dart';
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
import 'package:moodiary/utils/theme_util.dart';
|
||||
@@ -12,29 +10,12 @@ class ColorSheetLogic extends GetxController {
|
||||
|
||||
late SettingLogic settingLogic = Bind.find<SettingLogic>();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
if (state.supportDynamic) {
|
||||
state.systemColor = Color(PrefUtil.getValue<int>('systemColor')!);
|
||||
}
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
int _counter = 0;
|
||||
|
||||
//更改主题色
|
||||
Future<void> changeSeedColor(index) async {
|
||||
await PrefUtil.setValue<int>('color', index);
|
||||
state.currentColor = index;
|
||||
settingLogic.state.color = index;
|
||||
_counter++;
|
||||
await ThemeUtil.forceUpdateTheme();
|
||||
update();
|
||||
}
|
||||
|
||||
void changeTheme() async {
|
||||
_counter--;
|
||||
if (_counter > 0) return;
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.light));
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.dark));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
|
||||
class ColorSheetState {
|
||||
bool supportDynamic = PrefUtil.getValue<bool>('supportDynamicColor')!;
|
||||
int currentColor = PrefUtil.getValue<int>('color')!;
|
||||
|
||||
Color? systemColor;
|
||||
|
||||
ColorSheetState();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:moodiary/common/values/colors.dart';
|
||||
import 'package:moodiary/components/base/marquee.dart';
|
||||
import 'package:moodiary/main.dart';
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
import 'package:moodiary/utils/theme_util.dart';
|
||||
import 'package:refreshed/refreshed.dart';
|
||||
|
||||
import 'color_sheet_logic.dart';
|
||||
@@ -19,27 +20,28 @@ class ColorSheetComponent extends StatelessWidget {
|
||||
required Brightness brightness,
|
||||
required TextStyle? textStyle,
|
||||
required VoidCallback onTap,
|
||||
required VoidCallback onEnd,
|
||||
required BoxConstraints constraints,
|
||||
bool isSystemColor = false,
|
||||
Color? systemColor,
|
||||
}) {
|
||||
if (isSystemColor) assert(systemColor != null);
|
||||
|
||||
final customColorScheme = ColorScheme.fromSeed(
|
||||
seedColor: (isSystemColor && systemColor != null)
|
||||
? systemColor
|
||||
: AppColor.themeColorList[realIndex],
|
||||
dynamicSchemeVariant: (realIndex == 0)
|
||||
? DynamicSchemeVariant.monochrome
|
||||
: DynamicSchemeVariant.tonalSpot,
|
||||
brightness: brightness);
|
||||
final customColorScheme =
|
||||
isSystemColor
|
||||
? (brightness == Brightness.light
|
||||
? ThemeUtil().lightDynamic!
|
||||
: ThemeUtil().darkDynamic!)
|
||||
: ColorScheme.fromSeed(
|
||||
seedColor: AppColor.themeColorList[realIndex],
|
||||
dynamicSchemeVariant:
|
||||
(realIndex == 0)
|
||||
? DynamicSchemeVariant.monochrome
|
||||
: DynamicSchemeVariant.tonalSpot,
|
||||
brightness: brightness,
|
||||
);
|
||||
|
||||
final textPainter = TextPainter(
|
||||
text: TextSpan(text: AppColor.colorName(realIndex), style: textStyle),
|
||||
textDirection: TextDirection.ltr,
|
||||
textScaler: TextScaler.linear(PrefUtil.getValue<double>('fontScale')!))
|
||||
..layout();
|
||||
text: TextSpan(text: AppColor.colorName(realIndex), style: textStyle),
|
||||
textDirection: TextDirection.ltr,
|
||||
textScaler: TextScaler.linear(PrefUtil.getValue<double>('fontScale')!),
|
||||
)..layout();
|
||||
final showMarquee = textPainter.width > constraints.maxWidth - 8.0;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
@@ -57,52 +59,60 @@ class ColorSheetComponent extends StatelessWidget {
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedPositioned(
|
||||
left: currentColor == realIndex
|
||||
? 6
|
||||
: (constraints.maxWidth / 2 - textPainter.width / 2 - 4.0),
|
||||
bottom: currentColor == realIndex
|
||||
? 6
|
||||
: (constraints.maxHeight / 2 -
|
||||
textPainter.height / 2 -
|
||||
4.0),
|
||||
left:
|
||||
currentColor == realIndex
|
||||
? 6
|
||||
: (constraints.maxWidth / 2 -
|
||||
textPainter.width / 2 -
|
||||
4.0),
|
||||
bottom:
|
||||
currentColor == realIndex
|
||||
? 6
|
||||
: (constraints.maxHeight / 2 -
|
||||
textPainter.height / 2 -
|
||||
4.0),
|
||||
duration: const Duration(milliseconds: 300),
|
||||
onEnd: onEnd,
|
||||
child: showMarquee
|
||||
? SizedBox(
|
||||
height: textPainter.height,
|
||||
width: constraints.maxWidth - 8.0,
|
||||
child: Marquee(
|
||||
text: AppColor.colorName(realIndex),
|
||||
velocity: 20,
|
||||
blankSpace: 20,
|
||||
pauseAfterRound: const Duration(seconds: 1),
|
||||
accelerationDuration: const Duration(seconds: 1),
|
||||
accelerationCurve: Curves.linear,
|
||||
decelerationDuration:
|
||||
const Duration(milliseconds: 500),
|
||||
decelerationCurve: Curves.easeOut,
|
||||
child:
|
||||
showMarquee
|
||||
? SizedBox(
|
||||
height: textPainter.height,
|
||||
width: constraints.maxWidth - 8.0,
|
||||
child: Marquee(
|
||||
text: AppColor.colorName(realIndex),
|
||||
velocity: 20,
|
||||
blankSpace: 20,
|
||||
pauseAfterRound: const Duration(seconds: 1),
|
||||
accelerationDuration: const Duration(seconds: 1),
|
||||
accelerationCurve: Curves.linear,
|
||||
decelerationDuration: const Duration(
|
||||
milliseconds: 500,
|
||||
),
|
||||
decelerationCurve: Curves.easeOut,
|
||||
style: textStyle?.copyWith(
|
||||
color: customColorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
AppColor.colorName(realIndex),
|
||||
style: textStyle?.copyWith(
|
||||
color: customColorScheme.onPrimary),
|
||||
color: customColorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
AppColor.colorName(realIndex),
|
||||
style: textStyle?.copyWith(
|
||||
color: customColorScheme.onPrimary),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 6,
|
||||
right: 6,
|
||||
child: AnimatedOpacity(
|
||||
opacity: currentColor == realIndex ? 1 : 0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Icon(
|
||||
Icons.check_circle,
|
||||
size: 12,
|
||||
color: customColorScheme.onPrimary,
|
||||
)),
|
||||
)
|
||||
opacity: currentColor == realIndex ? 1 : 0,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: Icon(
|
||||
Icons.check_circle,
|
||||
size: 12,
|
||||
color: customColorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -119,20 +129,18 @@ class ColorSheetComponent extends StatelessWidget {
|
||||
|
||||
// 绘制普通配色
|
||||
Widget buildCommonColor() {
|
||||
final hasSystemColor = state.supportDynamic && state.systemColor != null;
|
||||
final itemCount = hasSystemColor
|
||||
? AppColor.themeColorList.length + 1
|
||||
: AppColor.themeColorList.length;
|
||||
final hasSystemColor = ThemeUtil().supportDynamic;
|
||||
final itemCount =
|
||||
hasSystemColor
|
||||
? AppColor.themeColorList.length + 1
|
||||
: AppColor.themeColorList.length;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
l10n.colorCommon,
|
||||
style: textStyle.titleMedium,
|
||||
),
|
||||
child: Text(l10n.colorCommon, style: textStyle.titleMedium),
|
||||
),
|
||||
GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
@@ -144,20 +152,21 @@ class ColorSheetComponent extends StatelessWidget {
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, index) {
|
||||
final realIndex = hasSystemColor ? index - 1 : index;
|
||||
return LayoutBuilder(builder: (context, constraints) {
|
||||
return buildColorOption(
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return buildColorOption(
|
||||
currentColor: state.currentColor,
|
||||
realIndex: realIndex,
|
||||
brightness: colorScheme.brightness,
|
||||
textStyle: textStyle.labelMedium,
|
||||
isSystemColor: realIndex == -1,
|
||||
systemColor: state.systemColor,
|
||||
constraints: constraints,
|
||||
onTap: () {
|
||||
logic.changeSeedColor(realIndex);
|
||||
},
|
||||
onEnd: logic.changeTheme);
|
||||
});
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
itemCount: itemCount,
|
||||
),
|
||||
|
||||
133
lib/main.dart
133
lib/main.dart
@@ -23,7 +23,6 @@ import 'package:moodiary/router/app_routes.dart';
|
||||
import 'package:moodiary/src/rust/frb_generated.dart';
|
||||
import 'package:moodiary/utils/log_util.dart';
|
||||
import 'package:moodiary/utils/media_util.dart';
|
||||
import 'package:moodiary/utils/notice_util.dart';
|
||||
import 'package:moodiary/utils/theme_util.dart';
|
||||
import 'package:moodiary/utils/webdav_util.dart';
|
||||
import 'package:refreshed/refreshed.dart';
|
||||
@@ -39,16 +38,23 @@ Future<void> _initSystem() async {
|
||||
await RustLib.init();
|
||||
await PrefUtil.initPref();
|
||||
await IsarUtil.initIsar();
|
||||
await ThemeUtil().buildTheme();
|
||||
await WebDavUtil().initWebDav();
|
||||
VideoPlayerMediaKit.ensureInitialized(
|
||||
android: true, iOS: true, macOS: true, windows: true);
|
||||
android: true,
|
||||
iOS: true,
|
||||
macOS: true,
|
||||
windows: true,
|
||||
);
|
||||
await FMTCObjectBoxBackend().initialise();
|
||||
await const FMTCStore('mapStore').manage.create();
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
systemNavigationBarContrastEnforced: false,
|
||||
));
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
const SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
systemNavigationBarContrastEnforced: false,
|
||||
),
|
||||
);
|
||||
await _findLanguage();
|
||||
await _platFormOption();
|
||||
}
|
||||
@@ -60,9 +66,10 @@ Future<void> _findLanguage() async {
|
||||
);
|
||||
if (language == Language.system) {
|
||||
final systemLocale = await findSystemLocale();
|
||||
final systemLanguageCode = systemLocale.contains('_')
|
||||
? systemLocale.split('_').first
|
||||
: systemLocale;
|
||||
final systemLanguageCode =
|
||||
systemLocale.contains('_')
|
||||
? systemLocale.split('_').first
|
||||
: systemLocale;
|
||||
language = Language.values.firstWhere(
|
||||
(e) => e.languageCode == systemLanguageCode,
|
||||
orElse: () => Language.english,
|
||||
@@ -96,71 +103,61 @@ String _getInitialRoute() {
|
||||
void main() async {
|
||||
await _initSystem();
|
||||
FlutterError.onError = (details) {
|
||||
LogUtil.printError('Flutter error',
|
||||
error: details.exception, stackTrace: details.stack);
|
||||
if (details.exceptionAsString().contains('Render')) {
|
||||
// NoticeUtil.showBug(
|
||||
// message:
|
||||
// Env.debugMode ? details.exceptionAsString() : l10n.layoutErrorToast,
|
||||
// );
|
||||
} else {
|
||||
// NoticeUtil.showBug(
|
||||
// message: Env.debugMode ? details.exceptionAsString() : l10n.errorToast,
|
||||
// );
|
||||
}
|
||||
LogUtil.printError(
|
||||
'Flutter error',
|
||||
error: details.exception,
|
||||
stackTrace: details.stack,
|
||||
);
|
||||
};
|
||||
PlatformDispatcher.instance.onError = (error, stack) {
|
||||
LogUtil.printWTF('Error', error: error, stackTrace: stack);
|
||||
NoticeUtil.showBug(
|
||||
message: Env.debugMode ? error.toString() : l10n.errorToast,
|
||||
);
|
||||
return true;
|
||||
};
|
||||
runApp(GetMaterialApp.router(
|
||||
routeInformationParser: GetInformationParser.createInformationParser(
|
||||
initialRoute: _getInitialRoute(),
|
||||
final themeData = ThemeUtil().getThemeData();
|
||||
runApp(
|
||||
GetMaterialApp.router(
|
||||
routeInformationParser: GetInformationParser.createInformationParser(
|
||||
initialRoute: _getInitialRoute(),
|
||||
),
|
||||
onGenerateTitle: (context) => AppLocalizations.of(context)!.appName,
|
||||
backButtonDispatcher: GetRootBackButtonDispatcher(),
|
||||
builder: (context, child) {
|
||||
l10n = AppLocalizations.of(context)!;
|
||||
final mediaQuery = MediaQuery(
|
||||
data: MediaQuery.of(context).copyWith(
|
||||
textScaler: TextScaler.linear(
|
||||
PrefUtil.getValue<double>('fontScale')!,
|
||||
),
|
||||
),
|
||||
child: FToastBuilder()(context, child!),
|
||||
);
|
||||
return Stack(
|
||||
children: [
|
||||
mediaQuery,
|
||||
const FrostedGlassOverlayComponent(),
|
||||
if (Env.debugMode)
|
||||
const Positioned(
|
||||
top: -15,
|
||||
right: -15,
|
||||
child: EnvBadge(envMode: '测试版'),
|
||||
),
|
||||
if (Platform.isWindows || Platform.isMacOS || Platform.isLinux)
|
||||
const Positioned(top: 0, left: 0, right: 0, child: MoveTitle()),
|
||||
],
|
||||
);
|
||||
},
|
||||
theme: themeData.$1,
|
||||
darkTheme: themeData.$2,
|
||||
locale: locale,
|
||||
themeMode: ThemeMode.values[PrefUtil.getValue<int>('themeMode')!],
|
||||
getPages: AppPages.routes,
|
||||
localizationsDelegates: const [
|
||||
...AppLocalizations.localizationsDelegates,
|
||||
FlutterQuillLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
),
|
||||
onGenerateTitle: (context) => AppLocalizations.of(context)!.appName,
|
||||
backButtonDispatcher: GetRootBackButtonDispatcher(),
|
||||
builder: (context, child) {
|
||||
l10n = AppLocalizations.of(context)!;
|
||||
final mediaQuery = MediaQuery(
|
||||
data: MediaQuery.of(context).copyWith(
|
||||
textScaler:
|
||||
TextScaler.linear(PrefUtil.getValue<double>('fontScale')!)),
|
||||
child: FToastBuilder()(context, child!),
|
||||
);
|
||||
return Stack(
|
||||
children: [
|
||||
mediaQuery,
|
||||
const FrostedGlassOverlayComponent(),
|
||||
if (Env.debugMode)
|
||||
const Positioned(
|
||||
top: -15,
|
||||
right: -15,
|
||||
child: EnvBadge(envMode: '测试版'),
|
||||
),
|
||||
if (Platform.isWindows || Platform.isMacOS || Platform.isLinux)
|
||||
const Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: MoveTitle(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
theme: await ThemeUtil.buildTheme(Brightness.light),
|
||||
darkTheme: await ThemeUtil.buildTheme(Brightness.dark),
|
||||
locale: locale,
|
||||
themeMode: ThemeMode.values[PrefUtil.getValue<int>('themeMode')!],
|
||||
getPages: AppPages.routes,
|
||||
localizationsDelegates: const [
|
||||
...AppLocalizations.localizationsDelegates,
|
||||
FlutterQuillLocalizations.delegate
|
||||
],
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
class GetRootBackButtonDispatcher extends BackButtonDispatcher
|
||||
|
||||
@@ -27,8 +27,10 @@ class FontLogic extends GetxController with GetSingleTickerProviderStateMixin {
|
||||
|
||||
void onVerticalDragStart(DragUpdateDetails details) {
|
||||
state.bottomSheetHeight.value -= details.delta.dy;
|
||||
state.bottomSheetHeight.value =
|
||||
state.bottomSheetHeight.value.clamp(state.minHeight, state.maxHeight);
|
||||
state.bottomSheetHeight.value = state.bottomSheetHeight.value.clamp(
|
||||
state.minHeight,
|
||||
state.maxHeight,
|
||||
);
|
||||
}
|
||||
|
||||
void changeSelectedFont({Font? font}) async {
|
||||
@@ -45,10 +47,12 @@ class FontLogic extends GetxController with GetSingleTickerProviderStateMixin {
|
||||
state.fontList.value = await IsarUtil.getAllFonts();
|
||||
final loadList = <Future>[];
|
||||
for (final font in state.fontList) {
|
||||
loadList.add(FontUtil.loadFont(
|
||||
fontName: font.fontFamily,
|
||||
fontPath: FileUtil.getRealPath('font', font.fontFileName),
|
||||
));
|
||||
loadList.add(
|
||||
FontUtil.loadFont(
|
||||
fontName: font.fontFamily,
|
||||
fontPath: FileUtil.getRealPath('font', font.fontFileName),
|
||||
),
|
||||
);
|
||||
}
|
||||
await Future.wait(loadList);
|
||||
state.isFetching.value = false;
|
||||
@@ -90,9 +94,11 @@ class FontLogic extends GetxController with GetSingleTickerProviderStateMixin {
|
||||
//更改字体
|
||||
Future<void> changeFontTheme() async {
|
||||
await PrefUtil.setValue<String>(
|
||||
'customFont', state.currentFontFamily.value);
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.light));
|
||||
Get.changeTheme(await ThemeUtil.buildTheme(Brightness.dark));
|
||||
'customFont',
|
||||
state.currentFontFamily.value,
|
||||
);
|
||||
await ThemeUtil.forceUpdateTheme();
|
||||
|
||||
EllipsisText.clearCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:moodiary/merge/merge.dart';
|
||||
import 'package:moodiary/utils/auth_util.dart';
|
||||
import 'package:moodiary/utils/file_util.dart';
|
||||
import 'package:moodiary/utils/package_util.dart';
|
||||
import 'package:moodiary/utils/theme_util.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
@@ -19,10 +18,6 @@ class PrefUtil {
|
||||
'firstStart',
|
||||
//自动同步
|
||||
'autoSync',
|
||||
//动态配色支持
|
||||
'supportDynamicColor',
|
||||
//当前系统颜色
|
||||
'systemColor',
|
||||
//主题颜色
|
||||
'color',
|
||||
//主题颜色类型
|
||||
@@ -100,8 +95,10 @@ class PrefUtil {
|
||||
|
||||
static Future<void> initPref() async {
|
||||
_prefs = await SharedPreferencesWithCache.create(
|
||||
cacheOptions:
|
||||
const SharedPreferencesWithCacheOptions(allowList: allowList));
|
||||
cacheOptions: const SharedPreferencesWithCacheOptions(
|
||||
allowList: allowList,
|
||||
),
|
||||
);
|
||||
// 首次启动
|
||||
final firstStart = _prefs.getBool('firstStart') ?? true;
|
||||
await _prefs.setBool('firstStart', firstStart);
|
||||
@@ -129,30 +126,19 @@ class PrefUtil {
|
||||
|
||||
/// 支持相关,每次都重新获取
|
||||
await _prefs.setBool(
|
||||
'supportBiometrics', await AuthUtil.canCheckBiometrics());
|
||||
|
||||
final supportDynamicColor = await ThemeUtil.supportDynamicColor();
|
||||
await _prefs.setBool('supportDynamicColor', supportDynamicColor);
|
||||
|
||||
if (supportDynamicColor) {
|
||||
final color = await ThemeUtil.getDynamicColor();
|
||||
await _prefs.setInt(
|
||||
'systemColor',
|
||||
((color.a * 255).toInt() << 24) |
|
||||
((color.r * 255).toInt() << 16) |
|
||||
((color.g * 255).toInt() << 8) |
|
||||
(color.b * 255).toInt());
|
||||
}
|
||||
'supportBiometrics',
|
||||
await AuthUtil.canCheckBiometrics(),
|
||||
);
|
||||
|
||||
await _prefs.setInt(
|
||||
'color',
|
||||
_prefs.getInt('color') ??
|
||||
(await ThemeUtil.supportDynamicColor() ? -1 : 0));
|
||||
await _prefs.setInt(
|
||||
'colorType', _prefs.getInt('colorType') ?? AppColorType.common.value);
|
||||
'colorType',
|
||||
_prefs.getInt('colorType') ?? AppColorType.common.value,
|
||||
);
|
||||
await _prefs.setInt('themeMode', _prefs.getInt('themeMode') ?? 0);
|
||||
await _prefs.setBool(
|
||||
'dynamicColor', _prefs.getBool('dynamicColor') ?? true);
|
||||
'dynamicColor',
|
||||
_prefs.getBool('dynamicColor') ?? true,
|
||||
);
|
||||
await _prefs.setInt('quality', _prefs.getInt('quality') ?? 2);
|
||||
await _prefs.setBool('local', _prefs.getBool('local') ?? false);
|
||||
await _prefs.setBool('lock', _prefs.getBool('lock') ?? false);
|
||||
@@ -162,38 +148,66 @@ class PrefUtil {
|
||||
|
||||
/// 支持相关,重新获取
|
||||
await _prefs.setString(
|
||||
'supportPath', (await getApplicationSupportDirectory()).path);
|
||||
'supportPath',
|
||||
(await getApplicationSupportDirectory()).path,
|
||||
);
|
||||
await _prefs.setString(
|
||||
'cachePath', (await getApplicationCacheDirectory()).path);
|
||||
'cachePath',
|
||||
(await getApplicationCacheDirectory()).path,
|
||||
);
|
||||
|
||||
await _prefs.setBool('getWeather', _prefs.getBool('getWeather') ?? false);
|
||||
await _prefs.setInt('startTime',
|
||||
_prefs.getInt('startTime') ?? DateTime.now().millisecondsSinceEpoch);
|
||||
await _prefs.setInt(
|
||||
'startTime',
|
||||
_prefs.getInt('startTime') ?? DateTime.now().millisecondsSinceEpoch,
|
||||
);
|
||||
await _prefs.setString(
|
||||
'customTitleName', _prefs.getString('customTitleName') ?? '');
|
||||
await _prefs.setInt('homeViewMode',
|
||||
_prefs.getInt('homeViewMode') ?? ViewModeType.list.number);
|
||||
'customTitleName',
|
||||
_prefs.getString('customTitleName') ?? '',
|
||||
);
|
||||
await _prefs.setInt(
|
||||
'homeViewMode',
|
||||
_prefs.getInt('homeViewMode') ?? ViewModeType.list.number,
|
||||
);
|
||||
await _prefs.setBool('autoWeather', _prefs.getBool('autoWeather') ?? false);
|
||||
await _prefs.setStringList(
|
||||
'webDavOption', _prefs.getStringList('webDavOption') ?? []);
|
||||
'webDavOption',
|
||||
_prefs.getStringList('webDavOption') ?? [],
|
||||
);
|
||||
await _prefs.setBool('diaryHeader', _prefs.getBool('diaryHeader') ?? true);
|
||||
await _prefs.setBool(
|
||||
'firstLineIndent', _prefs.getBool('firstLineIndent') ?? false);
|
||||
'firstLineIndent',
|
||||
_prefs.getBool('firstLineIndent') ?? false,
|
||||
);
|
||||
await _prefs.setBool(
|
||||
'autoCategory', _prefs.getBool('autoCategory') ?? false);
|
||||
'autoCategory',
|
||||
_prefs.getBool('autoCategory') ?? false,
|
||||
);
|
||||
await _prefs.setBool(
|
||||
'showWritingTime', _prefs.getBool('showWritingTime') ?? true);
|
||||
'showWritingTime',
|
||||
_prefs.getBool('showWritingTime') ?? true,
|
||||
);
|
||||
await _prefs.setBool(
|
||||
'showWordCount', _prefs.getBool('showWordCount') ?? true);
|
||||
'showWordCount',
|
||||
_prefs.getBool('showWordCount') ?? true,
|
||||
);
|
||||
await _prefs.setString('customFont', _prefs.getString('customFont') ?? '');
|
||||
await _prefs.setBool(
|
||||
'backendPrivacy', _prefs.getBool('backendPrivacy') ?? true);
|
||||
'backendPrivacy',
|
||||
_prefs.getBool('backendPrivacy') ?? true,
|
||||
);
|
||||
await _prefs.setBool(
|
||||
'autoSyncAfterChange', _prefs.getBool('autoSyncAfterChange') ?? false);
|
||||
'autoSyncAfterChange',
|
||||
_prefs.getBool('autoSyncAfterChange') ?? false,
|
||||
);
|
||||
await _prefs.setString(
|
||||
'language', _prefs.getString('language') ?? 'system');
|
||||
'language',
|
||||
_prefs.getString('language') ?? 'system',
|
||||
);
|
||||
await _prefs.setBool(
|
||||
'syncEncryption', _prefs.getBool('syncEncryption') ?? false);
|
||||
'syncEncryption',
|
||||
_prefs.getBool('syncEncryption') ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> setValue<T>(String key, T value) async {
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dartx/dartx.dart';
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart';
|
||||
import 'package:flutter_quill/internal.dart';
|
||||
import 'package:material_color_utilities/palettes/core_palette.dart';
|
||||
import 'package:moodiary/common/values/colors.dart';
|
||||
import 'package:moodiary/presentation/isar.dart';
|
||||
import 'package:moodiary/presentation/pref.dart';
|
||||
import 'package:moodiary/utils/file_util.dart';
|
||||
import 'package:moodiary/utils/font_util.dart';
|
||||
import 'package:moodiary/utils/log_util.dart';
|
||||
import 'package:refreshed/refreshed.dart';
|
||||
|
||||
class ThemeUtil {
|
||||
static Future<bool> supportDynamicColor() async {
|
||||
return (await DynamicColorPlugin.getCorePalette()) != null;
|
||||
}
|
||||
ThemeUtil._();
|
||||
|
||||
static Future<Color> getDynamicColor() async {
|
||||
return Color((await DynamicColorPlugin.getCorePalette())!.primary.get(40));
|
||||
}
|
||||
static final ThemeUtil instance = ThemeUtil._();
|
||||
|
||||
static Map<String, double> _unifyFontWeights(
|
||||
Map<String, double> fontWeights,
|
||||
) {
|
||||
factory ThemeUtil() => instance;
|
||||
|
||||
// 亮色模式的主题缓存
|
||||
ThemeData? _lightTheme;
|
||||
|
||||
// 暗色模式的主题缓存
|
||||
ThemeData? _darkTheme;
|
||||
|
||||
// 字体的字重缓存
|
||||
Map<String, double> wghtAxisMap = {};
|
||||
|
||||
// 动态配色的浅色主题
|
||||
ColorScheme? lightDynamic;
|
||||
|
||||
// 动态配色的深色主题
|
||||
ColorScheme? darkDynamic;
|
||||
|
||||
bool get supportDynamic => lightDynamic != null && darkDynamic != null;
|
||||
|
||||
// 字体的名称缓存
|
||||
String? fontFamily;
|
||||
|
||||
Map<String, double> _unifyFontWeights(Map<String, double> fontWeights) {
|
||||
// 标准
|
||||
final regular = fontWeights['default'] ?? 400;
|
||||
// 名称映射表:将各种名称映射到统一的标准名称
|
||||
@@ -69,11 +90,7 @@ class ThemeUtil {
|
||||
return unified;
|
||||
}
|
||||
|
||||
static TextTheme _applyFontVariations(
|
||||
TextTheme baseTheme,
|
||||
String? fontFamily, {
|
||||
required Map<String, double> wghtAxisMap,
|
||||
}) {
|
||||
TextTheme _applyFontVariations(TextTheme baseTheme) {
|
||||
final regularFontWeight = wghtAxisMap['Regular'] ?? 400;
|
||||
final mediumFontWeight = wghtAxisMap['Medium'] ?? 500;
|
||||
final semiBoldFontWeight = wghtAxisMap['SemiBold'] ?? 600;
|
||||
@@ -157,23 +174,49 @@ class ThemeUtil {
|
||||
);
|
||||
}
|
||||
|
||||
static Future<ThemeData> buildTheme(Brightness brightness) async {
|
||||
final color = PrefUtil.getValue<int>('color')!;
|
||||
final seedColor =
|
||||
(color == -1)
|
||||
? Color(PrefUtil.getValue<int>('systemColor')!)
|
||||
: AppColor.themeColorList[(color >= 0 &&
|
||||
color < AppColor.themeColorList.length)
|
||||
? color
|
||||
: 0];
|
||||
/// 构建主题
|
||||
/// 第一个返回值为亮色主题,第二个为暗色主题
|
||||
Future<void> buildTheme() async {
|
||||
await findDynamicColor();
|
||||
|
||||
final customFont = PrefUtil.getValue<String>('customFont')!;
|
||||
String? fontFamily;
|
||||
Map<String, double> wghtAxisMap = {};
|
||||
var color = PrefUtil.getValue<int>('color');
|
||||
|
||||
// 如果是首次打开软件,还没有设置配色,检查是否支持动态配色
|
||||
if (color == null) {
|
||||
// 如果支持动态配色,设置为动态配色
|
||||
if (supportDynamic) {
|
||||
PrefUtil.setValue('color', -1);
|
||||
color = -1;
|
||||
} else {
|
||||
// 否则设置为默认配色
|
||||
PrefUtil.setValue('color', 0);
|
||||
color = 0;
|
||||
}
|
||||
}
|
||||
|
||||
final isDynamic = color == -1 && supportDynamic;
|
||||
|
||||
late final normalColor =
|
||||
AppColor.themeColorList[(color! >= 0 &&
|
||||
color < AppColor.themeColorList.length)
|
||||
? color
|
||||
: 0];
|
||||
|
||||
final lightColorScheme =
|
||||
isDynamic
|
||||
? lightDynamic!
|
||||
: buildColorScheme(normalColor, Brightness.light, color);
|
||||
|
||||
final darkColorScheme =
|
||||
isDynamic
|
||||
? darkDynamic!
|
||||
: buildColorScheme(normalColor, Brightness.dark, color);
|
||||
|
||||
final customFont = PrefUtil.getValue<String>('customFont');
|
||||
|
||||
// 加载自定义字体
|
||||
if (customFont.isNotEmpty) {
|
||||
final font = await IsarUtil.getFontByFontFamily(customFont);
|
||||
if (customFont.isNotNullOrBlank) {
|
||||
final font = await IsarUtil.getFontByFontFamily(customFont!);
|
||||
if (font != null) {
|
||||
await FontUtil.loadFont(
|
||||
fontName: font.fontFamily,
|
||||
@@ -188,23 +231,77 @@ class ThemeUtil {
|
||||
fontFamily = 'Microsoft Yahei UI';
|
||||
}
|
||||
|
||||
// colorScheme
|
||||
final colorScheme = ColorScheme.fromSeed(
|
||||
final lightTextTheme = buildTextTheme(lightColorScheme);
|
||||
final darkTextTheme = buildTextTheme(darkColorScheme);
|
||||
|
||||
final lightTypography = buildTypography(lightColorScheme);
|
||||
final darkTypography = buildTypography(darkColorScheme);
|
||||
|
||||
_lightTheme = buildThemeData(
|
||||
lightColorScheme,
|
||||
lightTextTheme,
|
||||
lightTypography,
|
||||
fontFamily,
|
||||
wghtAxisMap,
|
||||
Brightness.light,
|
||||
);
|
||||
_darkTheme = buildThemeData(
|
||||
darkColorScheme,
|
||||
darkTextTheme,
|
||||
darkTypography,
|
||||
fontFamily,
|
||||
wghtAxisMap,
|
||||
Brightness.dark,
|
||||
);
|
||||
}
|
||||
|
||||
// 辅助函数:构建 colorScheme
|
||||
ColorScheme buildColorScheme(
|
||||
Color seedColor,
|
||||
Brightness brightness,
|
||||
int color,
|
||||
) {
|
||||
// 默认的配色生成算法,这个会生成低饱和度的配色
|
||||
var dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot;
|
||||
if (color == 0) {
|
||||
dynamicSchemeVariant = DynamicSchemeVariant.monochrome;
|
||||
}
|
||||
if (color == -1) {
|
||||
dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot;
|
||||
}
|
||||
return ColorScheme.fromSeed(
|
||||
seedColor: seedColor,
|
||||
brightness: brightness,
|
||||
dynamicSchemeVariant:
|
||||
color == 0
|
||||
? DynamicSchemeVariant.monochrome
|
||||
: DynamicSchemeVariant.tonalSpot,
|
||||
);
|
||||
// typography
|
||||
final typography = Typography.material2021(
|
||||
dynamicSchemeVariant: dynamicSchemeVariant,
|
||||
).harmonized();
|
||||
}
|
||||
|
||||
// 辅助函数:构建 typography
|
||||
Typography buildTypography(ColorScheme colorScheme) {
|
||||
return Typography.material2021(
|
||||
platform: defaultTargetPlatform,
|
||||
colorScheme: colorScheme,
|
||||
);
|
||||
final defaultTextTheme =
|
||||
brightness == Brightness.light ? typography.black : typography.white;
|
||||
}
|
||||
|
||||
TextTheme buildTextTheme(ColorScheme colorScheme) {
|
||||
final typography = buildTypography(colorScheme);
|
||||
final textTheme =
|
||||
colorScheme.brightness == Brightness.light
|
||||
? typography.black
|
||||
: typography.white;
|
||||
return _applyFontVariations(textTheme);
|
||||
}
|
||||
|
||||
// 辅助函数:构建 ThemeData
|
||||
ThemeData buildThemeData(
|
||||
ColorScheme colorScheme,
|
||||
TextTheme textTheme,
|
||||
Typography typography,
|
||||
String? fontFamily,
|
||||
Map<String, double> wghtAxisMap,
|
||||
Brightness brightness,
|
||||
) {
|
||||
return ThemeData(
|
||||
colorScheme: colorScheme,
|
||||
materialTapTargetSize: MaterialTapTargetSize.padded,
|
||||
@@ -220,14 +317,76 @@ class ThemeUtil {
|
||||
backgroundColor: colorScheme.surface,
|
||||
),
|
||||
fontFamily: fontFamily,
|
||||
textTheme: _applyFontVariations(
|
||||
defaultTextTheme,
|
||||
fontFamily,
|
||||
wghtAxisMap: wghtAxisMap,
|
||||
),
|
||||
typography: typography,
|
||||
textTheme: _applyFontVariations(textTheme),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> findDynamicColor() async {
|
||||
try {
|
||||
final CorePalette? corePalette =
|
||||
await DynamicColorPlugin.getCorePalette();
|
||||
|
||||
if (corePalette != null) {
|
||||
final seedColor = Color(corePalette.primary.get(40));
|
||||
|
||||
lightDynamic = buildColorScheme(seedColor, Brightness.light, -1);
|
||||
darkDynamic = buildColorScheme(seedColor, Brightness.dark, -1);
|
||||
return;
|
||||
}
|
||||
} on PlatformException {
|
||||
LogUtil.printInfo('dynamic_color: Failed to obtain core palette.');
|
||||
}
|
||||
|
||||
try {
|
||||
final Color? accentColor = await DynamicColorPlugin.getAccentColor();
|
||||
|
||||
if (accentColor != null) {
|
||||
lightDynamic = buildColorScheme(accentColor, Brightness.light, -1);
|
||||
darkDynamic = buildColorScheme(accentColor, Brightness.dark, -1);
|
||||
return;
|
||||
}
|
||||
} on PlatformException {
|
||||
LogUtil.printInfo('dynamic_color: Failed to obtain accent color.');
|
||||
}
|
||||
|
||||
LogUtil.printInfo(
|
||||
'dynamic_color: Dynamic color not detected on this device.',
|
||||
);
|
||||
}
|
||||
|
||||
(ThemeData, ThemeData) getThemeData() {
|
||||
final isDynamic = supportDynamic && PrefUtil.getValue<int>('color') == -1;
|
||||
if (isDynamic) {
|
||||
return (
|
||||
_lightTheme?.copyWith(
|
||||
colorScheme: lightDynamic,
|
||||
textTheme: buildTextTheme(lightDynamic!),
|
||||
typography: buildTypography(lightDynamic!),
|
||||
) ??
|
||||
ThemeData.light(),
|
||||
_darkTheme?.copyWith(
|
||||
colorScheme: darkDynamic,
|
||||
textTheme: buildTextTheme(darkDynamic!),
|
||||
typography: buildTypography(darkDynamic!),
|
||||
) ??
|
||||
ThemeData.dark(),
|
||||
);
|
||||
} else {
|
||||
return (_lightTheme ?? ThemeData.light(), _darkTheme ?? ThemeData.dark());
|
||||
}
|
||||
}
|
||||
|
||||
/// 强制更新主题
|
||||
/// 一般在更改了主题色或者字体后调用
|
||||
static Future<void> forceUpdateTheme() async {
|
||||
await ThemeUtil().buildTheme();
|
||||
final themeData = ThemeUtil().getThemeData();
|
||||
Get.changeTheme(themeData.$1);
|
||||
Get.changeTheme(themeData.$2);
|
||||
await Get.forceAppUpdate();
|
||||
}
|
||||
|
||||
static DefaultStyles getInstance(
|
||||
BuildContext context, {
|
||||
required ColorScheme customColorScheme,
|
||||
|
||||
86
pubspec.lock
86
pubspec.lock
@@ -98,10 +98,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "528579c7e4579719f04b21eeeeddfd73a18b31dabc22766893b7d1be7f49b967"
|
||||
sha256: "0c64e928dcbefddecd234205422bcfc2b5e6d31be0b86fef0d0dd48d7b4c9742"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.3"
|
||||
version: "4.0.4"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -314,10 +314,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
sha256: "28a712df2576b63c6c005c465989a348604960c0958d28be5303ba9baa841ac2"
|
||||
sha256: "8b158ab94ec6913e480dc3f752418348b5ae099eb75868b5f4775f0572999c61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.9.3"
|
||||
version: "8.9.4"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -510,6 +510,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.8"
|
||||
dartx:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dartx
|
||||
sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -522,10 +530,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "72d146c6d7098689ff5c5f66bcf593ac11efc530095385356e131070333e64da"
|
||||
sha256: "610739247975c2d0de43482afa13ec1018f63c9fddf97ef3d8dc895faa3b4543"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.3.0"
|
||||
version: "11.3.2"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -554,10 +562,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: e485c7a39ff2b384fa1d7e09b4e25f755804de8384358049124830b04fc4f93a
|
||||
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
dismissible_page:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -650,10 +658,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "6f6bfa8797f296965bdc3e1f702574ab49a540c19b9237b401e7c2b25dfe594c"
|
||||
sha256: "7423298f08f6fc8cce05792bae329f9a93653fc9c08712831b1a55540127995d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
version: "9.0.2"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -988,10 +996,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
|
||||
sha256: "1c2b787f99bdca1f3718543f81d38aa1b124817dfeb9fb196201bea85b6134bf"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.24"
|
||||
version: "2.0.26"
|
||||
flutter_quill:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1118,10 +1126,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: functions_client
|
||||
sha256: "61597ed93be197b1be6387855e4b760e6aac2355fcfc4df6d20d2b4579982158"
|
||||
sha256: a49876ebae32a50eb62483c5c5ac80ed0d8da34f98ccc23986b03a8d28cee07c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
gal:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1563,7 +1571,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
@@ -1765,18 +1773,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: "67eae327b1b0faf761964a1d2e5d323c797f3799db0e85aa232db8d9e922bc35"
|
||||
sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.1"
|
||||
version: "8.3.0"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "205ec83335c2ab9107bbba3f8997f9356d72ca3c715d2f038fc773d0366b4c76"
|
||||
sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
version: "3.2.0"
|
||||
page_transition:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -2069,10 +2077,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: realtime_client
|
||||
sha256: "1bfcb7455fdcf15953bf18ac2817634ea5b8f7f350c7e8c9873141a3ee2c3e9c"
|
||||
sha256: e3089dac2121917cc0c72d42ab056fea0abbaf3c2229048fc50e64bafc731adf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.4.2"
|
||||
record:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -2451,10 +2459,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: storage_client
|
||||
sha256: d80d34f0aa60e5199646bc301f5750767ee37310c2ecfe8d4bbdd29351e09ab0
|
||||
sha256: "9f9ed283943313b23a1b27139bb18986e9b152a6d34530232c702c468d98e91a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
version: "2.3.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -2483,34 +2491,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: supabase
|
||||
sha256: "270f63cd87a16578fee87e40cbf61062e8cdbce68d5e723e665f4651d70ddd8c"
|
||||
sha256: c3ebddba69ddcf16d8b78e8c44c4538b0193d1cf944fde3b72eb5b279892a370
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
version: "2.6.3"
|
||||
supabase_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: supabase_flutter
|
||||
sha256: ca8dfe3d4b109e7338cdf7778f3ec2c660a0178006876bfac343eb39b0f3d1e3
|
||||
sha256: "3b5b5b492e342f63f301605d0c66f6528add285b5744f53c9fd9abd5ffdbce5b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.8.3"
|
||||
version: "2.8.4"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "634adbc5c7d41e31513e9e3d60213bbc6aedff6e90ddb23b6495bfc0a23a260e"
|
||||
sha256: "393db014b90865222f8c442dd989a9ba6107bb92bf4d4774257d60a3ee05053f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "28.2.6"
|
||||
version: "28.2.7"
|
||||
syncfusion_flutter_sliders:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_sliders
|
||||
sha256: a376f2495888fc6b18cbb42694ec7f1d7805ff966326bcb1ecf4220dd779b160
|
||||
sha256: "131446a2818d31305596e7e94fd45f13fdc9a1b387939f4f814026aca99d8d7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "28.2.6"
|
||||
version: "28.2.7"
|
||||
synchronized:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -2543,6 +2551,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.0"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -2795,10 +2811,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -2835,10 +2851,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852"
|
||||
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.5"
|
||||
version: "2.1.0"
|
||||
wkt_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -113,6 +113,8 @@ dependencies:
|
||||
page_transition: 2.2.1
|
||||
dismissible_page: 1.0.2
|
||||
photo_view: 0.15.0
|
||||
dartx: 1.2.0
|
||||
material_color_utilities: 0.11.1
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user