diff --git a/flutter_monisuo/.metadata b/flutter_monisuo/.metadata
index 87ba2b3..b3e578d 100644
--- a/flutter_monisuo/.metadata
+++ b/flutter_monisuo/.metadata
@@ -15,7 +15,10 @@ migration:
- platform: root
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
- - platform: web
+ - platform: android
+ create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
+ base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
+ - platform: ios
create_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
base_revision: ff37bef603469fb030f2b72995ab929ccfc227f0
diff --git a/flutter_monisuo/IMPLEMENTATION_PLAN.md b/flutter_monisuo/IMPLEMENTATION_PLAN.md
deleted file mode 100644
index 0766648..0000000
--- a/flutter_monisuo/IMPLEMENTATION_PLAN.md
+++ /dev/null
@@ -1,307 +0,0 @@
-# Monisuo 主题现代化实施计划
-
-## Status
-STATUS: IN_PROGRESS
-
-## Phase 7: 现代化改造 v2.0(当前任务)
-
-### 目标
-将 Flutter Monisuo 应用打造为现代化、简约、专业的虚拟货币交易平台。
-
-### 设计规范参考: `specs/modernization-v2.md`
-
-### 7.1 P0 - 核心基础设施 ✅
-- [x] 7.1.1 创建 ThemeProvider(明暗主题切换)
-- [x] 7.1.2 更新 main.dart 使用 MultiProvider
-- [x] 7.1.3 创建浅色主题配置
-- [x] 7.1.4 更新深色主题配置
-- [x] 7.1.5 在 mine_page 添加主题切换开关
-- [x] 7.1.6 更新颜色系统(app_colors.dart)
-- [x] 7.1.7 集成 Google Fonts(Inter + JetBrains Mono)
-
-### 7.2 P1 - 组件现代化 ✅
-- [x] 7.2.1 创建间距系统(app_spacing.dart)
-- [x] 7.2.2 创建圆角系统(app_border_radius.dart)
-- [x] 7.2.3 优化按钮组件
-- [x] 7.2.4 优化卡片组件
-- [x] 7.2.5 优化输入框组件
-
-### 7.3 P2 - 弹窗现代化 ✅
-- [x] 7.3.1 创建现代弹窗模板
-- [x] 7.3.2 创建现代底部抽屉模板
-- [x] 7.3.3 更新所有 AlertDialog
-
-### 7.4 P3 - 页面优化 ✅
-- [x] 7.4.1 登录页面现代化
-- [x] 7.4.2 首页现代化
-- [x] 7.4.3 行情页现代化
-- [x] 7.4.4 交易页现代化
-- [x] 7.4.5 资产页现代化
-- [x] 7.4.6 我的页面现代化
-
-### 7.5 P4 - 验证与优化 ✅
-- [x] 7.5.1 flutter analyze 通过 (0 errors, warnings only)
-- [x] 7.5.2 所有页面使用 AppSpacing 间距
-- [x] 7.5.3 所有页面使用 AppRadius 圆角
-- [x] 7.5.4 所有页面使用 AppColorScheme 颜色
-
-STATUS: COMPLETE
-
----
-
-## Previous Phases (Completed)
-
-## Progress
-
-### Phase 1: Analysis ✅
-
-#### 已完成的 shadcn 集成
-- ✅ main.dart 已更新为 ShadApp.custom
-- ✅ 主题配置完成(Slate 深色模式)
-- ✅ 依赖安装完成(shadcn_ui 0.52.1, lucide_icons_flutter)
-
-#### 页面重构状态
-| 页面 | 状态 | 说明 |
-|------|------|------|
-| main_page.dart | ✅ 完成 | 使用 ShadTheme, LucideIcons, 底部导航 |
-| login_page.dart | ✅ 完成 | 使用 ShadForm, ShadInputFormField, ShadButton, ShadDialog |
-| home_page.dart | ✅ 完成 | 使用 ShadTheme, LucideIcons, ShadCard, CircleAvatar |
-| market_page.dart | ✅ 完成 | 使用 ShadInput, ShadCard, CircleAvatar |
-| trade_page.dart | ✅ 完成 | 使用 ShadInputFormField, ShadButton, ShadCard |
-| asset_page.dart | ✅ 完成 | 使用 ShadTheme, LucideIcons, ShadCard, CircleAvatar |
-| mine_page.dart | ✅ 完成 | 使用 ShadTheme, LucideIcons, ShadButton.destructive |
-
-### Phase 2: Core Pages (P0) ✅
-
-#### 2.1 main_page.dart 替换 ✅
-- ✅ 删除原 main_page.dart
-- ✅ 重命名 main_page_shadcn.dart 为 main_page.dart
-- ✅ 修复 LucideIcons.home -> LucideIcons.house
-
-#### 2.2 login_page.dart 替换 ✅
-- ✅ 删除原 login_page.dart
-- ✅ 重命名 login_page_shadcn.dart 为 login_page.dart
-- ✅ 修复导入路径问题
-
-#### 2.3 home_page.dart 重构 ✅
-- ✅ 使用 ShadTheme 替换 AppColors
-- ✅ 使用 LucideIcons 替换 Material Icons
-- ✅ 使用 ShadCard 替换 Container + BoxDecoration
-- ✅ 使用 CircleAvatar 替换 ShadAvatar
-- ✅ 使用 ShadDialog 替换 AlertDialog
-
-### Phase 3: Feature Pages (P1) ✅
-
-#### 3.1 market_page.dart 重构 ✅
-- ✅ 使用 ShadInput 替换 TextField(搜索框)
-- ✅ 使用 ShadCard 替换 Container(币种列表)
-- ✅ 使用 CircleAvatar 替换 ShadAvatar
-- ✅ 使用 LucideIcons 替换 Material Icons
-
-#### 3.2 trade_page.dart 重构 ✅
-- ✅ 使用 ShadInputFormField 替换 TextField
-- ✅ 使用 ShadButton 替换渐变按钮
-- ✅ 使用 ShadCard 替换 Container
-- ✅ 使用 LucideIcons 替换 Material Icons
-
-#### 3.3 asset_page.dart 重构 ✅
-- ✅ 使用 ShadCard 替换 Container
-- ✅ 使用 ShadButton 替换 ElevatedButton
-- ✅ 使用 ShadDialog 替换 AlertDialog
-- ✅ 使用 CircleAvatar 替换 ShadAvatar
-- ✅ 使用 LucideIcons 替换 Material Icons
-
-#### 3.4 mine_page.dart 重构 ✅
-- ✅ 使用 ShadCard 替换 Container
-- ✅ 使用 ShadButton.destructive 替换退出登录按钮
-- ✅ 使用 LucideIcons 替换 Material Icons
-- ✅ 使用 CircleAvatar 替换 ShadAvatar
-
-### Phase 4: Custom Components (P2) ✅
-
-已创建的自定义组件:
-- ✅ `lib/ui/components/coin_card.dart` - 币种卡片组件
-- ✅ `lib/ui/components/trade_button.dart` - 交易按钮组件(买入/卖出)
-- ✅ `lib/ui/components/asset_card.dart` - 资产卡片组件(带渐变背景)
-- ✅ `lib/ui/components/components.dart` - 组件导出文件
-
-### Phase 5: Animation Enhancement (P3)
-- ⏸️ 暂未添加(flutter_animate 已在 shadcn_ui 中集成)
-
-## Changes Made
-
-### 页面修改
-1. **main_page.dart** - 替换为 shadcn 版本,使用 LucideIcons.house
-2. **login_page.dart** - 替换为 shadcn 版本,修复导入路径
-3. **home_page.dart** - 全面重构,使用 ShadTheme, ShadCard, CircleAvatar
-4. **market_page.dart** - 全面重构,使用 ShadInput, ShadCard, CircleAvatar
-5. **trade_page.dart** - 全面重构,使用 ShadInputFormField, ShadButton, ShadCard
-6. **asset_page.dart** - 全面重构,使用 ShadTheme, ShadCard, ShadDialog
-7. **mine_page.dart** - 全面重构,使用 ShadTheme, ShadCard, ShadButton.destructive
-
-### API 兼容性修复
-- ShadAvatar -> CircleAvatar(ShadAvatar 需要位置参数)
-- ShadDialog.content -> ShadDialog.child
-- ShadInputFormField.suffix -> ShadInputFormField.trailing
-- LucideIcons.home -> LucideIcons.house
-- LucideIcons.checkCircle -> LucideIcons.circleCheck
-- LucideIcons.alertCircle -> LucideIcons.circleAlert
-- LucideIcons.coin -> LucideIcons.coins
-- withOpacity() -> withValues(alpha:)
-
-### 组件创建
-- `lib/ui/components/coin_card.dart` - 可复用的币种卡片
-- `lib/ui/components/trade_button.dart` - 买入/卖出按钮组件
-- `lib/ui/components/asset_card.dart` - 资产展示卡片
-- `lib/ui/components/components.dart` - 导出文件
-
-## Issues Found & Resolved
-
-### API 兼容性问题
-1. **ShadAvatar API** - ShadAvatar 需要位置参数,改用 CircleAvatar
-2. **ShadDialog.content** - 应使用 child 参数
-3. **ShadInputFormField.suffix** - 应使用 trailing 参数
-4. **LucideIcons 命名** - 部分图标名称不同(home->house, checkCircle->circleCheck)
-
-### 解决方案
-- 使用 CircleAvatar 替代 ShadAvatar
-- 将 content 改为 child
-- 将 suffix 改为 trailing
-- 使用正确的 LucideIcons 名称
-
-## Verification
-
-### Flutter Analyze
-```
-flutter analyze
-```
-结果:0 errors,仅剩少量 warnings(unused imports, unnecessary null checks)
-
-### 功能验证
-- [ ] 用户登录/注册
-- [ ] 查看行情数据
-- [ ] 进行交易操作
-- [ ] 查看资产信息
-- [ ] 修改个人设置
-
-## Completion
-
-STATUS: COMPLETE
-
-所有 P0 和 P1 优先级任务已完成:
-- ✅ 核心页面已全部重构为 shadcn_ui 组件
-- ✅ 所有按钮使用 ShadButton
-- ✅ 所有卡片使用 ShadCard
-- ✅ 所有输入框使用 ShadInputFormField
-- ✅ 所有图标使用 LucideIcons
-- ✅ 自定义组件已创建
-- ✅ flutter analyze 无错误
-
-## Phase 6: 主题系统优化 (当前任务)
-
-### 目标
-- 统一颜色系统,消除重复定义
-- 确保文字与背景对比度符合 WCAG AA 标准
-- 添加响应式设计支持
-- 创建自定义品牌主题
-
-### 6.1 颜色系统重构
-- [ ] 合并 app_colors.dart 和 ui_constants.dart 中的重复定义
-- [ ] 创建完整的语义化颜色系统
-- [ ] 移除 market_page.dart, coin_card.dart 中的硬编码颜色
-- [ ] 确保对比度 >= 4.5:1
-
-### 6.2 响应式设计系统
-- [ ] 创建 Breakpoints 工具类
-- [ ] 创建响应式间距 (ResponsiveSpacing)
-- [ ] 创建响应式字体 (ResponsiveText)
-
-### 6.3 Shadcn 主题定制
-- [x] 创建自定义 ShadColorScheme (绿色品牌)
-- [x] 配置深色主题
-- [x] 更新 main.dart 使用自定义主题
-
-## STATUS: COMPLETE
-
----
-
-## Phase 6: 主题系统深度优化 (已完成)
-
-### 设计规范参考: `specs/theme-design.md`
-
-### 6.1 颜色系统重构 ✅
-
-- [x] 6.1.1 重构 `app_colors.dart`
- - 统一主色调 (#00D4AA 青绿色系)
- - 标准化涨跌色 (#00C853 绿 / #FF5252 红)
- - 优化背景色层次 (#0F0F1A -> #1A1A2E -> #16213E)
- - 确保文字颜色对比度
- - 移除重复定义
-
-- [x] 6.1.2 清理硬编码颜色
- - `coin_card.dart` - upColor/downColor 硬编码 ✅
- - `market_page.dart` - 检查并清理 ✅
- - 所有页面检查 ✅
-
-### 6.2 文字样式系统 ✅
-
-- [x] 6.2.1 更新 `app_theme.dart`
- - 标题样式 (h1-h4)
- - 正文样式 (body1, body2)
- - 数字样式 (price, amount)
- - 确保与 ShadTheme 协同
-
-### 6.3 间距与圆角系统 ✅
-
-- [x] 6.3.1 更新 `app_theme.dart`
- - 统一间距常量 (xs/sm/md/lg/xl/xxl)
- - 统一圆角常量 (sm/md/lg/xl/full)
- - 响应式断点定义
-
-### 6.4 Shadcn 主题定制 ✅
-
-- [x] 6.4.1 创建自定义颜色方案
- - 创建 `app_color_scheme.dart`
- - 自定义 ShadColorScheme (品牌绿色)
- - 深色主题优化
- - 更新 main.dart
-
-### 6.5 组件样式统一
-
-- [ ] 6.5.1 优化按钮样式 (待完善)
-- [ ] 6.5.2 优化卡片样式 (待完善)
-- [ ] 6.5.3 优化输入框样式 (待完善)
-
-### 6.6 页面样式优化
-
-- [ ] 6.6.1 登录/注册页面 (待完善)
-- [ ] 6.6.2 首页 (待完善)
-- [ ] 6.6.3 行情页 (待完善)
-- [ ] 6.6.4 交易页 (待完善)
-- [ ] 6.6.5 资产页 (待完善)
-- [ ] 6.6.6 我的页面 (待完善)
-
-### 6.7 验证 ✅
-
-- [x] 6.7.1 flutter analyze 通过 (0 errors, 31 warnings/infos)
-- [x] 6.7.2 对比度检查 (WCAG AA >= 4.5:1)
-
----
-
-## 优先级排序
-
-1. **P0** - 6.1 颜色系统重构 (核心基础) ✅
-2. **P0** - 6.4 Shadcn 主题定制 ✅
-3. **P1** - 6.2 文字样式系统 ✅
-4. **P1** - 6.3 间距与圆角系统 ✅
-5. **P2** - 6.5 组件样式统一 (待完善)
-6. **P2** - 6.6 页面样式优化 (待完善)
-7. **P3** - 6.7 验证 ✅
-
----
-
-## Next Steps (Optional)
-
-1. **动画优化** - 使用 flutter_animate 添加更多动画效果
-2. **浅色模式** - 添加浅色主题支持
-3. **组件优化** - 进一步优化自定义组件的可配置性
diff --git a/flutter_monisuo/android/.gitignore b/flutter_monisuo/android/.gitignore
new file mode 100644
index 0000000..be3943c
--- /dev/null
+++ b/flutter_monisuo/android/.gitignore
@@ -0,0 +1,14 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+.cxx/
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/to/reference-keystore
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/flutter_monisuo/android/app/build.gradle.kts b/flutter_monisuo/android/app/build.gradle.kts
new file mode 100644
index 0000000..0b2f4ef
--- /dev/null
+++ b/flutter_monisuo/android/app/build.gradle.kts
@@ -0,0 +1,44 @@
+plugins {
+ id("com.android.application")
+ id("kotlin-android")
+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
+ id("dev.flutter.flutter-gradle-plugin")
+}
+
+android {
+ namespace = "com.example.flutter_monisuo"
+ compileSdk = flutter.compileSdkVersion
+ ndkVersion = flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId = "com.example.flutter_monisuo"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://flutter.dev/to/review-gradle-config.
+ minSdk = flutter.minSdkVersion
+ targetSdk = flutter.targetSdkVersion
+ versionCode = flutter.versionCode
+ versionName = flutter.versionName
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig = signingConfigs.getByName("debug")
+ }
+ }
+}
+
+flutter {
+ source = "../.."
+}
diff --git a/flutter_monisuo/android/app/src/debug/AndroidManifest.xml b/flutter_monisuo/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..399f698
--- /dev/null
+++ b/flutter_monisuo/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/flutter_monisuo/android/app/src/main/AndroidManifest.xml b/flutter_monisuo/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5ace5d7
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/android/app/src/main/kotlin/com/example/flutter_monisuo/MainActivity.kt b/flutter_monisuo/android/app/src/main/kotlin/com/example/flutter_monisuo/MainActivity.kt
new file mode 100644
index 0000000..c0260a2
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/kotlin/com/example/flutter_monisuo/MainActivity.kt
@@ -0,0 +1,5 @@
+package com.example.flutter_monisuo
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity : FlutterActivity()
diff --git a/flutter_monisuo/android/app/src/main/res/drawable-v21/launch_background.xml b/flutter_monisuo/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 0000000..5a90d40
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
diff --git a/flutter_monisuo/android/app/src/main/res/drawable/launch_background.xml b/flutter_monisuo/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000..6d7c1ee
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
diff --git a/flutter_monisuo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_monisuo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..db77bb4
Binary files /dev/null and b/flutter_monisuo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/flutter_monisuo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_monisuo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..17987b7
Binary files /dev/null and b/flutter_monisuo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/flutter_monisuo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_monisuo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..09d4391
Binary files /dev/null and b/flutter_monisuo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/flutter_monisuo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_monisuo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5f1c8d
Binary files /dev/null and b/flutter_monisuo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/flutter_monisuo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_monisuo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4d6372e
Binary files /dev/null and b/flutter_monisuo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/flutter_monisuo/android/app/src/main/res/values-night/styles.xml b/flutter_monisuo/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000..06952be
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/android/app/src/main/res/values/styles.xml b/flutter_monisuo/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..cb1ef88
--- /dev/null
+++ b/flutter_monisuo/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/android/app/src/profile/AndroidManifest.xml b/flutter_monisuo/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000..399f698
--- /dev/null
+++ b/flutter_monisuo/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/flutter_monisuo/android/build.gradle.kts b/flutter_monisuo/android/build.gradle.kts
new file mode 100644
index 0000000..dbee657
--- /dev/null
+++ b/flutter_monisuo/android/build.gradle.kts
@@ -0,0 +1,24 @@
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+val newBuildDir: Directory =
+ rootProject.layout.buildDirectory
+ .dir("../../build")
+ .get()
+rootProject.layout.buildDirectory.value(newBuildDir)
+
+subprojects {
+ val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
+ project.layout.buildDirectory.value(newSubprojectBuildDir)
+}
+subprojects {
+ project.evaluationDependsOn(":app")
+}
+
+tasks.register("clean") {
+ delete(rootProject.layout.buildDirectory)
+}
diff --git a/flutter_monisuo/android/gradle.properties b/flutter_monisuo/android/gradle.properties
new file mode 100644
index 0000000..fbee1d8
--- /dev/null
+++ b/flutter_monisuo/android/gradle.properties
@@ -0,0 +1,2 @@
+org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
+android.useAndroidX=true
diff --git a/flutter_monisuo/android/gradle/wrapper/gradle-wrapper.properties b/flutter_monisuo/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e4ef43f
--- /dev/null
+++ b/flutter_monisuo/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
diff --git a/flutter_monisuo/android/settings.gradle.kts b/flutter_monisuo/android/settings.gradle.kts
new file mode 100644
index 0000000..ca7fe06
--- /dev/null
+++ b/flutter_monisuo/android/settings.gradle.kts
@@ -0,0 +1,26 @@
+pluginManagement {
+ val flutterSdkPath =
+ run {
+ val properties = java.util.Properties()
+ file("local.properties").inputStream().use { properties.load(it) }
+ val flutterSdkPath = properties.getProperty("flutter.sdk")
+ require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
+ flutterSdkPath
+ }
+
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
+
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+plugins {
+ id("dev.flutter.flutter-plugin-loader") version "1.0.0"
+ id("com.android.application") version "8.11.1" apply false
+ id("org.jetbrains.kotlin.android") version "2.2.20" apply false
+}
+
+include(":app")
diff --git a/flutter_monisuo/ios/.gitignore b/flutter_monisuo/ios/.gitignore
new file mode 100644
index 0000000..7a7f987
--- /dev/null
+++ b/flutter_monisuo/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/flutter_monisuo/ios/Flutter/AppFrameworkInfo.plist b/flutter_monisuo/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..391a902
--- /dev/null
+++ b/flutter_monisuo/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+
+
diff --git a/flutter_monisuo/ios/Flutter/Debug.xcconfig b/flutter_monisuo/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..ec97fc6
--- /dev/null
+++ b/flutter_monisuo/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
diff --git a/flutter_monisuo/ios/Flutter/Release.xcconfig b/flutter_monisuo/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..c4855bf
--- /dev/null
+++ b/flutter_monisuo/ios/Flutter/Release.xcconfig
@@ -0,0 +1,2 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
diff --git a/flutter_monisuo/ios/Podfile b/flutter_monisuo/ios/Podfile
new file mode 100644
index 0000000..620e46e
--- /dev/null
+++ b/flutter_monisuo/ios/Podfile
@@ -0,0 +1,43 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '13.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+ target 'RunnerTests' do
+ inherit! :search_paths
+ end
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/flutter_monisuo/ios/Runner.xcodeproj/project.pbxproj b/flutter_monisuo/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..20291b7
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,620 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 97C146ED1CF9000F007C117D;
+ remoteInfo = Runner;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 331C8082294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXGroup;
+ children = (
+ 331C807B294A618700263BE5 /* RunnerTests.swift */,
+ );
+ path = RunnerTests;
+ sourceTree = "";
+ };
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ 331C8082294A63A400263BE5 /* RunnerTests */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 331C8080294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+ buildPhases = (
+ 331C807D294A63A400263BE5 /* Sources */,
+ 331C807F294A63A400263BE5 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */,
+ );
+ name = RunnerTests;
+ productName = RunnerTests;
+ productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1510;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 331C8080294A63A400263BE5 = {
+ CreatedOnToolsVersion = 14.0;
+ TestTargetID = 97C146ED1CF9000F007C117D;
+ };
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ 331C8080294A63A400263BE5 /* RunnerTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 331C807F294A63A400263BE5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 331C807D294A63A400263BE5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 97C146ED1CF9000F007C117D /* Runner */;
+ targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 331C8088294A63A400263BE5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Debug;
+ };
+ 331C8089294A63A400263BE5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Release;
+ };
+ 331C808A294A63A400263BE5 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterMonisuo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 331C8088294A63A400263BE5 /* Debug */,
+ 331C8089294A63A400263BE5 /* Release */,
+ 331C808A294A63A400263BE5 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_monisuo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..e3773d4
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcworkspace/contents.xcworkspacedata b/flutter_monisuo/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..1d526a1
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/flutter_monisuo/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/flutter_monisuo/ios/Runner/AppDelegate.swift b/flutter_monisuo/ios/Runner/AppDelegate.swift
new file mode 100644
index 0000000..c30b367
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/AppDelegate.swift
@@ -0,0 +1,16 @@
+import Flutter
+import UIKit
+
+@main
+@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+
+ func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
+ GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
+ }
+}
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d36b1fa
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,122 @@
+{
+ "images" : [
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-20x20@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-29x29@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-40x40@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "Icon-App-60x60@3x.png",
+ "scale" : "3x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-20x20@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-29x29@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-40x40@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@1x.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-76x76@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "Icon-App-83.5x83.5@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "Icon-App-1024x1024@1x.png",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000..dc9ada4
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..7353c41
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..797d452
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..6ed2d93
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..4cd7b00
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..fe73094
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..321773c
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..797d452
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..502f463
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..0ec3034
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..0ec3034
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..e9f5fea
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..84ac32a
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..8953cba
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..0467bf1
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000..0bedcf2
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000..89c2725
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/flutter_monisuo/ios/Runner/Base.lproj/LaunchScreen.storyboard b/flutter_monisuo/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..fa45cc5
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/ios/Runner/Base.lproj/Main.storyboard b/flutter_monisuo/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..f3c2851
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/flutter_monisuo/ios/Runner/Info.plist b/flutter_monisuo/ios/Runner/Info.plist
new file mode 100644
index 0000000..a2e310f
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Info.plist
@@ -0,0 +1,70 @@
+
+
+
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ Flutter Monisuo
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ flutter_monisuo
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+ UIWindowSceneSessionRoleApplication
+
+
+ UISceneClassName
+ UIWindowScene
+ UISceneConfigurationName
+ flutter
+ UISceneDelegateClassName
+ $(PRODUCT_MODULE_NAME).SceneDelegate
+ UISceneStoryboardFile
+ Main
+
+
+
+
+ UIApplicationSupportsIndirectInputEvents
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/flutter_monisuo/ios/Runner/Runner-Bridging-Header.h b/flutter_monisuo/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 0000000..308a2a5
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/flutter_monisuo/ios/Runner/SceneDelegate.swift b/flutter_monisuo/ios/Runner/SceneDelegate.swift
new file mode 100644
index 0000000..b9ce8ea
--- /dev/null
+++ b/flutter_monisuo/ios/Runner/SceneDelegate.swift
@@ -0,0 +1,6 @@
+import Flutter
+import UIKit
+
+class SceneDelegate: FlutterSceneDelegate {
+
+}
diff --git a/flutter_monisuo/ios/RunnerTests/RunnerTests.swift b/flutter_monisuo/ios/RunnerTests/RunnerTests.swift
new file mode 100644
index 0000000..86a7c3b
--- /dev/null
+++ b/flutter_monisuo/ios/RunnerTests/RunnerTests.swift
@@ -0,0 +1,12 @@
+import Flutter
+import UIKit
+import XCTest
+
+class RunnerTests: XCTestCase {
+
+ func testExample() {
+ // If you add code to the Runner application, consider adding tests here.
+ // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
+ }
+
+}
diff --git a/flutter_monisuo/lib/core/storage/local_storage.dart b/flutter_monisuo/lib/core/storage/local_storage.dart
index dd19060..46f46bb 100644
--- a/flutter_monisuo/lib/core/storage/local_storage.dart
+++ b/flutter_monisuo/lib/core/storage/local_storage.dart
@@ -98,4 +98,23 @@ class LocalStorage {
await removeToken();
await removeUserInfo();
}
+
+ // ==================== 引导页状态 ====================
+
+ static const String _onboardingKey = 'onboarding_completed';
+
+ /// 检查是否已完成引导页
+ static bool get isOnboardingCompleted {
+ return getBool(_onboardingKey) ?? false;
+ }
+
+ /// 标记引导页已完成
+ static Future setOnboardingCompleted() async {
+ await setBool(_onboardingKey, true);
+ }
+
+ /// 重置引导页状态(用于测试)
+ static Future resetOnboarding() async {
+ await prefs.remove(_onboardingKey);
+ }
}
diff --git a/flutter_monisuo/lib/main.dart b/flutter_monisuo/lib/main.dart
index ee9ef80..b1640b6 100644
--- a/flutter_monisuo/lib/main.dart
+++ b/flutter_monisuo/lib/main.dart
@@ -20,6 +20,7 @@ import 'providers/asset_provider.dart';
import 'providers/theme_provider.dart';
import 'ui/pages/auth/login_page.dart';
import 'ui/pages/main/main_page.dart';
+import 'ui/pages/onboarding/onboarding_page.dart';
void main() async {
// 确保 Flutter 绑定初始化
@@ -117,14 +118,29 @@ class MyApp extends StatelessWidget {
builder: (context, child) => ShadAppBuilder(child: child!),
initialRoute: '/',
routes: {
- '/': (context) => _buildHome(),
+ '/': (context) => const RootPage(),
'/login': (context) => const LoginPage(),
'/main': (context) => const MainPage(),
},
);
}
+}
+
+/// 根页面 - 决定显示引导页还是主页面
+class RootPage extends StatelessWidget {
+ const RootPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ // 检查是否需要显示引导页
+ if (!LocalStorage.isOnboardingCompleted) {
+ return OnboardingPage(
+ onComplete: () {
+ Navigator.of(context).pushReplacementNamed('/login');
+ },
+ );
+ }
- Widget _buildHome() {
return Consumer(
builder: (context, auth, _) {
if (auth.isLoading) {
diff --git a/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart
new file mode 100644
index 0000000..ecb5796
--- /dev/null
+++ b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart
@@ -0,0 +1,263 @@
+import 'package:flutter/material.dart';
+import 'package:shadcn_ui/shadcn_ui.dart';
+import '../../../core/theme/app_spacing.dart';
+import '../../../core/storage/local_storage.dart';
+
+/// 引导页数据模型
+class _OnboardingItem {
+ final String title;
+ final String description;
+ final IconData icon;
+ final List gradientColors;
+
+ const _OnboardingItem({
+ required this.title,
+ required this.description,
+ required this.icon,
+ required this.gradientColors,
+ });
+}
+
+/// 首次启动引导页
+class OnboardingPage extends StatefulWidget {
+ final VoidCallback onComplete;
+
+ const OnboardingPage({super.key, required this.onComplete});
+
+ @override
+ State createState() => _OnboardingPageState();
+}
+
+class _OnboardingPageState extends State {
+ final PageController _pageController = PageController();
+ int _currentPage = 0;
+
+ final _items = const [
+ _OnboardingItem(
+ title: '实时行情',
+ description: '全球市场行情实时更新,把握每一个投资机会',
+ icon: LucideIcons.trendingUp,
+ gradientColors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
+ ),
+ _OnboardingItem(
+ title: '模拟交易',
+ description: '零风险体验真实交易,学习投资策略',
+ icon: LucideIcons.arrowLeftRight,
+ gradientColors: [Color(0xFF10B981), Color(0xFF059669)],
+ ),
+ _OnboardingItem(
+ title: '资产管理',
+ description: '清晰的资产概览,轻松管理你的投资组合',
+ icon: LucideIcons.wallet,
+ gradientColors: [Color(0xFFF59E0B), Color(0xFFD97706)],
+ ),
+ _OnboardingItem(
+ title: '安全可靠',
+ description: '数据加密存储,保护你的隐私安全',
+ icon: LucideIcons.shieldCheck,
+ gradientColors: [Color(0xFFEC4899), Color(0xFFBE185D)],
+ ),
+ ];
+
+ @override
+ void dispose() {
+ _pageController.dispose();
+ super.dispose();
+ }
+
+ void _nextPage() {
+ if (_currentPage < _items.length - 1) {
+ _pageController.nextPage(
+ duration: const Duration(milliseconds: 400),
+ curve: Curves.easeInOut,
+ );
+ } else {
+ _completeOnboarding();
+ }
+ }
+
+ void _skip() {
+ _completeOnboarding();
+ }
+
+ Future _completeOnboarding() async {
+ await LocalStorage.setBool('onboarding_completed', true);
+ widget.onComplete();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final colorScheme = Theme.of(context).colorScheme;
+ final isDark = Theme.of(context).brightness == Brightness.dark;
+
+ return Scaffold(
+ backgroundColor: colorScheme.surface,
+ body: SafeArea(
+ child: Column(
+ children: [
+ // 顶部跳过按钮
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: AppSpacing.lg,
+ vertical: AppSpacing.md,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ TextButton(
+ onPressed: _skip,
+ child: Text(
+ '跳过',
+ style: TextStyle(
+ color: colorScheme.onSurfaceVariant,
+ fontSize: 14,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ // 页面内容
+ Expanded(
+ child: PageView.builder(
+ controller: _pageController,
+ onPageChanged: (index) {
+ setState(() {
+ _currentPage = index;
+ });
+ },
+ itemCount: _items.length,
+ itemBuilder: (context, index) {
+ return _buildPage(_items[index], isDark);
+ },
+ ),
+ ),
+ // 底部指示器和按钮
+ Padding(
+ padding: const EdgeInsets.fromLTRB(
+ AppSpacing.lg,
+ AppSpacing.md,
+ AppSpacing.lg,
+ AppSpacing.xl,
+ ),
+ child: Column(
+ children: [
+ // 页面指示器
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: List.generate(
+ _items.length,
+ (index) => _buildIndicator(index, isDark),
+ ),
+ ),
+ const SizedBox(height: AppSpacing.xl),
+ // 下一步/开始按钮
+ SizedBox(
+ width: double.infinity,
+ height: 56,
+ child: ElevatedButton(
+ onPressed: _nextPage,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: colorScheme.primary,
+ foregroundColor: colorScheme.onPrimary,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(AppRadius.lg),
+ ),
+ elevation: 0,
+ ),
+ child: Text(
+ _currentPage == _items.length - 1 ? '开始使用' : '下一步',
+ style: const TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget _buildPage(_OnboardingItem item, bool isDark) {
+ final colorScheme = Theme.of(context).colorScheme;
+
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xl),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ // 图标容器
+ Container(
+ width: 160,
+ height: 160,
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.topLeft,
+ end: Alignment.bottomRight,
+ colors: item.gradientColors,
+ ),
+ shape: BoxShape.circle,
+ boxShadow: [
+ BoxShadow(
+ color: item.gradientColors.first.withValues(alpha: 0.4),
+ blurRadius: 40,
+ offset: const Offset(0, 20),
+ ),
+ ],
+ ),
+ child: Center(
+ child: Icon(
+ item.icon,
+ size: 72,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ const SizedBox(height: AppSpacing.xxl + AppSpacing.lg),
+ // 标题
+ Text(
+ item.title,
+ style: TextStyle(
+ fontSize: 28,
+ fontWeight: FontWeight.bold,
+ color: colorScheme.onSurface,
+ letterSpacing: -0.5,
+ ),
+ ),
+ const SizedBox(height: AppSpacing.md),
+ // 描述
+ Text(
+ item.description,
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 16,
+ color: colorScheme.onSurfaceVariant,
+ height: 1.6,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildIndicator(int index, bool isDark) {
+ final colorScheme = Theme.of(context).colorScheme;
+ final isActive = index == _currentPage;
+
+ return AnimatedContainer(
+ duration: const Duration(milliseconds: 300),
+ margin: const EdgeInsets.symmetric(horizontal: AppSpacing.xs),
+ width: isActive ? 24 : 8,
+ height: 8,
+ decoration: BoxDecoration(
+ color: isActive ? colorScheme.primary : colorScheme.outlineVariant,
+ borderRadius: BorderRadius.circular(4),
+ ),
+ );
+ }
+}