diff --git a/README-EN.md b/README-EN.md
index 11044f8f6..13cf46805 100644
--- a/README-EN.md
+++ b/README-EN.md
@@ -29,16 +29,16 @@ FlutterUnit is a cross-platform experience app, Here, you can fully explore the
---
-### Env and Build
+### Env and Build
#### Flutter Version
```
·]>> flutter --version
-Flutter 3.32.0 • channel stable • https://github.com/flutter/flutter.git
-Framework • revision be698c48a6 (2 days ago) • 2025-05-19 12:59:14 -0700
-Engine • revision 1881800949 (2 days ago) • 2025-05-19 10:54:07 -0700
-Tools • Dart 3.8.0 • DevTools 2.45.1
+Flutter 3.35.1 • channel stable • https://github.com/flutter/flutter.git
+Framework • revision 20f8274939 (6 days ago) • 2025-08-14 10:53:09 -0700
+Engine • hash 6cd51c08a88e7bbe848a762c20ad3ecb8b063c0e (revision 1e9a811bf8) (7 days ago) • 2025-08-13 23:35:25.000Z
+Tools • Dart 3.9.0 • DevTools 2.48.0
```
#### Build Application
diff --git a/README.md b/README.md
index 9e4306022..0881234c8 100644
--- a/README.md
+++ b/README.md
@@ -34,10 +34,10 @@ FlutterUnit 是一个全平台体验应用,你可以在这里尽情体验 Flut
```
·]>> flutter --version
-Flutter 3.32.0 • channel stable • https://github.com/flutter/flutter.git
-Framework • revision be698c48a6 (2 days ago) • 2025-05-19 12:59:14 -0700
-Engine • revision 1881800949 (2 days ago) • 2025-05-19 10:54:07 -0700
-Tools • Dart 3.8.0 • DevTools 2.45.1
+Flutter 3.35.1 • channel stable • https://github.com/flutter/flutter.git
+Framework • revision 20f8274939 (6 days ago) • 2025-08-14 10:53:09 -0700
+Engine • hash 6cd51c08a88e7bbe848a762c20ad3ecb8b063c0e (revision 1e9a811bf8) (7 days ago) • 2025-08-13 23:35:25.000Z
+Tools • Dart 3.9.0 • DevTools 2.48.0
```
#### 构建应用
diff --git a/assets/article.db b/assets/article.db
new file mode 100644
index 000000000..2d4ee64f0
Binary files /dev/null and b/assets/article.db differ
diff --git a/assets/flutter.db b/assets/flutter.db
index b09da0bcc..4ca299955 100644
Binary files a/assets/flutter.db and b/assets/flutter.db differ
diff --git a/assets/images/widgets/Banner.svg b/assets/images/widgets/Banner.svg
index e4f8b66d7..27c390ff1 100644
--- a/assets/images/widgets/Banner.svg
+++ b/assets/images/widgets/Banner.svg
@@ -5,16 +5,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/Card.svg b/assets/images/widgets/Card.svg
index b69099b84..62d2d4b8d 100644
--- a/assets/images/widgets/Card.svg
+++ b/assets/images/widgets/Card.svg
@@ -5,22 +5,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/Chip.svg b/assets/images/widgets/Chip.svg
index cea4cbee4..a66547522 100644
--- a/assets/images/widgets/Chip.svg
+++ b/assets/images/widgets/Chip.svg
@@ -9,16 +9,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/Container.svg b/assets/images/widgets/Container.svg
index be18043df..c1500829f 100644
--- a/assets/images/widgets/Container.svg
+++ b/assets/images/widgets/Container.svg
@@ -11,16 +11,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/FilterChip.svg b/assets/images/widgets/FilterChip.svg
index 7a3f6fdd2..2c0214a26 100644
--- a/assets/images/widgets/FilterChip.svg
+++ b/assets/images/widgets/FilterChip.svg
@@ -11,16 +11,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/InputChip.svg b/assets/images/widgets/InputChip.svg
index b739a7ae0..d50adf71c 100644
--- a/assets/images/widgets/InputChip.svg
+++ b/assets/images/widgets/InputChip.svg
@@ -13,16 +13,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/images/widgets/MaterialButton.svg b/assets/images/widgets/MaterialButton.svg
index 7ace688c5..11b59f54b 100644
--- a/assets/images/widgets/MaterialButton.svg
+++ b/assets/images/widgets/MaterialButton.svg
@@ -5,16 +5,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/version.json b/assets/version.json
index 231c882a0..0c311e970 100644
--- a/assets/version.json
+++ b/assets/version.json
@@ -1,3 +1,3 @@
{
- "dbVersion": 4
+ "dbVersion": 5
}
\ No newline at end of file
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
new file mode 100644
index 000000000..65c14cf2b
--- /dev/null
+++ b/doc/development/architecture.md
@@ -0,0 +1,247 @@
+# FlutterUnit 架构设计文档
+
+## 项目概述
+
+FlutterUnit 是一个全平台的 Flutter 组件展示和学习应用,支持 Android、iOS、Web、Windows、macOS 和 Linux 平台。项目采用模块化架构,提供了 300+ Flutter 组件的详细展示、代码示例和交互演示。
+
+## 技术栈
+
+- **框架**: Flutter 3.35.1
+- **状态管理**: flutter_bloc (BLoC 模式)
+- **路由管理**: go_router
+- **数据库**: SQLite (本地数据存储)
+- **网络请求**: dio
+- **国际化**: flutter_localizations
+- **UI组件**: 自研 TolyUI 组件库
+
+## 整体架构
+
+### 分层架构
+
+```
+┌─────────────────────────────────────┐
+│ Presentation Layer │ ← UI层 (Views/Pages)
+├─────────────────────────────────────┤
+│ Business Logic Layer │ ← 业务逻辑层 (BLoC)
+├─────────────────────────────────────┤
+│ Repository Layer │ ← 仓储层 (Repository)
+├─────────────────────────────────────┤
+│ Data Source Layer │ ← 数据源层 (Database/API)
+└─────────────────────────────────────┘
+```
+
+### 模块化设计
+
+```
+FlutterUnit/
+├── modules/
+│ ├── basic_system/ # 基础系统模块
+│ │ ├── app/ # 应用核心配置
+│ │ ├── app_update/ # 应用更新
+│ │ ├── authentication/ # 用户认证
+│ │ ├── components/ # 通用组件
+│ │ ├── l10n/ # 国际化
+│ │ ├── storage/ # 数据存储
+│ │ ├── toly_ui/ # UI组件库
+│ │ └── utils/ # 工具类
+│ ├── widget_system/ # 组件系统模块
+│ │ ├── widget_module/ # 组件业务逻辑
+│ │ ├── widget_repository/ # 组件数据仓储
+│ │ └── widget_ui/ # 组件UI展示
+│ ├── knowledge_system/ # 知识系统模块
+│ │ ├── algorithm/ # 算法相关
+│ │ ├── artifact/ # 工件管理
+│ │ ├── awesome/ # 精选内容
+│ │ ├── layout/ # 布局相关
+│ │ └── note/ # 笔记功能
+│ ├── painting_system/ # 绘制系统模块
+│ │ └── draw_system/ # 自定义绘制
+│ └── tools_system/ # 工具系统模块
+│ └── treasure_tools/ # 实用工具集
+└── lib/
+ ├── src/
+ │ ├── navigation/ # 路由导航
+ │ ├── l10n/ # 本地化
+ │ └── starter/ # 应用启动
+ └── main.dart
+```
+
+## 核心架构组件
+
+### 1. 应用启动器 (FxApplication)
+
+```dart
+class FxApplication with FxStarter {
+ @override
+ Widget get app => const AppBlocProvider(child: FlutterUnit3());
+
+ @override
+ AppStartRepository get repository => const FlutterUnitStartRepo();
+}
+```
+
+**职责**:
+- 应用启动流程管理
+- 全局配置初始化
+- 错误处理和监控
+
+### 2. 状态管理 (BLoC 模式)
+
+```
+Event → BLoC → State → UI
+ ↑ ↓
+ └── User Interaction ┘
+```
+
+**主要 BLoC**:
+- `AppConfigBloc`: 应用配置管理
+- `WidgetsBloc`: 组件数据管理
+- `CategoryBloc`: 分类管理
+- `LikeWidgetBloc`: 收藏功能
+
+### 3. 路由架构
+
+```dart
+GoRoute(
+ path: AppRoute.home.path,
+ routes: [
+ if (kAppEnv.isDesktopUI)
+ ShellRoute(
+ builder: (_, __, Widget child) => AppDeskNavigation(content: child),
+ routes: body,
+ ),
+ if (!kAppEnv.isDesktopUI) ...body,
+ ],
+)
+```
+
+**特点**:
+- 支持桌面端和移动端不同导航
+- 声明式路由配置
+- 深度链接支持
+
+### 4. 数据层架构
+
+#### Repository 模式
+
+```dart
+abstract class WidgetRepository {
+ Future> loadWidgets();
+ Future findWidget(int id);
+ Future> loadNodeByWidgetId(int widgetId);
+}
+```
+
+**实现层**:
+- `WidgetDbRepository`: 数据库实现
+- `MemoryWidgetRepository`: 内存缓存实现
+
+#### 数据库设计
+
+**核心表**:
+- `widget`: Widget基本信息
+- `node`: 示例代码节点
+- `category`: Widget分类
+
+详见: [数据表结构总览](../modules/widget_system/widget_repository/doc/tables_overview.md)
+
+## 平台适配
+
+### 平台检测
+
+```dart
+class kAppEnv {
+ static bool get isWeb;
+ static bool get isDesktopUI;
+ static bool get isMobile;
+}
+```
+
+### 响应式设计
+
+- **移动端**: 底部导航 + 侧滑菜单
+- **桌面端**: 侧边栏导航 + 多窗口布局
+- **Web端**: 响应式布局适配
+
+## 核心功能
+
+### 1. 组件展示系统
+
+- 300+ Flutter组件收录
+- 实时代码演示
+- 交互式组件体验
+- 组件关联跳转
+
+### 2. 搜索与过滤
+
+- 组件名称搜索
+- 星级过滤
+- 分类筛选
+
+### 3. 收藏系统
+
+- 自定义收藏集
+- 收藏集管理
+- 批量操作
+
+### 4. 主题系统
+
+- 明暗主题切换
+- 8种预设颜色主题
+- 6种字体选择
+- 自定义代码高亮
+
+## 性能优化
+
+### 1. 数据缓存
+- 内存缓存: 热点数据常驻内存
+- 数据库缓存: 本地SQLite存储
+
+### 2. 懒加载
+- 路由懒加载: 按需加载页面
+- 组件懒加载: 滚动时动态加载
+
+### 3. 构建优化
+- 代码分割: 模块化打包
+- 资源优化: 图片压缩、字体子集化
+
+## 构建与部署
+
+### 多平台构建
+
+```bash
+# Android
+flutter build apk --target-platform --split-per-abi
+
+# iOS
+flutter build ios
+
+# Web
+flutter build web
+
+# Desktop
+flutter build windows
+flutter build macos
+flutter build linux
+```
+
+### 发布渠道
+
+- Android: APK 直接下载
+- iOS: App Store
+- Web: 在线访问
+- Desktop: 可执行文件下载
+
+## 开发规范
+
+### 代码规范
+- 遵循 Dart 官方代码规范
+- 使用 `flutter_lints` 进行代码检查
+
+### 模块规范
+- 每个模块独立的 `pubspec.yaml`
+- 清晰的模块边界和依赖关系
+
+### 测试规范
+- 单元测试覆盖核心业务逻辑
+- Widget测试验证UI行为
\ No newline at end of file
diff --git a/lib/src/navigation/view/mobile/unit_navigation.dart b/lib/src/navigation/view/mobile/unit_navigation.dart
index 702bca963..2873021dc 100644
--- a/lib/src/navigation/view/mobile/unit_navigation.dart
+++ b/lib/src/navigation/view/mobile/unit_navigation.dart
@@ -96,7 +96,7 @@ class _UnitPhoneNavigationState extends State {
_controller.jumpToPage(index);
_activeTab.value = AppTab.values[index];
if (index == 3) {
- BlocProvider.of(context).add(const EventLoadLikeData());
+ context.read().loadLikeData();
}
}
}
diff --git a/lib/src/starter/fx_application.dart b/lib/src/starter/fx_application.dart
index f66b52b39..b029751d0 100644
--- a/lib/src/starter/fx_application.dart
+++ b/lib/src/starter/fx_application.dart
@@ -24,12 +24,12 @@ class FxApplication with FxStarter {
AppStartRepository get repository => const FlutterUnitStartRepo();
@override
- void onLoaded(BuildContext context, int cost, AppConfig state) {
+ void onLoaded(BuildContext context, int cost, AppConfig state) async {
debugPrint("App启动耗时:$cost ms");
context.read().init(state);
context.initWidgetData();
if (!kAppEnv.isWeb) {
- context.read().add(const EventLoadLikeData());
+ context.read().loadLikeData();
context.read().add(const EventLoadCategory());
context.read().load();
}
diff --git a/lib/src/starter/start_repository.dart b/lib/src/starter/start_repository.dart
index 86aea38b0..e022bdf03 100644
--- a/lib/src/starter/start_repository.dart
+++ b/lib/src/starter/start_repository.dart
@@ -11,8 +11,9 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:storage/storage.dart';
import 'package:path/path.dart' as path;
import 'package:utils/utils.dart';
-
+import 'package:path/path.dart' as p;
import 'bridge/unit_bridge.dart';
+import 'package:widget_module/widget_module.dart';
class FlutterUnitStartRepo implements AppStartRepository {
const FlutterUnitStartRepo();
@@ -31,6 +32,8 @@ class FlutterUnitStartRepo implements AppStartRepository {
registerHttpClient();
NoteEnv().attachBridge(UnitNoteBridge());
if (!kAppEnv.isWeb) await initDb();
+ await initWidgetStatistics(); // 加载统计数据
+
HttpUtil.instance.rebase(PathUnit.baseUrl);
AppConfigPo po = await SpStorage().appConfig.read();
AppConfig state = AppConfig.fromPo(po);
@@ -54,11 +57,19 @@ class FlutterUnitStartRepo implements AppStartRepository {
if (!dir.existsSync()) {
await dir.create(recursive: true);
}
- ByteData data = await rootBundle.load("assets/flutter.db");
- List bytes =
- data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
- await File(dbPath).writeAsBytes(bytes, flush: true);
-
+ {
+ ByteData data = await rootBundle.load("assets/flutter.db");
+ List bytes =
+ data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
+ await File(dbPath).writeAsBytes(bytes, flush: true);
+ }
+ {
+ ByteData data = await rootBundle.load("assets/article.db");
+ List bytes =
+ data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
+ await File(p.join(dir.path, 'article.db'))
+ .writeAsBytes(bytes, flush: true);
+ }
print("=====flutter.db==== assets ======拷贝完成====");
}
diff --git a/lib/src/starter/view/splash/Flutter_unit_splash.dart b/lib/src/starter/view/splash/Flutter_unit_splash.dart
index e9d55f1eb..fadb85b50 100644
--- a/lib/src/starter/view/splash/Flutter_unit_splash.dart
+++ b/lib/src/starter/view/splash/Flutter_unit_splash.dart
@@ -22,6 +22,7 @@ class FlutterUnitSplash extends StatelessWidget {
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
+ systemNavigationBarColor: Colors.transparent,
),
child: Material(color: Colors.white, child: _SplashBody()),
),
@@ -74,7 +75,7 @@ class _SplashBody extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text("Power By 张风捷特烈", style: shadowStyle),
- Text("· 2021 · @编程之王 ", style: shadowStyle),
+ Text("· 2025 · @编程之王 ", style: shadowStyle),
],
)),
],
@@ -101,7 +102,11 @@ class ColorfulText extends StatelessWidget {
);
return Text(
"U",
- style: TextStyle(fontSize: 26, height: 1, fontWeight: FontWeight.bold, foreground: paint),
+ style: TextStyle(
+ fontSize: 26,
+ height: 1,
+ fontWeight: FontWeight.bold,
+ foreground: paint),
);
}
}
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index 43f825ccf..faea87d4e 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -6,19 +6,11 @@
#include "generated_plugin_registrant.h"
-#include
-#include
#include
#include
#include
void fl_register_plugins(FlPluginRegistry* registry) {
- g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
- fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
- file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
- g_autoptr(FlPluginRegistrar) open_file_linux_registrar =
- fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin");
- open_file_linux_plugin_register_with_registrar(open_file_linux_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index 95b737f5c..4f427dd2a 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -3,8 +3,6 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
- file_selector_linux
- open_file_linux
screen_retriever_linux
url_launcher_linux
window_manager
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 25112d2fa..ab2f2a3fc 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -6,10 +6,8 @@ import FlutterMacOS
import Foundation
import file_picker
-import open_file_mac
import package_info_plus
import path_provider_foundation
-import quill_native_bridge_macos
import screen_retriever_macos
import share_plus
import shared_preferences_foundation
@@ -20,10 +18,8 @@ import window_manager
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
- OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
- QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin"))
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
diff --git a/modules/basic_system/app/lib/app/cons/global_value.dart b/modules/basic_system/app/lib/app/cons/global_value.dart
index 3e1babfa4..36c8608b2 100644
--- a/modules/basic_system/app/lib/app/cons/global_value.dart
+++ b/modules/basic_system/app/lib/app/cons/global_value.dart
@@ -6,7 +6,7 @@ import 'package:uuid/uuid.dart';
double px1 = 1 / window.devicePixelRatio;
-String get kAppVersion => "3.2.0";
+String get kAppVersion => "3.2.3";
bool kIsDesk =
kIsWeb || Platform.isMacOS || Platform.isWindows || Platform.isLinux;
diff --git a/modules/basic_system/app/lib/app/cons/str_unit.dart b/modules/basic_system/app/lib/app/cons/str_unit.dart
index 4345daddf..abfa191a2 100644
--- a/modules/basic_system/app/lib/app/cons/str_unit.dart
+++ b/modules/basic_system/app/lib/app/cons/str_unit.dart
@@ -7,7 +7,7 @@ import 'package:l10n/l10n.dart';
class StrUnit {
// 小文字大小
- static const String version = 'V3.2.0';
+ static const String version = 'V3.2.2';
static const String appName = 'Flutter Unit';
static String galleryDesc(BuildContext context) => """
diff --git a/modules/basic_system/app/lib/app/theme/app_theme.dart b/modules/basic_system/app/lib/app/theme/app_theme.dart
index 7940d16a0..125bd7147 100644
--- a/modules/basic_system/app/lib/app/theme/app_theme.dart
+++ b/modules/basic_system/app/lib/app/theme/app_theme.dart
@@ -3,13 +3,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
ThemeData darkTheme(AppConfig state) {
- Color scaffoldBackgroundColor = const Color(0xff010201);
+ const Color scaffoldBackgroundColor = Color(0xff010201);
SystemUiOverlayStyle overlayStyle = const SystemUiOverlayStyle(
- statusBarColor: Colors.transparent,
- statusBarBrightness: Brightness.dark,
- statusBarIconBrightness: Brightness.light,
- );
+ statusBarColor: Colors.transparent,
+ statusBarBrightness: Brightness.dark,
+ statusBarIconBrightness: Brightness.light,
+ systemNavigationBarColor: Color(0xff181818));
return ThemeData(
scaffoldBackgroundColor: scaffoldBackgroundColor,
@@ -51,7 +51,7 @@ ThemeData darkTheme(AppConfig state) {
dividerTheme: DividerThemeData(
color: const Color(0xff2F2F2F),
space: px1,
- thickness: px1,
+ thickness: divHeight,
),
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
backgroundColor: Color(0xff181818),
@@ -59,17 +59,25 @@ ThemeData darkTheme(AppConfig state) {
);
}
+double get divHeight {
+ if (kAppEnv.isAndroid) {
+ return 0.2;
+ }
+ return px1;
+}
+
ThemeData lightTheme(AppConfig state) {
SystemUiOverlayStyle overlayStyle = const SystemUiOverlayStyle(
- statusBarColor: Colors.transparent,
- statusBarBrightness: Brightness.light,
- statusBarIconBrightness: Brightness.dark,
- );
+ statusBarColor: Colors.transparent,
+ statusBarBrightness: Brightness.light,
+ statusBarIconBrightness: Brightness.dark,
+ systemNavigationBarColor: Colors.transparent);
String fontFamily = state.fontFamily;
if (kAppEnv.isWindows) {
fontFamily = '宋体';
}
+
return ThemeData(
fontFamily: fontFamily,
primaryColor: state.themeColor.color,
@@ -88,7 +96,7 @@ ThemeData lightTheme(AppConfig state) {
dividerTheme: DividerThemeData(
color: const Color(0xffDEE0E2),
space: px1,
- thickness: px1,
+ thickness: divHeight,
),
pageTransitionsTheme: const PageTransitionsTheme(builders: {
TargetPlatform.android: SlidePageTransitionsBuilder(),
diff --git a/modules/basic_system/app/lib/view/data_manage/data_manage_page.dart b/modules/basic_system/app/lib/view/data_manage/data_manage_page.dart
index a2a714dc3..a6a38d011 100644
--- a/modules/basic_system/app/lib/view/data_manage/data_manage_page.dart
+++ b/modules/basic_system/app/lib/view/data_manage/data_manage_page.dart
@@ -81,7 +81,7 @@ class DataManagePage extends StatelessWidget {
await File(dbPath).writeAsBytes(bytes, flush: true);
print("==== debug ===== assets ======拷贝完成====");
BlocProvider.of(context).add(const EventLoadCategory());
- BlocProvider.of(context).add(const EventLoadLikeData());
+ context.read().loadLikeData();
Toast.toast(context, '重置成功!');
}
@@ -116,7 +116,7 @@ class DataManagePage extends StatelessWidget {
await repository.syncCategoryByData(
result.data!.data, result.data!.likeData);
BlocProvider.of(context).add(const EventLoadCategory());
- BlocProvider.of(context).add(const EventLoadLikeData());
+ context.read().loadLikeData();
} else {
// 说明还没有后台数据,
// 这里防止有傻孩子没点备份,就点同步,哥哥好心,给备份一下。
diff --git a/modules/basic_system/authentication/lib/views/mobile/user/page_item.dart b/modules/basic_system/authentication/lib/views/mobile/user/page_item.dart
index 5e6131ebf..c01c44496 100644
--- a/modules/basic_system/authentication/lib/views/mobile/user/page_item.dart
+++ b/modules/basic_system/authentication/lib/views/mobile/user/page_item.dart
@@ -18,25 +18,31 @@ class MePageItem extends StatelessWidget {
return _buildChild(context);
}
+ Widget get divider {
+ return const Divider();
+ }
+
Widget _buildChild(BuildContext context) {
return ScrollConfiguration(
behavior: NoScrollBehavior(),
child: ListView(
padding: EdgeInsets.zero,
children: [
- const SizedBox(
- height: 10,
- ),
+ const SizedBox(height: 10),
Gap.sfl10,
- _buildItem(context, TolyIcon.icon_them, context.l10n.appSettings, AppRoute.settings.url),
- const Divider(),
- _buildItem(
- context, TolyIcon.icon_layout, context.l10n.dataManagement, AppRoute.dataManage.url),
- const Divider(),
+ _buildItem(context, TolyIcon.icon_them, context.l10n.appSettings,
+ AppRoute.settings.url),
+ divider,
+ _buildItem(context, TolyIcon.icon_layout, context.l10n.dataManagement,
+ AppRoute.dataManage.url),
+ divider,
_buildItem(
- context, TolyIcon.icon_collect, context.l10n.userCollection, AppRoute.collection.url,),
+ context,
+ TolyIcon.icon_collect,
+ context.l10n.userCollection,
+ AppRoute.collection.url,
+ ),
Gap.sfl10,
-
Stack(
children: [
_buildItem(
@@ -48,13 +54,15 @@ class MePageItem extends StatelessWidget {
const Positioned(left: 40, top: 10, child: UpdateRedPoint())
],
),
- const Divider(),
- _buildItem(context, Icons.info, context.l10n.aboutApplications, AppRoute.aboutApp.url),
-
+ divider,
+ _buildItem(context, Icons.info, context.l10n.aboutApplications,
+ AppRoute.aboutApp.url),
Gap.sfl10,
- _buildItem(context, TolyIcon.icon_kafei, context.l10n.contactThisKing, AppRoute.aboutMe.url),
- const Divider(),
- _buildItem(context, Icons.sanitizer, context.l10n.homeAccountSupport, AppRoute.supportMe.url),
+ _buildItem(context, TolyIcon.icon_kafei, context.l10n.contactThisKing,
+ AppRoute.aboutMe.url),
+ divider,
+ _buildItem(context, Icons.sanitizer, context.l10n.homeAccountSupport,
+ AppRoute.supportMe.url),
],
),
);
@@ -68,7 +76,7 @@ class MePageItem extends StatelessWidget {
icon,
color: Theme.of(context).primaryColor,
),
- title: Text(title, style: const TextStyle(fontSize: 16)),
+ title: Text(title, style: const TextStyle(fontSize: 16)),
trailing:
Icon(Icons.chevron_right, color: Theme.of(context).primaryColor),
onTap: () {
diff --git a/modules/basic_system/components/lib/flutter_ui/toly_date_picker.dart b/modules/basic_system/components/lib/flutter_ui/toly_date_picker.dart
index 7d7bc385a..495884cbc 100644
--- a/modules/basic_system/components/lib/flutter_ui/toly_date_picker.dart
+++ b/modules/basic_system/components/lib/flutter_ui/toly_date_picker.dart
@@ -144,20 +144,20 @@ Future showDatePicker({
firstDate = DateUtils.dateOnly(firstDate);
lastDate = DateUtils.dateOnly(lastDate);
assert(
- !lastDate.isBefore(firstDate),
- 'lastDate $lastDate must be on or after firstDate $firstDate.',
+ !lastDate.isBefore(firstDate),
+ 'lastDate $lastDate must be on or after firstDate $firstDate.',
);
assert(
- !initialDate.isBefore(firstDate),
- 'initialDate $initialDate must be on or after firstDate $firstDate.',
+ !initialDate.isBefore(firstDate),
+ 'initialDate $initialDate must be on or after firstDate $firstDate.',
);
assert(
- !initialDate.isAfter(lastDate),
- 'initialDate $initialDate must be on or before lastDate $lastDate.',
+ !initialDate.isAfter(lastDate),
+ 'initialDate $initialDate must be on or before lastDate $lastDate.',
);
assert(
- selectableDayPredicate == null || selectableDayPredicate(initialDate),
- 'Provided initialDate $initialDate must satisfy provided selectableDayPredicate.',
+ selectableDayPredicate == null || selectableDayPredicate(initialDate),
+ 'Provided initialDate $initialDate must satisfy provided selectableDayPredicate.',
);
assert(initialEntryMode != null);
assert(useRootNavigator != null);
@@ -237,7 +237,7 @@ class DatePickerDialog extends StatefulWidget {
this.fieldLabelText,
this.keyboardType,
this.restorationId,
- }) : assert(initialDate != null),
+ }) : assert(initialDate != null),
assert(firstDate != null),
assert(lastDate != null),
initialDate = DateUtils.dateOnly(initialDate),
@@ -247,20 +247,21 @@ class DatePickerDialog extends StatefulWidget {
assert(initialEntryMode != null),
assert(initialCalendarMode != null) {
assert(
- !this.lastDate.isBefore(this.firstDate),
- 'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.',
+ !this.lastDate.isBefore(this.firstDate),
+ 'lastDate ${this.lastDate} must be on or after firstDate ${this.firstDate}.',
);
assert(
- !this.initialDate.isBefore(this.firstDate),
- 'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.',
+ !this.initialDate.isBefore(this.firstDate),
+ 'initialDate ${this.initialDate} must be on or after firstDate ${this.firstDate}.',
);
assert(
- !this.initialDate.isAfter(this.lastDate),
- 'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.',
+ !this.initialDate.isAfter(this.lastDate),
+ 'initialDate ${this.initialDate} must be on or before lastDate ${this.lastDate}.',
);
assert(
- selectableDayPredicate == null || selectableDayPredicate!(this.initialDate),
- 'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate',
+ selectableDayPredicate == null ||
+ selectableDayPredicate!(this.initialDate),
+ 'Provided initialDate ${this.initialDate} must satisfy provided selectableDayPredicate',
);
}
@@ -343,10 +344,14 @@ class DatePickerDialog extends StatefulWidget {
State createState() => _DatePickerDialogState();
}
-class _DatePickerDialogState extends State with RestorationMixin {
- late final RestorableDateTime _selectedDate = RestorableDateTime(widget.initialDate);
- late final _RestorableDatePickerEntryMode _entryMode = _RestorableDatePickerEntryMode(widget.initialEntryMode);
- final _RestorableAutovalidateMode _autovalidateMode = _RestorableAutovalidateMode(AutovalidateMode.disabled);
+class _DatePickerDialogState extends State
+ with RestorationMixin {
+ late final RestorableDateTime _selectedDate =
+ RestorableDateTime(widget.initialDate);
+ late final _RestorableDatePickerEntryMode _entryMode =
+ _RestorableDatePickerEntryMode(widget.initialEntryMode);
+ final _RestorableAutovalidateMode _autovalidateMode =
+ _RestorableAutovalidateMode(AutovalidateMode.disabled);
@override
String? get restorationId => widget.restorationId;
@@ -362,7 +367,8 @@ class _DatePickerDialogState extends State with RestorationMix
final GlobalKey _formKey = GlobalKey();
void _handleOk() {
- if (_entryMode.value == DatePickerEntryMode.input || _entryMode.value == DatePickerEntryMode.inputOnly) {
+ if (_entryMode.value == DatePickerEntryMode.input ||
+ _entryMode.value == DatePickerEntryMode.inputOnly) {
final FormState form = _formKey.currentState!;
if (!form.validate()) {
setState(() => _autovalidateMode.value = AutovalidateMode.always);
@@ -424,7 +430,8 @@ class _DatePickerDialogState extends State with RestorationMix
}
}
- static const Map _formShortcutMap = {
+ static const Map _formShortcutMap =
+ {
// Pressing enter on the field will move focus to the next field or control.
SingleActivator(LogicalKeyboardKey.enter): NextFocusIntent(),
};
@@ -433,12 +440,14 @@ class _DatePickerDialogState extends State with RestorationMix
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final TextTheme textTheme = theme.textTheme;
// Constrain the textScaleFactor to the largest supported value to prevent
// layout issues.
- final double textScaleFactor = math.min(MediaQuery.of(context).textScaleFactor, 1.3);
+ final double textScaleFactor =
+ math.min(MediaQuery.of(context).textScaleFactor, 1.3);
final String dateText = localizations.formatMediumDate(_selectedDate.value);
final Color onPrimarySurface = colorScheme.brightness == Brightness.light
@@ -486,7 +495,9 @@ class _DatePickerDialogState extends State with RestorationMix
autovalidateMode: _autovalidateMode.value,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24),
- height: orientation == Orientation.portrait ? _inputFormPortraitHeight : _inputFormLandscapeHeight,
+ height: orientation == Orientation.portrait
+ ? _inputFormPortraitHeight
+ : _inputFormLandscapeHeight,
child: Shortcuts(
shortcuts: _formShortcutMap,
child: Column(
@@ -559,7 +570,8 @@ class _DatePickerDialogState extends State with RestorationMix
final Size dialogSize = _dialogSize(context) * textScaleFactor;
return Dialog(
- insetPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0),
+ insetPadding:
+ const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0),
clipBehavior: Clip.antiAlias,
child: AnimatedContainer(
width: dialogSize.width,
@@ -611,10 +623,11 @@ class _DatePickerDialogState extends State with RestorationMix
// A restorable [DatePickerEntryMode] value.
//
// This serializes each entry as a unique `int` value.
-class _RestorableDatePickerEntryMode extends RestorableValue {
+class _RestorableDatePickerEntryMode
+ extends RestorableValue {
_RestorableDatePickerEntryMode(
- DatePickerEntryMode defaultValue,
- ) : _defaultValue = defaultValue;
+ DatePickerEntryMode defaultValue,
+ ) : _defaultValue = defaultValue;
final DatePickerEntryMode _defaultValue;
@@ -628,7 +641,8 @@ class _RestorableDatePickerEntryMode extends RestorableValue DatePickerEntryMode.values[data! as int];
+ DatePickerEntryMode fromPrimitives(Object? data) =>
+ DatePickerEntryMode.values[data! as int];
@override
Object? toPrimitives() => value.index;
@@ -639,8 +653,8 @@ class _RestorableDatePickerEntryMode extends RestorableValue {
_RestorableAutovalidateMode(
- AutovalidateMode defaultValue,
- ) : _defaultValue = defaultValue;
+ AutovalidateMode defaultValue,
+ ) : _defaultValue = defaultValue;
final AutovalidateMode _defaultValue;
@@ -654,7 +668,8 @@ class _RestorableAutovalidateMode extends RestorableValue {
}
@override
- AutovalidateMode fromPrimitives(Object? data) => AutovalidateMode.values[data! as int];
+ AutovalidateMode fromPrimitives(Object? data) =>
+ AutovalidateMode.values[data! as int];
@override
Object? toPrimitives() => value.index;
@@ -672,7 +687,6 @@ class _RestorableAutovalidateMode extends RestorableValue {
/// [helpText], [orientation], [icon], [onIconPressed] are required and must be
/// non-null.
class _DatePickerHeader extends StatelessWidget {
-
/// Creates a header for use in a date picker dialog.
const _DatePickerHeader({
required this.helpText,
@@ -682,7 +696,7 @@ class _DatePickerHeader extends StatelessWidget {
required this.orientation,
this.isShort = false,
this.entryModeButton,
- }) : assert(helpText != null),
+ }) : assert(helpText != null),
assert(orientation != null),
assert(isShort != null);
@@ -727,8 +741,10 @@ class _DatePickerHeader extends StatelessWidget {
// The header should use the primary color in light themes and surface color in dark
final bool isDark = colorScheme.brightness == Brightness.dark;
- final Color primarySurfaceColor = isDark ? colorScheme.surface : colorScheme.primary;
- final Color onPrimarySurfaceColor = isDark ? colorScheme.onSurface : colorScheme.onPrimary;
+ final Color primarySurfaceColor =
+ isDark ? colorScheme.surface : colorScheme.primary;
+ final Color onPrimarySurfaceColor =
+ isDark ? colorScheme.onSurface : colorScheme.onPrimary;
final TextStyle? helpStyle = textTheme.headlineMedium?.copyWith(
color: onPrimarySurfaceColor,
@@ -768,8 +784,7 @@ class _DatePickerHeader extends StatelessWidget {
Row(
children: [
Expanded(child: title),
- if (entryModeButton != null)
- entryModeButton!,
+ if (entryModeButton != null) entryModeButton!,
],
),
],
@@ -935,37 +950,40 @@ Future showDateRangePicker({
}) async {
assert(context != null);
assert(
- initialDateRange == null || (initialDateRange.start != null && initialDateRange.end != null),
- 'initialDateRange must be null or have non-null start and end dates.',
+ initialDateRange == null ||
+ (initialDateRange.start != null && initialDateRange.end != null),
+ 'initialDateRange must be null or have non-null start and end dates.',
);
assert(
- initialDateRange == null || !initialDateRange.start.isAfter(initialDateRange.end),
- "initialDateRange's start date must not be after it's end date.",
+ initialDateRange == null ||
+ !initialDateRange.start.isAfter(initialDateRange.end),
+ "initialDateRange's start date must not be after it's end date.",
);
- initialDateRange = initialDateRange == null ? null : DateUtils.datesOnly(initialDateRange);
+ initialDateRange =
+ initialDateRange == null ? null : DateUtils.datesOnly(initialDateRange);
assert(firstDate != null);
firstDate = DateUtils.dateOnly(firstDate);
assert(lastDate != null);
lastDate = DateUtils.dateOnly(lastDate);
assert(
- !lastDate.isBefore(firstDate),
- 'lastDate $lastDate must be on or after firstDate $firstDate.',
+ !lastDate.isBefore(firstDate),
+ 'lastDate $lastDate must be on or after firstDate $firstDate.',
);
assert(
- initialDateRange == null || !initialDateRange.start.isBefore(firstDate),
- "initialDateRange's start date must be on or after firstDate $firstDate.",
+ initialDateRange == null || !initialDateRange.start.isBefore(firstDate),
+ "initialDateRange's start date must be on or after firstDate $firstDate.",
);
assert(
- initialDateRange == null || !initialDateRange.end.isBefore(firstDate),
- "initialDateRange's end date must be on or after firstDate $firstDate.",
+ initialDateRange == null || !initialDateRange.end.isBefore(firstDate),
+ "initialDateRange's end date must be on or after firstDate $firstDate.",
);
assert(
- initialDateRange == null || !initialDateRange.start.isAfter(lastDate),
- "initialDateRange's start date must be on or before lastDate $lastDate.",
+ initialDateRange == null || !initialDateRange.start.isAfter(lastDate),
+ "initialDateRange's start date must be on or before lastDate $lastDate.",
);
assert(
- initialDateRange == null || !initialDateRange.end.isAfter(lastDate),
- "initialDateRange's end date must be on or before lastDate $lastDate.",
+ initialDateRange == null || !initialDateRange.end.isAfter(lastDate),
+ "initialDateRange's end date must be on or before lastDate $lastDate.",
);
currentDate = DateUtils.dateOnly(currentDate ?? DateTime.now());
assert(initialEntryMode != null);
@@ -1024,12 +1042,13 @@ Future showDateRangePicker({
/// is in the same year as the `endDate` then it will use the short month
/// day format (i.e. 'Jan 21'). Otherwise it will return the short date format
/// (i.e. 'Jan 21, 2020').
-String _formatRangeStartDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate) {
+String _formatRangeStartDate(MaterialLocalizations localizations,
+ DateTime? startDate, DateTime? endDate) {
return startDate == null
? localizations.dateRangeStartLabel
: (endDate == null || startDate.year == endDate.year)
- ? localizations.formatShortMonthDay(startDate)
- : localizations.formatShortDate(startDate);
+ ? localizations.formatShortMonthDay(startDate)
+ : localizations.formatShortDate(startDate);
}
/// Returns an locale-appropriate string to describe the end of a date range.
@@ -1038,12 +1057,15 @@ String _formatRangeStartDate(MaterialLocalizations localizations, DateTime? star
/// is in the same year as the `startDate` and the `currentDate` then it will
/// just use the short month day format (i.e. 'Jan 21'), otherwise it will
/// include the year (i.e. 'Jan 21, 2020').
-String _formatRangeEndDate(MaterialLocalizations localizations, DateTime? startDate, DateTime? endDate, DateTime currentDate) {
+String _formatRangeEndDate(MaterialLocalizations localizations,
+ DateTime? startDate, DateTime? endDate, DateTime currentDate) {
return endDate == null
? localizations.dateRangeEndLabel
- : (startDate != null && startDate.year == endDate.year && startDate.year == currentDate.year)
- ? localizations.formatShortMonthDay(endDate)
- : localizations.formatShortDate(endDate);
+ : (startDate != null &&
+ startDate.year == endDate.year &&
+ startDate.year == currentDate.year)
+ ? localizations.formatShortMonthDay(endDate)
+ : localizations.formatShortDate(endDate);
}
/// A Material-style date range picker dialog.
@@ -1199,13 +1221,18 @@ class DateRangePickerDialog extends StatefulWidget {
State createState() => _DateRangePickerDialogState();
}
-class _DateRangePickerDialogState extends State with RestorationMixin {
- late final _RestorableDatePickerEntryMode _entryMode = _RestorableDatePickerEntryMode(widget.initialEntryMode);
- late final RestorableDateTimeN _selectedStart = RestorableDateTimeN(widget.initialDateRange?.start);
- late final RestorableDateTimeN _selectedEnd = RestorableDateTimeN(widget.initialDateRange?.end);
+class _DateRangePickerDialogState extends State
+ with RestorationMixin {
+ late final _RestorableDatePickerEntryMode _entryMode =
+ _RestorableDatePickerEntryMode(widget.initialEntryMode);
+ late final RestorableDateTimeN _selectedStart =
+ RestorableDateTimeN(widget.initialDateRange?.start);
+ late final RestorableDateTimeN _selectedEnd =
+ RestorableDateTimeN(widget.initialDateRange?.end);
final RestorableBool _autoValidate = RestorableBool(false);
final GlobalKey _calendarPickerKey = GlobalKey();
- final GlobalKey<_InputDateRangePickerState> _inputPickerKey = GlobalKey<_InputDateRangePickerState>();
+ final GlobalKey<_InputDateRangePickerState> _inputPickerKey =
+ GlobalKey<_InputDateRangePickerState>();
@override
String? get restorationId => widget.restorationId;
@@ -1219,7 +1246,8 @@ class _DateRangePickerDialogState extends State with Rest
}
void _handleOk() {
- if (_entryMode.value == DatePickerEntryMode.input || _entryMode.value == DatePickerEntryMode.inputOnly) {
+ if (_entryMode.value == DatePickerEntryMode.input ||
+ _entryMode.value == DatePickerEntryMode.inputOnly) {
final _InputDateRangePickerState picker = _inputPickerKey.currentState!;
if (!picker.validate()) {
setState(() {
@@ -1248,19 +1276,23 @@ class _DateRangePickerDialogState extends State with Rest
break;
case DatePickerEntryMode.input:
- // Validate the range dates
+ // Validate the range dates
if (_selectedStart.value != null &&
- (_selectedStart.value!.isBefore(widget.firstDate) || _selectedStart.value!.isAfter(widget.lastDate))) {
+ (_selectedStart.value!.isBefore(widget.firstDate) ||
+ _selectedStart.value!.isAfter(widget.lastDate))) {
_selectedStart.value = null;
// With no valid start date, having an end date makes no sense for the UI.
_selectedEnd.value = null;
}
if (_selectedEnd.value != null &&
- (_selectedEnd.value!.isBefore(widget.firstDate) || _selectedEnd.value!.isAfter(widget.lastDate))) {
+ (_selectedEnd.value!.isBefore(widget.firstDate) ||
+ _selectedEnd.value!.isAfter(widget.lastDate))) {
_selectedEnd.value = null;
}
// If invalid range (start after end), then just use the start date
- if (_selectedStart.value != null && _selectedEnd.value != null && _selectedStart.value!.isAfter(_selectedEnd.value!)) {
+ if (_selectedStart.value != null &&
+ _selectedEnd.value != null &&
+ _selectedStart.value!.isAfter(_selectedEnd.value!)) {
_selectedEnd.value = null;
}
_entryMode.value = DatePickerEntryMode.calendar;
@@ -1282,14 +1314,16 @@ class _DateRangePickerDialogState extends State with Rest
setState(() => _selectedEnd.value = date);
}
- bool get _hasSelectedDateRange => _selectedStart.value != null && _selectedEnd.value != null;
+ bool get _hasSelectedDateRange =>
+ _selectedStart.value != null && _selectedEnd.value != null;
@override
Widget build(BuildContext context) {
final MediaQueryData mediaQuery = MediaQuery.of(context);
final Orientation orientation = mediaQuery.orientation;
final double textScaleFactor = math.min(mediaQuery.textScaleFactor, 1.3);
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final ColorScheme colors = Theme.of(context).colorScheme;
final Color onPrimarySurface = colors.brightness == Brightness.light
? colors.onPrimary
@@ -1319,12 +1353,12 @@ class _DateRangePickerDialogState extends State with Rest
onCancel: _handleCancel,
entryModeButton: showEntryModeButton
? IconButton(
- icon: const Icon(Icons.edit),
- padding: EdgeInsets.zero,
- color: onPrimarySurface,
- tooltip: localizations.inputDateModeButtonLabel,
- onPressed: _handleEntryModeToggle,
- )
+ icon: const Icon(Icons.edit),
+ padding: EdgeInsets.zero,
+ color: onPrimarySurface,
+ tooltip: localizations.inputDateModeButtonLabel,
+ onPressed: _handleEntryModeToggle,
+ )
: null,
confirmText: widget.saveText ?? localizations.saveButtonLabel,
helpText: widget.helpText ?? localizations.dateRangePickerHelpText,
@@ -1376,20 +1410,23 @@ class _DateRangePickerDialogState extends State with Rest
onCancel: _handleCancel,
entryModeButton: showEntryModeButton
? IconButton(
- icon: const Icon(Icons.calendar_today),
- padding: EdgeInsets.zero,
- color: onPrimarySurface,
- tooltip: localizations.calendarModeButtonLabel,
- onPressed: _handleEntryModeToggle,
- )
+ icon: const Icon(Icons.calendar_today),
+ padding: EdgeInsets.zero,
+ color: onPrimarySurface,
+ tooltip: localizations.calendarModeButtonLabel,
+ onPressed: _handleEntryModeToggle,
+ )
: null,
confirmText: widget.confirmText ?? localizations.okButtonLabel,
cancelText: widget.cancelText ?? localizations.cancelButtonLabel,
helpText: widget.helpText ?? localizations.dateRangePickerHelpText,
);
final DialogThemeData dialogTheme = Theme.of(context).dialogTheme;
- size = orientation == Orientation.portrait ? _inputPortraitDialogSize : _inputRangeLandscapeDialogSize;
- insetPadding = const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0);
+ size = orientation == Orientation.portrait
+ ? _inputPortraitDialogSize
+ : _inputRangeLandscapeDialogSize;
+ insetPadding =
+ const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0);
shape = dialogTheme.shape;
elevation = dialogTheme.elevation ?? 24;
break;
@@ -1452,21 +1489,27 @@ class _CalendarRangePickerDialog extends StatelessWidget {
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final TextTheme textTheme = theme.textTheme;
final Color headerForeground = colorScheme.brightness == Brightness.light
? colorScheme.onPrimary
: colorScheme.onSurface;
final Color headerDisabledForeground = headerForeground.withOpacity(0.38);
- final String startDateText = _formatRangeStartDate(localizations, selectedStartDate, selectedEndDate);
- final String endDateText = _formatRangeEndDate(localizations, selectedStartDate, selectedEndDate, DateTime.now());
+ final String startDateText = _formatRangeStartDate(
+ localizations, selectedStartDate, selectedEndDate);
+ final String endDateText = _formatRangeEndDate(
+ localizations, selectedStartDate, selectedEndDate, DateTime.now());
final TextStyle? headlineStyle = textTheme.headlineMedium;
final TextStyle? startDateStyle = headlineStyle?.apply(
- color: selectedStartDate != null ? headerForeground : headerDisabledForeground,
+ color: selectedStartDate != null
+ ? headerForeground
+ : headerDisabledForeground,
);
final TextStyle? endDateStyle = headlineStyle?.apply(
- color: selectedEndDate != null ? headerForeground : headerDisabledForeground,
+ color:
+ selectedEndDate != null ? headerForeground : headerDisabledForeground,
);
final TextStyle saveButtonStyle = textTheme.headlineMedium!.apply(
color: onConfirm != null ? headerForeground : headerDisabledForeground,
@@ -1493,7 +1536,8 @@ class _CalendarRangePickerDialog extends StatelessWidget {
bottom: PreferredSize(
preferredSize: const Size(double.infinity, 64),
child: Row(children: [
- SizedBox(width: MediaQuery.of(context).size.width < 360 ? 42 : 72),
+ SizedBox(
+ width: MediaQuery.of(context).size.width < 360 ? 42 : 72),
Expanded(
child: Semantics(
label: '$helpText $startDateText to $endDateText',
@@ -1516,7 +1560,9 @@ class _CalendarRangePickerDialog extends StatelessWidget {
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
- Text(' – ', style: startDateStyle,
+ Text(
+ ' – ',
+ style: startDateStyle,
),
Flexible(
child: Text(
@@ -1533,7 +1579,8 @@ class _CalendarRangePickerDialog extends StatelessWidget {
),
),
),
- if (orientation == Orientation.portrait && entryModeButton != null)
+ if (orientation == Orientation.portrait &&
+ entryModeButton != null)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: entryModeButton,
@@ -1577,20 +1624,25 @@ class _CalendarDateRangePicker extends StatefulWidget {
DateTime? currentDate,
required this.onStartDateChanged,
required this.onEndDateChanged,
- }) : initialStartDate = initialStartDate != null ? DateUtils.dateOnly(initialStartDate) : null,
- initialEndDate = initialEndDate != null ? DateUtils.dateOnly(initialEndDate) : null,
+ }) : initialStartDate = initialStartDate != null
+ ? DateUtils.dateOnly(initialStartDate)
+ : null,
+ initialEndDate =
+ initialEndDate != null ? DateUtils.dateOnly(initialEndDate) : null,
assert(firstDate != null),
assert(lastDate != null),
firstDate = DateUtils.dateOnly(firstDate),
lastDate = DateUtils.dateOnly(lastDate),
currentDate = DateUtils.dateOnly(currentDate ?? DateTime.now()) {
assert(
- this.initialStartDate == null || this.initialEndDate == null || !this.initialStartDate!.isAfter(initialEndDate!),
- 'initialStartDate must be on or before initialEndDate.',
+ this.initialStartDate == null ||
+ this.initialEndDate == null ||
+ !this.initialStartDate!.isAfter(initialEndDate!),
+ 'initialStartDate must be on or before initialEndDate.',
);
assert(
- !this.lastDate.isBefore(this.firstDate),
- 'firstDate must be on or before lastDate.',
+ !this.lastDate.isBefore(this.firstDate),
+ 'firstDate must be on or before lastDate.',
);
}
@@ -1616,7 +1668,8 @@ class _CalendarDateRangePicker extends StatefulWidget {
final ValueChanged? onEndDateChanged;
@override
- _CalendarDateRangePickerState createState() => _CalendarDateRangePickerState();
+ _CalendarDateRangePickerState createState() =>
+ _CalendarDateRangePickerState();
}
class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
@@ -1665,7 +1718,8 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
}
}
- int get _numberOfMonths => DateUtils.monthDelta(widget.firstDate, widget.lastDate) + 1;
+ int get _numberOfMonths =>
+ DateUtils.monthDelta(widget.firstDate, widget.lastDate) + 1;
void _vibrate() {
switch (Theme.of(context).platform) {
@@ -1693,7 +1747,9 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
void _updateSelection(DateTime date) {
_vibrate();
setState(() {
- if (_startDate != null && _endDate == null && !date.isBefore(_startDate!)) {
+ if (_startDate != null &&
+ _endDate == null &&
+ !date.isBefore(_startDate!)) {
_endDate = date;
widget.onEndDateChanged?.call(_endDate);
} else {
@@ -1707,15 +1763,20 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
});
}
- Widget _buildMonthItem(BuildContext context, int index, bool beforeInitialMonth) {
+ Widget _buildMonthItem(
+ BuildContext context, int index, bool beforeInitialMonth) {
final int monthIndex = beforeInitialMonth
? _initialMonthIndex - index - 1
: _initialMonthIndex + index;
- final DateTime month = DateUtils.addMonthsToMonthDate(widget.firstDate, monthIndex);
+ final DateTime month =
+ DateUtils.addMonthsToMonthDate(widget.firstDate, monthIndex);
return Stack(
alignment: Alignment.center,
children: [
- Text("${month.month}",style: TextStyle(fontSize: 200,color: Colors.grey.withOpacity(0.1)),),
+ Text(
+ "${month.month}",
+ style: TextStyle(fontSize: 200, color: Colors.grey.withOpacity(0.1)),
+ ),
_MonthItem(
selectedDateStart: _startDate,
selectedDateEnd: _endDate,
@@ -1741,7 +1802,8 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
child: _CalendarKeyboardNavigator(
firstDate: widget.firstDate,
lastDate: widget.lastDate,
- initialFocusedDay: _startDate ?? widget.initialStartDate ?? widget.currentDate,
+ initialFocusedDay:
+ _startDate ?? widget.initialStartDate ?? widget.currentDate,
// In order to prevent performance issues when displaying the
// correct initial month, 2 `SliverList`s are used to split the
// months. The first item in the second SliverList is the initial
@@ -1753,14 +1815,16 @@ class _CalendarDateRangePickerState extends State<_CalendarDateRangePicker> {
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
- (BuildContext context, int index) => _buildMonthItem(context, index, true),
+ (BuildContext context, int index) =>
+ _buildMonthItem(context, index, true),
childCount: _initialMonthIndex,
),
),
SliverList(
key: sliverAfterKey,
delegate: SliverChildBuilderDelegate(
- (BuildContext context, int index) => _buildMonthItem(context, index, false),
+ (BuildContext context, int index) =>
+ _buildMonthItem(context, index, false),
childCount: _numberOfMonths - _initialMonthIndex,
),
),
@@ -1787,16 +1851,22 @@ class _CalendarKeyboardNavigator extends StatefulWidget {
final DateTime initialFocusedDay;
@override
- _CalendarKeyboardNavigatorState createState() => _CalendarKeyboardNavigatorState();
+ _CalendarKeyboardNavigatorState createState() =>
+ _CalendarKeyboardNavigatorState();
}
-class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator> {
-
- final Map _shortcutMap = const {
- SingleActivator(LogicalKeyboardKey.arrowLeft): DirectionalFocusIntent(TraversalDirection.left),
- SingleActivator(LogicalKeyboardKey.arrowRight): DirectionalFocusIntent(TraversalDirection.right),
- SingleActivator(LogicalKeyboardKey.arrowDown): DirectionalFocusIntent(TraversalDirection.down),
- SingleActivator(LogicalKeyboardKey.arrowUp): DirectionalFocusIntent(TraversalDirection.up),
+class _CalendarKeyboardNavigatorState
+ extends State<_CalendarKeyboardNavigator> {
+ final Map _shortcutMap =
+ const {
+ SingleActivator(LogicalKeyboardKey.arrowLeft):
+ DirectionalFocusIntent(TraversalDirection.left),
+ SingleActivator(LogicalKeyboardKey.arrowRight):
+ DirectionalFocusIntent(TraversalDirection.right),
+ SingleActivator(LogicalKeyboardKey.arrowDown):
+ DirectionalFocusIntent(TraversalDirection.down),
+ SingleActivator(LogicalKeyboardKey.arrowUp):
+ DirectionalFocusIntent(TraversalDirection.up),
};
late Map> _actionMap;
late FocusNode _dayGridFocus;
@@ -1808,9 +1878,12 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
super.initState();
_actionMap = >{
- NextFocusIntent: CallbackAction(onInvoke: _handleGridNextFocus),
- PreviousFocusIntent: CallbackAction(onInvoke: _handleGridPreviousFocus),
- DirectionalFocusIntent: CallbackAction(onInvoke: _handleDirectionFocus),
+ NextFocusIntent:
+ CallbackAction(onInvoke: _handleGridNextFocus),
+ PreviousFocusIntent: CallbackAction(
+ onInvoke: _handleGridPreviousFocus),
+ DirectionalFocusIntent: CallbackAction(
+ onInvoke: _handleDirectionFocus),
};
_dayGridFocus = FocusNode(debugLabel: 'Day Grid');
}
@@ -1853,7 +1926,8 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
void _handleDirectionFocus(DirectionalFocusIntent intent) {
assert(_focusedDay != null);
setState(() {
- final DateTime? nextDate = _nextDateInDirection(_focusedDay!, intent.direction);
+ final DateTime? nextDate =
+ _nextDateInDirection(_focusedDay!, intent.direction);
if (nextDate != null) {
_focusedDay = nextDate;
_dayTraversalDirection = intent.direction;
@@ -1861,14 +1935,16 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
});
}
- static const Map _directionOffset = {
+ static const Map _directionOffset =
+ {
TraversalDirection.up: -DateTime.daysPerWeek,
TraversalDirection.right: 1,
TraversalDirection.down: DateTime.daysPerWeek,
TraversalDirection.left: -1,
};
- int _dayDirectionOffset(TraversalDirection traversalDirection, TextDirection textDirection) {
+ int _dayDirectionOffset(
+ TraversalDirection traversalDirection, TextDirection textDirection) {
// Swap left and right if the text direction if RTL
if (textDirection == TextDirection.rtl) {
if (traversalDirection == TraversalDirection.left) {
@@ -1882,8 +1958,10 @@ class _CalendarKeyboardNavigatorState extends State<_CalendarKeyboardNavigator>
DateTime? _nextDateInDirection(DateTime date, TraversalDirection direction) {
final TextDirection textDirection = Directionality.of(context);
- final DateTime nextDate = DateUtils.addDaysToDate(date, _dayDirectionOffset(direction, textDirection));
- if (!nextDate.isBefore(widget.firstDate) && !nextDate.isAfter(widget.lastDate)) {
+ final DateTime nextDate = DateUtils.addDaysToDate(
+ date, _dayDirectionOffset(direction, textDirection));
+ if (!nextDate.isBefore(widget.firstDate) &&
+ !nextDate.isAfter(widget.lastDate)) {
return nextDate;
}
return null;
@@ -1921,7 +1999,8 @@ class _FocusedDate extends InheritedWidget {
@override
bool updateShouldNotify(_FocusedDate oldWidget) {
- return !DateUtils.isSameDay(date, oldWidget.date) || scrollDirection != oldWidget.scrollDirection;
+ return !DateUtils.isSameDay(date, oldWidget.date) ||
+ scrollDirection != oldWidget.scrollDirection;
}
static _FocusedDate? of(BuildContext context) {
@@ -1929,7 +2008,6 @@ class _FocusedDate extends InheritedWidget {
}
}
-
class _DayHeaders extends StatelessWidget {
const _DayHeaders();
@@ -1951,7 +2029,8 @@ class _DayHeaders extends StatelessWidget {
/// _ _ _ _ 1 2 3
/// 4 5 6 7 8 9 10
/// ```
- List _getDayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) {
+ List _getDayHeaders(
+ TextStyle headerStyle, MaterialLocalizations localizations) {
final List result = [];
for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) {
final String weekday = localizations.narrowWeekdays[i];
@@ -1969,8 +2048,10 @@ class _DayHeaders extends StatelessWidget {
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final ColorScheme colorScheme = themeData.colorScheme;
- final TextStyle textStyle = themeData.textTheme.headlineMedium!.apply(color: colorScheme.onSurface);
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final TextStyle textStyle =
+ themeData.textTheme.headlineMedium!.apply(color: colorScheme.onSurface);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final List labels = _getDayHeaders(textStyle, localizations);
// Add leading and trailing containers for edges of the custom grid layout.
@@ -2001,7 +2082,9 @@ class _MonthItemGridDelegate extends SliverGridDelegate {
@override
SliverGridLayout getLayout(SliverConstraints constraints) {
- final double tileWidth = (constraints.crossAxisExtent - 2 * _horizontalPadding) / DateTime.daysPerWeek;
+ final double tileWidth =
+ (constraints.crossAxisExtent - 2 * _horizontalPadding) /
+ DateTime.daysPerWeek;
return _MonthSliverGridLayout(
crossAxisCount: DateTime.daysPerWeek + 2,
dayChildWidth: tileWidth,
@@ -2028,7 +2111,7 @@ class _MonthSliverGridLayout extends SliverGridLayout {
required this.dayChildWidth,
required this.edgeChildWidth,
required this.reverseCrossAxis,
- }) : assert(crossAxisCount != null && crossAxisCount > 0),
+ }) : assert(crossAxisCount != null && crossAxisCount > 0),
assert(dayChildWidth != null && dayChildWidth >= 0),
assert(edgeChildWidth != null && edgeChildWidth >= 0),
assert(reverseCrossAxis != null);
@@ -2077,10 +2160,9 @@ class _MonthSliverGridLayout extends SliverGridLayout {
double _getCrossAxisOffset(double crossAxisStart, bool isPadding) {
if (reverseCrossAxis) {
- return
- ((crossAxisCount - 2) * dayChildWidth + 2 * edgeChildWidth) -
- crossAxisStart -
- (isPadding ? edgeChildWidth : dayChildWidth);
+ return ((crossAxisCount - 2) * dayChildWidth + 2 * edgeChildWidth) -
+ crossAxisStart -
+ (isPadding ? edgeChildWidth : dayChildWidth);
}
return crossAxisStart;
}
@@ -2088,8 +2170,10 @@ class _MonthSliverGridLayout extends SliverGridLayout {
@override
SliverGridGeometry getGeometryForChildIndex(int index) {
final int adjustedIndex = index % crossAxisCount;
- final bool isEdge = adjustedIndex == 0 || adjustedIndex == crossAxisCount - 1;
- final double crossAxisStart = math.max(0, (adjustedIndex - 1) * dayChildWidth + edgeChildWidth);
+ final bool isEdge =
+ adjustedIndex == 0 || adjustedIndex == crossAxisCount - 1;
+ final double crossAxisStart =
+ math.max(0, (adjustedIndex - 1) * dayChildWidth + edgeChildWidth);
return SliverGridGeometry(
scrollOffset: (index ~/ crossAxisCount) * _rowHeight,
@@ -2123,14 +2207,18 @@ class _MonthItem extends StatefulWidget {
required this.lastDate,
required this.displayedMonth,
this.dragStartBehavior = DragStartBehavior.start,
- }) : assert(firstDate != null),
+ }) : assert(firstDate != null),
assert(lastDate != null),
assert(!firstDate.isAfter(lastDate)),
- assert(selectedDateStart == null || !selectedDateStart.isBefore(firstDate)),
+ assert(selectedDateStart == null ||
+ !selectedDateStart.isBefore(firstDate)),
assert(selectedDateEnd == null || !selectedDateEnd.isBefore(firstDate)),
- assert(selectedDateStart == null || !selectedDateStart.isAfter(lastDate)),
+ assert(
+ selectedDateStart == null || !selectedDateStart.isAfter(lastDate)),
assert(selectedDateEnd == null || !selectedDateEnd.isAfter(lastDate)),
- assert(selectedDateStart == null || selectedDateEnd == null || !selectedDateStart.isAfter(selectedDateEnd)),
+ assert(selectedDateStart == null ||
+ selectedDateEnd == null ||
+ !selectedDateStart.isAfter(selectedDateEnd)),
assert(currentDate != null),
assert(onChanged != null),
assert(displayedMonth != null),
@@ -2191,10 +2279,12 @@ class _MonthItemState extends State<_MonthItem> {
@override
void initState() {
super.initState();
- final int daysInMonth = DateUtils.getDaysInMonth(widget.displayedMonth.year, widget.displayedMonth.month);
+ final int daysInMonth = DateUtils.getDaysInMonth(
+ widget.displayedMonth.year, widget.displayedMonth.month);
_dayFocusNodes = List.generate(
daysInMonth,
- (int index) => FocusNode(skipTraversal: true, debugLabel: 'Day ${index + 1}'),
+ (int index) =>
+ FocusNode(skipTraversal: true, debugLabel: 'Day ${index + 1}'),
);
}
@@ -2203,7 +2293,8 @@ class _MonthItemState extends State<_MonthItem> {
super.didChangeDependencies();
// Check to see if the focused date is in this month, if so focus it.
final DateTime? focusedDate = _FocusedDate.of(context)?.date;
- if (focusedDate != null && DateUtils.isSameMonth(widget.displayedMonth, focusedDate)) {
+ if (focusedDate != null &&
+ DateUtils.isSameMonth(widget.displayedMonth, focusedDate)) {
_dayFocusNodes[focusedDate.day - 1].requestFocus();
}
}
@@ -2222,9 +2313,11 @@ class _MonthItemState extends State<_MonthItem> {
void _dayFocusChanged(bool focused) {
if (focused) {
- final TraversalDirection? focusDirection = _FocusedDate.of(context)?.scrollDirection;
+ final TraversalDirection? focusDirection =
+ _FocusedDate.of(context)?.scrollDirection;
if (focusDirection != null) {
- ScrollPositionAlignmentPolicy policy = ScrollPositionAlignmentPolicy.explicit;
+ ScrollPositionAlignmentPolicy policy =
+ ScrollPositionAlignmentPolicy.explicit;
switch (focusDirection) {
case TraversalDirection.up:
case TraversalDirection.left:
@@ -2235,7 +2328,8 @@ class _MonthItemState extends State<_MonthItem> {
policy = ScrollPositionAlignmentPolicy.keepVisibleAtEnd;
break;
}
- Scrollable.ensureVisible(primaryFocus!.context!,
+ Scrollable.ensureVisible(
+ primaryFocus!.context!,
duration: _monthScrollDuration,
alignmentPolicy: policy,
);
@@ -2243,23 +2337,29 @@ class _MonthItemState extends State<_MonthItem> {
}
}
- Widget _buildDayItem(BuildContext context, DateTime dayToBuild, int firstDayOffset, int daysInMonth) {
+ Widget _buildDayItem(BuildContext context, DateTime dayToBuild,
+ int firstDayOffset, int daysInMonth) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
final TextTheme textTheme = theme.textTheme;
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final TextDirection textDirection = Directionality.of(context);
final Color highlightColor = _highlightColor(context);
final int day = dayToBuild.day;
- final bool isDisabled = dayToBuild.isAfter(widget.lastDate) || dayToBuild.isBefore(widget.firstDate);
+ final bool isDisabled = dayToBuild.isAfter(widget.lastDate) ||
+ dayToBuild.isBefore(widget.firstDate);
BoxDecoration? decoration;
TextStyle? itemStyle = textTheme.headlineMedium;
- final bool isRangeSelected = widget.selectedDateStart != null && widget.selectedDateEnd != null;
- final bool isSelectedDayStart = widget.selectedDateStart != null && dayToBuild.isAtSameMomentAs(widget.selectedDateStart!);
- final bool isSelectedDayEnd = widget.selectedDateEnd != null && dayToBuild.isAtSameMomentAs(widget.selectedDateEnd!);
+ final bool isRangeSelected =
+ widget.selectedDateStart != null && widget.selectedDateEnd != null;
+ final bool isSelectedDayStart = widget.selectedDateStart != null &&
+ dayToBuild.isAtSameMomentAs(widget.selectedDateStart!);
+ final bool isSelectedDayEnd = widget.selectedDateEnd != null &&
+ dayToBuild.isAtSameMomentAs(widget.selectedDateEnd!);
final bool isInRange = isRangeSelected &&
dayToBuild.isAfter(widget.selectedDateStart!) &&
dayToBuild.isBefore(widget.selectedDateEnd!);
@@ -2275,7 +2375,8 @@ class _MonthItemState extends State<_MonthItem> {
shape: BoxShape.circle,
);
- if (isRangeSelected && widget.selectedDateStart != widget.selectedDateEnd) {
+ if (isRangeSelected &&
+ widget.selectedDateStart != widget.selectedDateEnd) {
final _HighlightPainterStyle style = isSelectedDayStart
? _HighlightPainterStyle.highlightTrailing
: _HighlightPainterStyle.highlightLeading;
@@ -2293,7 +2394,8 @@ class _MonthItemState extends State<_MonthItem> {
textDirection: textDirection,
);
} else if (isDisabled) {
- itemStyle = textTheme.headlineMedium?.apply(color: colorScheme.onSurface.withOpacity(0.38));
+ itemStyle = textTheme.headlineMedium
+ ?.apply(color: colorScheme.onSurface.withOpacity(0.38));
} else if (DateUtils.isSameDay(widget.currentDate, dayToBuild)) {
// The current day gets a different text color and a circle stroke
// border.
@@ -2310,11 +2412,14 @@ class _MonthItemState extends State<_MonthItem> {
// day of month before the rest of the date, as they are looking
// for the day of month. To do that we prepend day of month to the
// formatted full date.
- String semanticLabel = '${localizations.formatDecimal(day)}, ${localizations.formatFullDate(dayToBuild)}';
+ String semanticLabel =
+ '${localizations.formatDecimal(day)}, ${localizations.formatFullDate(dayToBuild)}';
if (isSelectedDayStart) {
- semanticLabel = localizations.dateRangeStartDateSemanticLabel(semanticLabel);
+ semanticLabel =
+ localizations.dateRangeStartDateSemanticLabel(semanticLabel);
} else if (isSelectedDayEnd) {
- semanticLabel = localizations.dateRangeEndDateSemanticLabel(semanticLabel);
+ semanticLabel =
+ localizations.dateRangeEndDateSemanticLabel(semanticLabel);
}
Widget dayWidget = Container(
@@ -2359,7 +2464,8 @@ class _MonthItemState extends State<_MonthItem> {
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final TextTheme textTheme = themeData.textTheme;
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final int year = widget.displayedMonth.year;
final int month = widget.displayedMonth.month;
final int daysInMonth = DateUtils.getDaysInMonth(year, month);
@@ -2401,38 +2507,40 @@ class _MonthItemState extends State<_MonthItem> {
);
final List weekList = dayItems.sublist(start, end);
- final DateTime dateAfterLeadingPadding = DateTime(year, month, start - dayOffset + 1);
+ final DateTime dateAfterLeadingPadding =
+ DateTime(year, month, start - dayOffset + 1);
// Only color the edge container if it is after the start date and
// on/before the end date.
- final bool isLeadingInRange =
- !(dayOffset > 0 && i == 0) &&
- widget.selectedDateStart != null &&
- widget.selectedDateEnd != null &&
- dateAfterLeadingPadding.isAfter(widget.selectedDateStart!) &&
- !dateAfterLeadingPadding.isAfter(widget.selectedDateEnd!);
+ final bool isLeadingInRange = !(dayOffset > 0 && i == 0) &&
+ widget.selectedDateStart != null &&
+ widget.selectedDateEnd != null &&
+ dateAfterLeadingPadding.isAfter(widget.selectedDateStart!) &&
+ !dateAfterLeadingPadding.isAfter(widget.selectedDateEnd!);
weekList.insert(0, _buildEdgeContainer(context, isLeadingInRange));
// Only add a trailing edge container if it is for a full week and not a
// partial week.
- if (end < dayItems.length || (end == dayItems.length && dayItems.length % DateTime.daysPerWeek == 0)) {
+ if (end < dayItems.length ||
+ (end == dayItems.length &&
+ dayItems.length % DateTime.daysPerWeek == 0)) {
final DateTime dateBeforeTrailingPadding =
- DateTime(year, month, end - dayOffset);
+ DateTime(year, month, end - dayOffset);
// Only color the edge container if it is on/after the start date and
// before the end date.
- final bool isTrailingInRange =
- widget.selectedDateStart != null &&
- widget.selectedDateEnd != null &&
- !dateBeforeTrailingPadding.isBefore(widget.selectedDateStart!) &&
- dateBeforeTrailingPadding.isBefore(widget.selectedDateEnd!);
+ final bool isTrailingInRange = widget.selectedDateStart != null &&
+ widget.selectedDateEnd != null &&
+ !dateBeforeTrailingPadding.isBefore(widget.selectedDateStart!) &&
+ dateBeforeTrailingPadding.isBefore(widget.selectedDateEnd!);
weekList.add(_buildEdgeContainer(context, isTrailingInRange));
}
paddedDayItems.addAll(weekList);
}
- final double maxWidth = MediaQuery.of(context).orientation == Orientation.landscape
- ? _maxCalendarWidthLandscape
- : _maxCalendarWidthPortrait;
+ final double maxWidth =
+ MediaQuery.of(context).orientation == Orientation.landscape
+ ? _maxCalendarWidthLandscape
+ : _maxCalendarWidthPortrait;
return Column(
children: [
Container(
@@ -2443,7 +2551,8 @@ class _MonthItemState extends State<_MonthItem> {
child: ExcludeSemantics(
child: Text(
localizations.formatMonthYear(widget.displayedMonth),
- style: textTheme.headlineMedium!.apply(color: themeData.colorScheme.onSurface),
+ style: textTheme.headlineMedium!
+ .apply(color: themeData.colorScheme.onSurface),
),
),
),
@@ -2510,7 +2619,8 @@ class _HighlightPainter extends CustomPainter {
..style = PaintingStyle.fill;
final Rect rectLeft = Rect.fromLTWH(0, 0, size.width / 2, size.height);
- final Rect rectRight = Rect.fromLTWH(size.width / 2, 0, size.width / 2, size.height);
+ final Rect rectRight =
+ Rect.fromLTWH(size.width / 2, 0, size.width / 2, size.height);
switch (style) {
case _HighlightPainterStyle.highlightTrailing:
@@ -2565,8 +2675,10 @@ class _InputDateRangePickerDialog extends StatelessWidget {
final String? helpText;
final Widget? entryModeButton;
- String _formatDateRange(BuildContext context, DateTime? start, DateTime? end, DateTime now) {
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ String _formatDateRange(
+ BuildContext context, DateTime? start, DateTime? end, DateTime now) {
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final String startText = _formatRangeStartDate(localizations, start, end);
final String endText = _formatRangeEndDate(localizations, start, end, now);
if (start == null || end == null) {
@@ -2583,18 +2695,22 @@ class _InputDateRangePickerDialog extends StatelessWidget {
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final ColorScheme colorScheme = theme.colorScheme;
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
final Orientation orientation = MediaQuery.of(context).orientation;
final TextTheme textTheme = theme.textTheme;
- final Color onPrimarySurfaceColor = colorScheme.brightness == Brightness.light
- ? colorScheme.onPrimary
- : colorScheme.onSurface;
+ final Color onPrimarySurfaceColor =
+ colorScheme.brightness == Brightness.light
+ ? colorScheme.onPrimary
+ : colorScheme.onSurface;
final TextStyle? dateStyle = orientation == Orientation.landscape
? textTheme.headlineMedium?.apply(color: onPrimarySurfaceColor)
: textTheme.headlineMedium?.apply(color: onPrimarySurfaceColor);
- final String dateText = _formatDateRange(context, selectedStartDate, selectedEndDate, currentDate!);
- final String semanticDateText = selectedStartDate != null && selectedEndDate != null
+ final String dateText = _formatDateRange(
+ context, selectedStartDate, selectedEndDate, currentDate!);
+ final String semanticDateText = selectedStartDate != null &&
+ selectedEndDate != null
? '${localizations.formatMediumDate(selectedStartDate!)} – ${localizations.formatMediumDate(selectedEndDate!)}'
: '';
@@ -2684,8 +2800,11 @@ class _InputDateRangePicker extends StatefulWidget {
this.fieldEndLabelText,
this.autofocus = false,
this.autovalidate = false,
- }) : initialStartDate = initialStartDate == null ? null : DateUtils.dateOnly(initialStartDate),
- initialEndDate = initialEndDate == null ? null : DateUtils.dateOnly(initialEndDate),
+ }) : initialStartDate = initialStartDate == null
+ ? null
+ : DateUtils.dateOnly(initialStartDate),
+ initialEndDate =
+ initialEndDate == null ? null : DateUtils.dateOnly(initialEndDate),
assert(firstDate != null),
firstDate = DateUtils.dateOnly(firstDate),
assert(lastDate != null),
@@ -2785,7 +2904,8 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
if (_startDate != null) {
_startInputText = localizations.formatCompactDate(_startDate!);
final bool selectText = widget.autofocus && !_autoSelected;
@@ -2810,7 +2930,8 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
final String? endError = _validateDate(_endDate);
if (startError == null && endError == null) {
if (_startDate!.isAfter(_endDate!)) {
- startError = widget.errorInvalidRangeText ?? MaterialLocalizations.of(context).invalidDateRangeLabel;
+ startError = widget.errorInvalidRangeText ??
+ MaterialLocalizations.of(context).invalidDateRangeLabel;
}
}
setState(() {
@@ -2821,23 +2942,29 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
}
DateTime? _parseDate(String? text) {
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
return localizations.parseCompactDate(text);
}
String? _validateDate(DateTime? date) {
if (date == null) {
- return widget.errorFormatText ?? MaterialLocalizations.of(context).invalidDateFormatLabel;
- } else if (date.isBefore(widget.firstDate) || date.isAfter(widget.lastDate)) {
- return widget.errorInvalidText ?? MaterialLocalizations.of(context).dateOutOfRangeLabel;
+ return widget.errorFormatText ??
+ MaterialLocalizations.of(context).invalidDateFormatLabel;
+ } else if (date.isBefore(widget.firstDate) ||
+ date.isAfter(widget.lastDate)) {
+ return widget.errorInvalidText ??
+ MaterialLocalizations.of(context).dateOutOfRangeLabel;
}
return null;
}
- void _updateController(TextEditingController controller, String text, bool selectText) {
+ void _updateController(
+ TextEditingController controller, String text, bool selectText) {
TextEditingValue textEditingValue = controller.value.copyWith(text: text);
if (selectText) {
- textEditingValue = textEditingValue.copyWith(selection: TextSelection(
+ textEditingValue = textEditingValue.copyWith(
+ selection: TextSelection(
baseOffset: 0,
extentOffset: text.length,
));
@@ -2869,8 +2996,10 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
@override
Widget build(BuildContext context) {
- final MaterialLocalizations localizations = MaterialLocalizations.of(context);
- final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;
+ final MaterialLocalizations localizations =
+ MaterialLocalizations.of(context);
+ final InputDecorationThemeData inputTheme =
+ Theme.of(context).inputDecorationTheme;
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -2881,7 +3010,8 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
border: inputTheme.border ?? const UnderlineInputBorder(),
filled: inputTheme.filled,
hintText: widget.fieldStartHintText ?? localizations.dateHelpText,
- labelText: widget.fieldStartLabelText ?? localizations.dateRangeStartLabel,
+ labelText: widget.fieldStartLabelText ??
+ localizations.dateRangeStartLabel,
errorText: _startErrorText,
),
keyboardType: TextInputType.datetime,
@@ -2897,7 +3027,8 @@ class _InputDateRangePickerState extends State<_InputDateRangePicker> {
border: inputTheme.border ?? const UnderlineInputBorder(),
filled: inputTheme.filled,
hintText: widget.fieldEndHintText ?? localizations.dateHelpText,
- labelText: widget.fieldEndLabelText ?? localizations.dateRangeEndLabel,
+ labelText:
+ widget.fieldEndLabelText ?? localizations.dateRangeEndLabel,
errorText: _endErrorText,
),
keyboardType: TextInputType.datetime,
diff --git a/modules/basic_system/components/lib/project_ui/refresh/refresh.dart b/modules/basic_system/components/lib/project_ui/refresh/refresh.dart
index fa66aedd0..27edcb913 100644
--- a/modules/basic_system/components/lib/project_ui/refresh/refresh.dart
+++ b/modules/basic_system/components/lib/project_ui/refresh/refresh.dart
@@ -1,2 +1,2 @@
export 'refresh_config_wrapper.dart';
-export 'package:refresh/refresh.dart' show SmartRefresher,RefreshController;
\ No newline at end of file
+export 'package:tolyui_refresh/tolyui_refresh.dart' show TolyRefresh,RefreshController;
\ No newline at end of file
diff --git a/modules/basic_system/components/lib/project_ui/refresh/refresh_config_wrapper.dart b/modules/basic_system/components/lib/project_ui/refresh/refresh_config_wrapper.dart
index 23d5dc367..d9ffba556 100644
--- a/modules/basic_system/components/lib/project_ui/refresh/refresh_config_wrapper.dart
+++ b/modules/basic_system/components/lib/project_ui/refresh/refresh_config_wrapper.dart
@@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-import 'package:refresh/refresh.dart';
+import 'package:tolyui_refresh/tolyui_refresh.dart';
import 'toly_refresh_indicator.dart';
@@ -11,10 +11,15 @@ class RefreshConfigWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
Color themeColor = Theme.of(context).primaryColor;
- return RefreshConfiguration(
+ return RefreshConfigScope(
headerTriggerDistance: 60,
topHitBoundary: 20,
child: child,
+ springDescription: SpringDescription.withDampingRatio(
+ mass: 0.5,
+ stiffness: 100.0,
+ ratio: 1.1,
+ ),
headerBuilder: () => const TolyRefreshIndicator(),
footerBuilder: () => CustomFooter(
builder: (BuildContext context, LoadStatus? mode) {
@@ -25,8 +30,7 @@ class RefreshConfigWrapper extends StatelessWidget {
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Icon(Icons.arrow_upward, color: themeColor),
- Text("上拉加载",
- style: TextStyle(color: themeColor, height: 1)),
+ Text("上拉加载", style: TextStyle(color: themeColor, height: 1)),
],
);
} else if (mode == LoadStatus.loading) {
diff --git a/modules/basic_system/components/lib/project_ui/refresh/toly_refresh_indicator.dart b/modules/basic_system/components/lib/project_ui/refresh/toly_refresh_indicator.dart
index d44ac625f..cd239d439 100644
--- a/modules/basic_system/components/lib/project_ui/refresh/toly_refresh_indicator.dart
+++ b/modules/basic_system/components/lib/project_ui/refresh/toly_refresh_indicator.dart
@@ -4,7 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'
hide RefreshIndicator, RefreshIndicatorState;
import 'package:flutter/services.dart';
-import 'package:refresh/refresh.dart';
+import 'package:tolyui_refresh/tolyui_refresh.dart';
class TolyRefreshIndicator extends RefreshIndicator {
const TolyRefreshIndicator({super.key});
@@ -22,8 +22,8 @@ class _TolyRefreshIndicatorState
@override
void initState() {
super.initState();
- _iconRotateCtrl =
- AnimationController(vsync: this, duration: const Duration(milliseconds: 250));
+ _iconRotateCtrl = AnimationController(
+ vsync: this, duration: const Duration(milliseconds: 250));
rotateAnima = Tween(begin: 0.0, end: -0.5).animate(_iconRotateCtrl);
}
@@ -63,8 +63,13 @@ class _TolyRefreshIndicatorState
@override
Widget buildContent(BuildContext context, RefreshStatus mode) {
Widget child = switch (mode) {
- RefreshStatus.refreshing => const CupertinoActivityIndicator(radius: 10,),
- RefreshStatus.completed => const Icon(Icons.check,color: Colors.green,),
+ RefreshStatus.refreshing => const CupertinoActivityIndicator(
+ radius: 10,
+ ),
+ RefreshStatus.completed => const Icon(
+ Icons.check,
+ color: Colors.green,
+ ),
RefreshStatus.idle || RefreshStatus.canRefresh => RotationTransition(
turns: rotateAnima,
child: Icon(
diff --git a/modules/basic_system/l10n/lib/enum/language.dart b/modules/basic_system/l10n/lib/enum/language.dart
index 2fbd17a56..7f969262d 100644
--- a/modules/basic_system/l10n/lib/enum/language.dart
+++ b/modules/basic_system/l10n/lib/enum/language.dart
@@ -1,19 +1,20 @@
import 'dart:ui';
enum Language {
- zh_CN(locale: Locale('zh','CN'), label: '简体中文'),
- en_US(locale: Locale('en','US'), label: 'English'),
- ru_RU(locale: Locale('ru','RU'), label: 'Русский'),
- fr_FR(locale: Locale('fr','FR'), label: 'Français'),
- ko_KR(locale: Locale('ko','KR'), label: '한국어'),
- de_DE(locale: Locale('de','DE'), label: 'Deutsch'),
- ja_JP(locale: Locale('ja','JP'), label: '日本語'),
- it_IT(locale: Locale('it','IT'), label: 'Italiano'),
- pt_PT(locale: Locale('pt','PT'), label: 'Português'),
- es_ES(locale: Locale('es','ES'), label: 'Español'),
+ zh_CN(locale: Locale('zh', 'CN'), label: '简体中文'),
+ en_US(locale: Locale('en', 'US'), label: 'English'),
+ // ru_RU(locale: Locale('ru','RU'), label: 'Русский'),
+ // fr_FR(locale: Locale('fr','FR'), label: 'Français'),
+ // ko_KR(locale: Locale('ko','KR'), label: '한국어'),
+ // de_DE(locale: Locale('de','DE'), label: 'Deutsch'),
+ // ja_JP(locale: Locale('ja','JP'), label: '日本語'),
+ // it_IT(locale: Locale('it','IT'), label: 'Italiano'),
+ // pt_PT(locale: Locale('pt','PT'), label: 'Português'),
+ // es_ES(locale: Locale('es','ES'), label: 'Español'),
;
- String get code => '${locale.languageCode}-${locale.countryCode}'.toLowerCase();
+ String get code =>
+ '${locale.languageCode}-${locale.countryCode}'.toLowerCase();
final Locale locale;
final String label;
diff --git a/modules/basic_system/storage/lib/src/app_storage.dart b/modules/basic_system/storage/lib/src/app_storage.dart
index 7e671a454..70af2ad9f 100644
--- a/modules/basic_system/storage/lib/src/app_storage.dart
+++ b/modules/basic_system/storage/lib/src/app_storage.dart
@@ -1,11 +1,10 @@
-
import 'package:storage/storage.dart';
+import 'db_storage/flutter/article_db_store.dart';
import 'db_storage/flutter/flutter_db_store.dart';
import 'db_storage/flutter_unit/flutter_unit_db_store.dart';
class AppStorage {
-
AppStorage._();
static AppStorage? _instance;
@@ -15,17 +14,21 @@ class AppStorage {
final FlutterDbStore _flutterDb = FlutterDbStore();
final FlutterUnitDbStore _flutterUnitDb = FlutterUnitDbStore();
+ final ArticleDbStore _articleDb = ArticleDbStore();
+
FlutterDbStore get flutter => _flutterDb;
+ ArticleDbStore get article => _articleDb;
FlutterUnitDbStore get flutterUnit => _flutterUnitDb;
- Future init() async{
+ Future init() async {
await _flutterDb.open();
await _flutterUnitDb.open();
+ await _articleDb.open();
}
- void close() async{
+ void close() async {
await _flutterDb.close();
await _flutterUnitDb.close();
+ await _articleDb.close();
}
-
}
diff --git a/modules/basic_system/storage/lib/src/db_storage/flutter/article_db_store.dart b/modules/basic_system/storage/lib/src/db_storage/flutter/article_db_store.dart
new file mode 100644
index 000000000..2bf579e54
--- /dev/null
+++ b/modules/basic_system/storage/lib/src/db_storage/flutter/article_db_store.dart
@@ -0,0 +1,27 @@
+import 'dart:async';
+import 'package:sqflite/sqflite.dart';
+import 'package:sqflite_common_ffi/sqflite_ffi.dart';
+import 'package:fx_dao/fx_dao.dart';
+
+import 'package:widget_module/widget_module.dart';
+import 'package:artifact/artifact.dart';
+
+class ArticleDbStore extends FxDb {
+ @override
+ String get dbname => 'article.db';
+
+ @override
+ int get version => 1;
+
+ @override
+ Future onCreate(Database db, int version) async {}
+
+ @override
+ Iterable<(int, MigrationOperation)> get migrations => [];
+
+ @override
+ Iterable get tables => [
+ ColumnizeDao(),
+ ArticleDao(),
+ ];
+}
diff --git a/modules/basic_system/storage/lib/src/db_storage/flutter/flutter_db_store.dart b/modules/basic_system/storage/lib/src/db_storage/flutter/flutter_db_store.dart
index e78b638c1..3386bd79c 100644
--- a/modules/basic_system/storage/lib/src/db_storage/flutter/flutter_db_store.dart
+++ b/modules/basic_system/storage/lib/src/db_storage/flutter/flutter_db_store.dart
@@ -4,7 +4,7 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:fx_dao/fx_dao.dart';
import 'package:widget_module/widget_module.dart';
-import 'package:artifact/artifact.dart';
+import 'package:widget_repository/widget_repository.dart';
class FlutterDbStore extends FxDb {
@override
@@ -27,10 +27,9 @@ class FlutterDbStore extends FxDb {
@override
Iterable get tables => [
- ColumnizeDao(),
- ArticleDao(),
CategoryDao(),
WidgetDao(),
+ WidgetStatisticsDao(),
NodeDao(),
LikeDao(),
];
diff --git a/modules/basic_system/toly_ui/lib/ti/panel.dart b/modules/basic_system/toly_ui/lib/ti/panel.dart
index 2fc3bd777..cc6d0e2fb 100644
--- a/modules/basic_system/toly_ui/lib/ti/panel.dart
+++ b/modules/basic_system/toly_ui/lib/ti/panel.dart
@@ -1,21 +1,30 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-
class Panel extends StatelessWidget {
final double radius;
final Color? color;
final Widget? child;
final EdgeInsetsGeometry? margin;
+ final BoxConstraints? constraints;
+ final AlignmentGeometry? alignment;
- const Panel({Key? key, this.radius = 5.0, this.color, this.child, this.margin=const EdgeInsets.all(10)}) : super(key: key);
+ const Panel(
+ {Key? key,
+ this.radius = 5.0,
+ this.color,
+ this.child,
+ this.margin = const EdgeInsets.all(10),
+ this.constraints,
+ this.alignment})
+ : super(key: key);
@override
Widget build(BuildContext context) {
-
return Container(
- alignment: Alignment.centerLeft,
+ alignment: alignment ?? Alignment.centerLeft,
padding: margin,
+ constraints: constraints,
decoration: BoxDecoration(
color: color ?? const Color(0xffF6F8FA),
borderRadius: BorderRadius.all(Radius.circular(radius))),
@@ -23,5 +32,3 @@ class Panel extends StatelessWidget {
);
}
}
-
-
diff --git a/modules/knowledge_system/artifact/lib/src/articles/data/repository/article_repository.dart b/modules/knowledge_system/artifact/lib/src/articles/data/repository/article_repository.dart
index 094a7a982..8f27f1f85 100644
--- a/modules/knowledge_system/artifact/lib/src/articles/data/repository/article_repository.dart
+++ b/modules/knowledge_system/artifact/lib/src/articles/data/repository/article_repository.dart
@@ -1,16 +1,13 @@
-
import 'package:storage/storage.dart';
import '../dao/article_dao.dart';
import '../exp.dart';
-
-
// 仓储: 提供数据
class ArticleRepository {
const ArticleRepository();
- ArticleDao get dao => AppStorage().flutter();
+ ArticleDao get dao => AppStorage().article();
// 从数据库加载资源
Future> queryByDb(ArticleFilter filter) async {
diff --git a/modules/knowledge_system/artifact/lib/src/articles/data/repository/columnize_repository.dart b/modules/knowledge_system/artifact/lib/src/articles/data/repository/columnize_repository.dart
index 60ac4d529..7b2b53c5d 100644
--- a/modules/knowledge_system/artifact/lib/src/articles/data/repository/columnize_repository.dart
+++ b/modules/knowledge_system/artifact/lib/src/articles/data/repository/columnize_repository.dart
@@ -1,15 +1,12 @@
-
import 'package:storage/storage.dart';
import '../exp.dart';
// 仓储: 提供数据
class ColumnizeRepository {
-
const ColumnizeRepository();
- ColumnizeDao get dao => AppStorage().flutter();
-
+ ColumnizeDao get dao => AppStorage().article();
// 从数据库加载资源
Future> queryByDb({
@@ -22,6 +19,4 @@ class ColumnizeRepository {
);
return caches;
}
-
-
}
diff --git a/modules/knowledge_system/artifact/lib/src/articles/view/article/sliver_article.dart b/modules/knowledge_system/artifact/lib/src/articles/view/article/sliver_article.dart
index 155a56962..2ec98f1c6 100644
--- a/modules/knowledge_system/artifact/lib/src/articles/view/article/sliver_article.dart
+++ b/modules/knowledge_system/artifact/lib/src/articles/view/article/sliver_article.dart
@@ -81,8 +81,9 @@ class ArticlePanel extends StatelessWidget {
builder: (_) => ArticleDetailPage(article: article),
),
);
+ } else {
+ _launchURL('https://juejin.cn${article.url}');
}
- _launchURL('https://juejin.cn${article.url}');
}
void _launchURL(String url) async {
diff --git a/modules/knowledge_system/artifact/lib/src/articles/view/article/toly_article_scroll_page.dart b/modules/knowledge_system/artifact/lib/src/articles/view/article/toly_article_scroll_page.dart
index d1deb5d09..81815e97a 100644
--- a/modules/knowledge_system/artifact/lib/src/articles/view/article/toly_article_scroll_page.dart
+++ b/modules/knowledge_system/artifact/lib/src/articles/view/article/toly_article_scroll_page.dart
@@ -1,11 +1,10 @@
-
import 'package:artifact/artifact.dart';
import 'package:components/components.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:refresh/refresh.dart';
+import 'package:tolyui_refresh/tolyui_refresh.dart';
import '../../bloc/exp.dart';
@@ -20,7 +19,6 @@ class TolyArticleScrollPage extends StatefulWidget {
}
class _TolyArticleScrollPageState extends State {
-
final RefreshController _refreshController =
RefreshController(initialRefresh: false);
@@ -35,7 +33,7 @@ class _TolyArticleScrollPageState extends State {
@override
Widget build(BuildContext context) {
return RefreshConfigWrapper(
- child: SmartRefresher(
+ child: TolyRefresh(
enablePullUp: true,
onRefresh: _onRefresh,
onLoading: _loadMore,
@@ -46,7 +44,7 @@ class _TolyArticleScrollPageState extends State {
// handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
// ),
SliverPadding(
- padding: EdgeInsets.only(top: 10,bottom: 10),
+ padding: EdgeInsets.only(top: 10, bottom: 10),
sliver: const SliverToBoxAdapter(
child: ColumnizeViewPage(),
),
@@ -76,7 +74,7 @@ class _TolyArticleScrollPageState extends State {
await context.read().loadNextPageMore();
// int length = data.length;
ArticleState state = bloc.state;
- if(state is ArticleWithData){
+ if (state is ArticleWithData) {
if (state.data.length >= state.total) {
_refreshController.loadNoData();
await Future.delayed(Duration(milliseconds: 2000));
@@ -86,8 +84,5 @@ class _TolyArticleScrollPageState extends State {
_refreshController.loadComplete();
}
-
}
-
-
}
diff --git a/modules/knowledge_system/artifact/lib/src/articles/view/artifact_page.dart b/modules/knowledge_system/artifact/lib/src/articles/view/artifact_page.dart
index 101e3bacc..1e7c65204 100644
--- a/modules/knowledge_system/artifact/lib/src/articles/view/artifact_page.dart
+++ b/modules/knowledge_system/artifact/lib/src/articles/view/artifact_page.dart
@@ -47,7 +47,7 @@ class _ArtifactPageState extends State
@override
void initState() {
super.initState();
- controller = TabController(length: 4, vsync: this);
+ controller = TabController(length: 2, vsync: this);
controller.addListener(_listen);
data = List.generate(5, (index) => 'Init $index');
}
@@ -70,8 +70,10 @@ class _ArtifactPageState extends State
return MultiBlocProvider(
providers: [
- BlocProvider(create: (_) => ColumnizeBloc(cRepository)..init()),
- BlocProvider(create: (_) => ArticleBloc(aRepository)..init()),
+ BlocProvider(
+ create: (_) => ColumnizeBloc(cRepository)..init()),
+ BlocProvider(
+ create: (_) => ArticleBloc(aRepository)..init()),
],
child: Scaffold(
endDrawer: SortSettings(),
@@ -92,7 +94,8 @@ class _ArtifactPageState extends State
children: [
GestureDetector(
onTap: () {
- _launchURL('https://github.com/toly1994328/FlutterUnit/blob/master/packages/algorithm/lib/src/algorithm/sort/functions/${name}.dart');
+ _launchURL(
+ 'https://github.com/toly1994328/FlutterUnit/blob/master/packages/algorithm/lib/src/algorithm/sort/functions/${name}.dart');
},
child: Text(
'查看排序源码',
@@ -109,8 +112,8 @@ class _ArtifactPageState extends State
Expanded(child: SortPaper()),
],
),
- BuildingPanel(),
- BuildingPanel(),
+ // BuildingPanel(),
+ // BuildingPanel(),
],
),
),
@@ -121,14 +124,12 @@ class _ArtifactPageState extends State
_launchURL(String url) async {
Uri uri = Uri.parse(url);
if (await canLaunchUrl(Uri.parse(url))) {
- await launchUrl(uri,mode: LaunchMode.externalApplication);
+ await launchUrl(uri, mode: LaunchMode.externalApplication);
} else {
debugPrint('Could not launch $url');
}
}
-
-
List _buildAppBar(BuildContext context, bool innerBoxIsScrolled) {
// print('innerBoxIsScrolled:$innerBoxIsScrolled');
return [
@@ -203,8 +204,7 @@ class _ArtifactPageState extends State
// ),
bottom: TabBar(
controller: controller,
- tabs:
- [
+ tabs: [
Tab(
// icon: Icon(Icons.account_balance_wallet_outlined),
text: context.l10n.knowledgeTabToly,
@@ -213,14 +213,14 @@ class _ArtifactPageState extends State
// icon: Icon(Icons.account_balance_wallet_outlined),
text: context.l10n.knowledgeTabAlgo,
),
- Tab(
- // icon: Icon(Icons.account_balance_wallet_outlined),
- text:context.l10n.knowledgeTabLayout,
- ),
- Tab(
- // icon: Icon(Icons.account_balance_wallet_outlined),
- text:context.l10n.knowledgeTabPoint,
- ),
+ // Tab(
+ // // icon: Icon(Icons.account_balance_wallet_outlined),
+ // text:context.l10n.knowledgeTabLayout,
+ // ),
+ // Tab(
+ // // icon: Icon(Icons.account_balance_wallet_outlined),
+ // text:context.l10n.knowledgeTabPoint,
+ // ),
],
),
), // )
diff --git a/modules/widget_system/widget_module/lib/blocs/action/widget_action.dart b/modules/widget_system/widget_module/lib/blocs/action/widget_action.dart
index 422951199..09b814078 100644
--- a/modules/widget_system/widget_module/lib/blocs/action/widget_action.dart
+++ b/modules/widget_system/widget_module/lib/blocs/action/widget_action.dart
@@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:app/app.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:widget_module/blocs/blocs.dart';
+import 'package:widget_ui/widget_ui.dart';
import '../../widget_module.dart';
@@ -16,6 +17,17 @@ extension WidgetContext on BuildContext {
}
void toggleLike(int widgetId) {
- read().add(ToggleLikeWidgetEvent(id: widgetId));
+ read().toggle(widgetId);
+ }
+
+ void handleWidgetAction(WidgetAction value) {
+ switch (value) {
+ case JumpWidgetDetail():
+ String? name = value.widgetName ?? value.model?.name;
+ push('${AppRoute.widgetDetail.url}$name', extra: value.model);
+ return;
+ case ToggleLikeWidget():
+ toggleLike(value.widgetId);
+ }
}
}
diff --git a/modules/widget_system/widget_module/lib/blocs/blocs.dart b/modules/widget_system/widget_module/lib/blocs/blocs.dart
index 3844b6083..443306fb9 100644
--- a/modules/widget_system/widget_module/lib/blocs/blocs.dart
+++ b/modules/widget_system/widget_module/lib/blocs/blocs.dart
@@ -1,5 +1,4 @@
export 'category_bloc/category_bloc.dart';
export 'category_widget_bloc/category_widget_bloc.dart';
-export 'liked_widget_bloc/liked_widget_bloc.dart';
export 'widget_detail_bloc/widget_detail_bloc.dart';
-export 'widgets_bloc/widgets_bloc.dart';
\ No newline at end of file
+export 'widgets_bloc/widgets_bloc.dart';
diff --git a/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_bloc.dart b/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_bloc.dart
index b263c2bdc..9ddea8b70 100644
--- a/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_bloc.dart
+++ b/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_bloc.dart
@@ -2,8 +2,6 @@ import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:widget_repository/widget_repository.dart';
-
-
import '../category_bloc/category_bloc.dart';
part 'category_widget_event.dart';
@@ -18,24 +16,26 @@ class CategoryWidgetBloc
final CategoryBloc categoryBloc;
CategoryWidgetBloc({required this.categoryBloc})
- : super(CategoryWidgetEmptyState()){
+ : super(CategoryWidgetEmptyState()) {
on(_onEventLoadCategoryWidget);
on(_onEventToggleCategoryWidget);
}
CategoryRepository get repository => categoryBloc.repository;
- void _onEventLoadCategoryWidget(EventLoadCategoryWidget event, Emitter emit) async{
+ void _onEventLoadCategoryWidget(
+ EventLoadCategoryWidget event, Emitter emit) async {
final widgets =
- await repository.loadCategoryWidgets(categoryId: event.categoryId);
- widgets.isNotEmpty
+ await repository.loadCategoryWidgets(categoryId: event.categoryId);
+ widgets.isNotEmpty
? emit(CategoryWidgetLoadedState(widgets))
: emit(CategoryWidgetEmptyState());
categoryBloc.add(const EventLoadCategory());
}
- void _onEventToggleCategoryWidget(EventToggleCategoryWidget event, Emitter emit) async{
+ void _onEventToggleCategoryWidget(EventToggleCategoryWidget event,
+ Emitter emit) async {
await repository.toggleCategory(event.categoryId, event.widgetId);
- add(EventLoadCategoryWidget(event.categoryId));
+ add(EventLoadCategoryWidget(event.categoryId, 'zh-cn'));
}
}
diff --git a/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_event.dart b/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_event.dart
index 1e2d62bc2..45a23fd69 100644
--- a/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_event.dart
+++ b/modules/widget_system/widget_module/lib/blocs/category_widget_bloc/category_widget_event.dart
@@ -2,28 +2,29 @@ part of 'category_widget_bloc.dart';
/// create by 张风捷特烈 on 2020-04-21
/// contact me by email 1981462002@qq.com
-/// 说明:
+/// 说明:
-abstract class CategoryWidgetEvent extends Equatable{
+abstract class CategoryWidgetEvent extends Equatable {
@override
List