feat: initial commit - Habo habit tracking app
- Complete MVP with Repository Pattern, SQLite storage - Provider + ChangeNotifier state management - Navigation 2.0 with deep link support - Habit CRUD with twoDayRule, notifications, categories - Backup/Restore via JSON - Statistics with streak tracking - Material You theme support - Biometric lock support - Desktop widget support - 27 languages i18n structure - Comprehensive test suite (87/89 passing)
This commit is contained in:
547
docs/04-ASSETS.md
Normal file
547
docs/04-ASSETS.md
Normal file
@@ -0,0 +1,547 @@
|
||||
# Habo 可复用素材清单
|
||||
|
||||
> 从原项目提取的静态资源、国际化文本、测试用例,作为 AI 复刻项目的起点素材
|
||||
|
||||
---
|
||||
|
||||
## 1. 静态资源清单
|
||||
|
||||
### 1.1 图片资源 (`assets/images/`)
|
||||
|
||||
| 文件 | 用途 | 格式 |
|
||||
|------|------|------|
|
||||
| `icon.png` | Android 应用图标 | PNG |
|
||||
| `ios_icon.jpg` | iOS 应用图标 | JPG |
|
||||
| `macos_icon.png` | macOS 应用图标 | PNG |
|
||||
| `app_icon.png` | 通用应用图标 | PNG |
|
||||
| `splash_icon.png` | 启动画面图标 | PNG |
|
||||
| `splash_icon2.png` | 备用启动图标 | PNG |
|
||||
| `android_foreground.png` | Android 自适应图标前景 | PNG |
|
||||
| `android_background.png` | Android 自适应图标背景 | PNG |
|
||||
| `android_monochrome.svg` | Android 单色图标 | SVG |
|
||||
| `emptyList.svg` | 空列表占位图 | SVG |
|
||||
| `noDataStatistics.svg` | 统计页空数据占位图 | SVG |
|
||||
|
||||
### 1.2 引导页图片 (`assets/images/onboard/`)
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `1.svg` | 第 1 步: 定义习惯 (空列表插图) |
|
||||
| `2.svg` | 第 2 步: 记录天数 (习惯追踪插图) |
|
||||
| `3.svg` | 第 3 步: 观察进步 (进度追踪插图) |
|
||||
|
||||
### 1.3 音效资源 (`assets/sounds/`)
|
||||
|
||||
| 文件 | 用途 | 说明 |
|
||||
|------|------|------|
|
||||
| `check.wav` | 打卡完成音效 | 成功完成的正向音效 |
|
||||
| `click.wav` | 通用点击音效 | 失败/跳过等操作的反馈音效 |
|
||||
| `sound_sources.txt` | 音效来源说明 | 开源协议信息 |
|
||||
|
||||
### 1.4 字体资源 (`assets/google_fonts/`)
|
||||
|
||||
**字体族**: Nunito(18 个字重/样式变体)
|
||||
|
||||
| 文件 | 字重 |
|
||||
|------|------|
|
||||
| Nunito-ExtraLight.ttf | 200 |
|
||||
| Nunito-Light.ttf | 300 |
|
||||
| Nunito-Regular.ttf | 400 |
|
||||
| Nunito-Medium.ttf | 500 |
|
||||
| Nunito-SemiBold.ttf | 600 |
|
||||
| Nunito-Bold.ttf | 700 |
|
||||
| Nunito-ExtraBold.ttf | 800 |
|
||||
| Nunito-Black.ttf | 900 |
|
||||
| 以及对应的 Italic 变体 | |
|
||||
|
||||
许可证: OFL (SIL Open Font License)
|
||||
|
||||
---
|
||||
|
||||
## 2. 国际化文本 (英文基准 ARB)
|
||||
|
||||
> 完整的 `intl_en.arb`,包含 **354 个键**,可直接复制为项目的国际化基准文件
|
||||
|
||||
```json
|
||||
{
|
||||
"@@locale": "en",
|
||||
"habits": "Habits:",
|
||||
"statistics": "Statistics",
|
||||
"emptyList": "Empty list",
|
||||
"noDataAboutHabits": "There is no data about habits.",
|
||||
"topStreak": "Top streak",
|
||||
"currentStreak": "Current streak",
|
||||
"total": "Total",
|
||||
"unknown": "Unknown",
|
||||
"warning": "Warning",
|
||||
"allHabitsWillBeReplaced": "All habits will be replaced with habits from backup.",
|
||||
"restore": "Restore",
|
||||
"cancel": "Cancel",
|
||||
"settings": "Settings",
|
||||
"theme": "Theme",
|
||||
"firstDayOfWeek": "First day of the week",
|
||||
"notifications": "Notifications",
|
||||
"notificationTime": "Notification time",
|
||||
"soundEffects": "Sound effects",
|
||||
"showMonthName": "Show month name",
|
||||
"setColors": "Set colors",
|
||||
"backup": "Backup",
|
||||
"create": "Create",
|
||||
"onboarding": "Onboarding",
|
||||
"about": "About",
|
||||
"habo": "Habo",
|
||||
"copyright": "©2023 Habo",
|
||||
"termsAndConditions": "Terms and Conditions",
|
||||
"privacyPolicy": "Privacy Policy",
|
||||
"disclaimer": "Disclaimer",
|
||||
"sourceCode": "Source code (GitHub)",
|
||||
"ifYouWantToSupport": "If you want to support Habo you can:",
|
||||
"buyMeACoffee": "Buy me a coffee",
|
||||
"reset": "Reset",
|
||||
"done": "Done",
|
||||
"congratulationsReward": "Congratulations! Your reward:",
|
||||
"ohNoSanction": "Oh no! Your sanction:",
|
||||
"month": "Month",
|
||||
"week": "Week",
|
||||
"habitLoop": "Habit loop",
|
||||
"habitLoopDescription": "Habit Loop is a psychological model describing the process of habit formation. It consists of three components: Cue, Routine, and Reward. The Cue triggers the Routine (habitual action), which is then reinforced by the Reward, creating a loop that makes the habit more ingrained and likely to be repeated.",
|
||||
"cue": "Cue",
|
||||
"cueDescription": "is the trigger that initiates your habit. It could be a specific time, location, feeling, or an event.",
|
||||
"routine": "Routine",
|
||||
"routineDescription": "is the action you take in response to the cue. This is the habit itself.",
|
||||
"reward": "Reward",
|
||||
"rewardDescription": "is the benefit or positive feeling you experience after performing the routine. It reinforces the habit.",
|
||||
"editHabit": "Edit Habit",
|
||||
"createHabit": "Create Habit",
|
||||
"delete": "Delete",
|
||||
"habitTitleEmptyError": "The habit title can not be empty.",
|
||||
"save": "Save",
|
||||
"exercise": "Exercise",
|
||||
"habit": "Habit",
|
||||
"useTwoDayRule": "Use Two day rule",
|
||||
"twoDayRule": "Two day rule",
|
||||
"twoDayRuleDescription": "With two day rule, you can miss one day and do not lose a streak if the next day is successful.",
|
||||
"advancedHabitBuilding": "Advanced habit building",
|
||||
"advancedHabitBuildingDescription": "This section helps you better define your habits utilizing the Habit loop. You should define cues, routines, and rewards for every habit.",
|
||||
"at7AM": "At 7:00AM",
|
||||
"do50PushUps": "Do 50 push ups",
|
||||
"fifteenMinOfVideoGames": "15 min. of video games",
|
||||
"showReward": "Show reward",
|
||||
"remainderOfReward": "The reminder of the reward after a successful routine.",
|
||||
"habitContract": "Habit contract",
|
||||
"habitContractDescription": "While positive reinforcement is recommended, some people may opt for a habit contract. A habit contract allows you to specify a sanction that will be imposed if you miss your habit, and may involve an accountability partner who helps supervise your goals.",
|
||||
"donateToCharity": "Donate 10$ to charity",
|
||||
"sanction": "Sanction",
|
||||
"showSanction": "Show sanction",
|
||||
"remainderOfSanction": "The reminder of the sanction after a unsuccessful routine.",
|
||||
"dan": "Dan",
|
||||
"accountabilityPartner": "Accountability partner",
|
||||
"add": "Add",
|
||||
"haboNeedsPermission": "Habo needs permission to send notifications to work properly.",
|
||||
"allow": "Allow",
|
||||
"date": "Date",
|
||||
"check": "Check",
|
||||
"fail": "Fail",
|
||||
"skip": "Skip",
|
||||
"note": "Note",
|
||||
"yourCommentHere": "Your note here",
|
||||
"close": "Close",
|
||||
"createYourFirstHabit": "Create your first habit.",
|
||||
"modify": "Modify",
|
||||
"backupFailedError": "ERROR: Creating backup failed.",
|
||||
"restoreFailedError": "ERROR: Restoring backup failed.",
|
||||
"habitDeleted": "Habit deleted.",
|
||||
"undo": "Undo",
|
||||
"appNotifications": "App notifications",
|
||||
"appNotificationsChannel": "Notification channel for application notifications",
|
||||
"habitNotifications": "Habit notifications",
|
||||
"habitNotificationsChannel": "Notification channel for habit notifications",
|
||||
"doNotForgetToCheckYourHabits": "Do not forget to check your habits.",
|
||||
"themeSelect": "{theme, select, device {Device} light {Light} dark {Dark} oled {OLED black} materialYou {Material You} other{Device}}",
|
||||
"@themeSelect": {
|
||||
"placeholders": {
|
||||
"theme": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defineYourHabits": "Define your habits",
|
||||
"defineYourHabitsDescription": "To better stick to your habits, you can define:",
|
||||
"cueNumbered": "1. Cue",
|
||||
"routineNumbered": "2. Routine",
|
||||
"rewardNumbered": "3. Reward",
|
||||
"logYourDays": "Log your days",
|
||||
"successful": "Successful",
|
||||
"notSoSuccessful": "Not so successful",
|
||||
"skipDoesNotAffectStreaks": "Skip (does not affect streaks)",
|
||||
"observeYourProgress": "Observe your progress",
|
||||
"trackYourProgress": "You can track your progress through the calendar view in every habit or on the statistics page.",
|
||||
"backupCreatedSuccessfully": "Backup created successfully!",
|
||||
"backupFailed": "Backup failed!",
|
||||
"restoreCompletedSuccessfully": "Restore completed successfully!",
|
||||
"restoreFailed": "Restore failed!",
|
||||
"fileNotFound": "File not found",
|
||||
"fileTooLarge": "File too large (max 10MB)",
|
||||
"invalidBackupFile": "Invalid backup file",
|
||||
"progress": "Progress",
|
||||
"enterAmount": "Enter amount",
|
||||
"complete": "Complete",
|
||||
"saveProgress": "Save Progress",
|
||||
"currentProgress": "Current: {current} {unit}",
|
||||
"@currentProgress": {
|
||||
"placeholders": {
|
||||
"current": { "type": "String" },
|
||||
"unit": { "type": "String" }
|
||||
}
|
||||
},
|
||||
"targetProgress": "Target: {target} {unit}",
|
||||
"@targetProgress": {
|
||||
"placeholders": {
|
||||
"target": { "type": "String" },
|
||||
"unit": { "type": "String" }
|
||||
}
|
||||
},
|
||||
"progressOf": "{current} / {target} {unit}",
|
||||
"@progressOf": {
|
||||
"placeholders": {
|
||||
"current": { "type": "String" },
|
||||
"target": { "type": "String" },
|
||||
"unit": { "type": "String" }
|
||||
}
|
||||
},
|
||||
"numericHabit": "Progressive",
|
||||
"targetValue": "Target value",
|
||||
"partialValue": "Partial value",
|
||||
"unit": "Unit",
|
||||
"habitType": "Habit type",
|
||||
"booleanHabit": "Checkable (Yes/No)",
|
||||
"slider": "Slider",
|
||||
"input": "Input",
|
||||
"numericHabitDescription": "Numeric habits let you track progress in increments throughout the day.",
|
||||
"partialValueDescription": "To track progress in smaller increments",
|
||||
"categories": "Categories",
|
||||
"addCategory": "Add Category",
|
||||
"editCategory": "Edit Category",
|
||||
"category": "Category",
|
||||
"noCategoriesYet": "No categories yet",
|
||||
"createFirstCategory": "Create your first category to organize your habits",
|
||||
"pleaseEnterCategoryTitle": "Please enter a category title",
|
||||
"categoryAlreadyExists": "Category \"{title}\" already exists",
|
||||
"@categoryAlreadyExists": { "placeholders": { "title": { "type": "String" } } },
|
||||
"categoryCreatedSuccessfully": "Category \"{title}\" created successfully",
|
||||
"@categoryCreatedSuccessfully": { "placeholders": { "title": { "type": "String" } } },
|
||||
"categoryUpdatedSuccessfully": "Category \"{title}\" updated successfully",
|
||||
"@categoryUpdatedSuccessfully": { "placeholders": { "title": { "type": "String" } } },
|
||||
"categoryDeletedSuccessfully": "Category \"{title}\" deleted successfully",
|
||||
"@categoryDeletedSuccessfully": { "placeholders": { "title": { "type": "String" } } },
|
||||
"failedToSaveCategory": "Failed to save category: {error}",
|
||||
"@failedToSaveCategory": { "placeholders": { "error": { "type": "String" } } },
|
||||
"failedToDeleteCategory": "Failed to delete category: {error}",
|
||||
"@failedToDeleteCategory": { "placeholders": { "error": { "type": "String" } } },
|
||||
"selectCategories": "Select Categories",
|
||||
"selectedCategories": "Selected Categories ({count})",
|
||||
"@selectedCategories": { "placeholders": { "count": { "type": "int" } } },
|
||||
"allCategories": "All Categories",
|
||||
"deleteCategory": "Delete Category",
|
||||
"deleteCategoryConfirmation": "Are you sure you want to delete \"{title}\"?\n\nThis will remove the category from all habits that use it.",
|
||||
"@deleteCategoryConfirmation": { "placeholders": { "title": { "type": "String" } } },
|
||||
"noHabitsInCategory": "No habits in \"{title}\"",
|
||||
"@noHabitsInCategory": { "placeholders": { "title": { "type": "String" } } },
|
||||
"createHabitForCategory": "Create a habit and assign it to this category",
|
||||
"showCategories": "Show Categories",
|
||||
"archive": "Archive",
|
||||
"unarchive": "Unarchive",
|
||||
"archiveHabit": "Archive habit",
|
||||
"unarchiveHabit": "Unarchive habit",
|
||||
"archivedHabits": "Archived Habits",
|
||||
"noArchivedHabits": "No archived habits",
|
||||
"viewArchivedHabits": "View archived habits",
|
||||
"habitArchived": "Habit archived",
|
||||
"habitUnarchived": "Habit unarchived",
|
||||
"biometric": "Biometric",
|
||||
"biometricLockEnabled": "Biometric lock enabled",
|
||||
"biometricLockDisabled": "Biometric lock disabled",
|
||||
"authenticationError": "Authentication error",
|
||||
"biometricAuthenticationRequired": "Biometric authentication required",
|
||||
"setupFingerprintFaceUnlock": "Please set up your fingerprint or face unlock in device settings",
|
||||
"touchSensor": "Touch sensor",
|
||||
"biometricNotRecognized": "Biometric not recognized, try again",
|
||||
"biometricRequired": "Biometric required",
|
||||
"biometricAuthenticationSucceeded": "Biometric authentication succeeded",
|
||||
"deviceCredentialsRequired": "Device credentials required",
|
||||
"setupDeviceCredentials": "Please set up device credentials in settings",
|
||||
"setupTouchIdFaceId": "Please set up your Touch ID or Face ID in device settings",
|
||||
"reenableTouchIdFaceId": "Please reenable your Touch ID or Face ID",
|
||||
"biometricLock": "Biometric Lock",
|
||||
"biometricLockDescription": "Secure app with {authMethod}",
|
||||
"@biometricLockDescription": { "placeholders": { "authMethod": { "type": "String" } } },
|
||||
"authenticateToEnable": "Authenticate to enable biometric lock",
|
||||
"authenticateToAccess": "Please authenticate to access Habo",
|
||||
"authenticationRequired": "Authentication Required",
|
||||
"authenticationFailedMessage": "Please authenticate to access Habo using {authMethod}",
|
||||
"@authenticationFailedMessage": { "placeholders": { "authMethod": { "type": "String" } } },
|
||||
"tryAgain": "Try Again",
|
||||
"authenticating": "Authenticating…",
|
||||
"authenticate": "Authenticate",
|
||||
"buildingBetterHabits": "Building Better Habits",
|
||||
"authenticationPrompt": "Please authenticate using {authMethod} to access your habits",
|
||||
"@authenticationPrompt": { "placeholders": { "authMethod": { "type": "String" } } },
|
||||
"devicePinPatternPassword": "Device PIN, Pattern, or Password",
|
||||
"fingerprint": "Fingerprint",
|
||||
"iris": "Iris",
|
||||
"whatsNewTitle": "What's New",
|
||||
"whatsNewVersion": "Version {version}",
|
||||
"@whatsNewVersion": { "placeholders": { "version": { "type": "String" } } },
|
||||
"featureNumericTitle": "Numeric values in habits",
|
||||
"featureNumericDesc": "Track counts like glasses of water or pages read",
|
||||
"featureDeepLinksTitle": "URL scheme (deep links)",
|
||||
"featureDeepLinksDesc": "Open Habo directly to screens like settings or create",
|
||||
"featureCategoriesTitle": "Categories",
|
||||
"featureCategoriesDesc": "Organize habits with category filters",
|
||||
"featureArchiveTitle": "Archive",
|
||||
"featureArchiveDesc": "Hide habits you no longer track without deleting",
|
||||
"featureMaterialYouTitle": "Material You theme (Android)",
|
||||
"featureMaterialYouDesc": "Dynamic colors that match your wallpaper",
|
||||
"featureSoundTitle": "New sound engine",
|
||||
"featureSoundDesc": "Adjustable volume",
|
||||
"featureLockTitle": "Lock feature",
|
||||
"featureLockDesc": "Secure the app with Face ID / Touch ID / biometrics",
|
||||
"featureIosSoundMixingTitle": "Fixed sound mixing",
|
||||
"featureIosSoundMixingDesc": "Habo sounds no longer interrupt your music or podcasts",
|
||||
"featureHomescreenWidgetTitle": "Homescreen widget",
|
||||
"featureHomescreenWidgetDesc": "View your habit progress at a glance from your home screen (experimental)",
|
||||
"featureLongpressCheckTitle": "Longpress check",
|
||||
"featureLongpressCheckDesc": "Longpress on habit buttons to quickly change status",
|
||||
"haboSyncComingSoon": "Coming Soon",
|
||||
"haboSyncDescription": "Sync your habits across all your devices with Habo's end-to-end encrypted cloud service.",
|
||||
"haboSyncLearnMore": "Learn more at habo.space/sync",
|
||||
"habitsToday": "Habits today",
|
||||
"or": "or",
|
||||
"oneTapCheck": "Single tap to check",
|
||||
"tapCheckLongPressMenu": "Tap to check, long press for menu",
|
||||
"categoryName": "Category name",
|
||||
"createCategory": "Create category",
|
||||
"all": "All",
|
||||
"selectIcon": "Pick an icon",
|
||||
"searchIcons": "Search"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 支持的语言 (27 种)
|
||||
|
||||
| 代码 | 语言 |
|
||||
|------|------|
|
||||
| `en` | English (基准) |
|
||||
| `zh_Hans` | 中文简体 |
|
||||
| `zh_Hant` | 中文繁體 |
|
||||
| `es` | Español |
|
||||
| `fr` | Français |
|
||||
| `de` | Deutsch |
|
||||
| `it` | Italiano |
|
||||
| `pt` | Português |
|
||||
| `pt_BR` | Português (Brasil) |
|
||||
| `ru` | Русский |
|
||||
| `ja` | (可能缺失, 需确认) |
|
||||
| `ar` | العربية |
|
||||
| `he` | עברית |
|
||||
| `pl` | Polski |
|
||||
| `nl` | Nederlands |
|
||||
| `sv` | Svenska |
|
||||
| `cs` | Čeština |
|
||||
| `sk` | Slovenčina |
|
||||
| `uk` | Українська |
|
||||
| `vi` | Tiếng Việt |
|
||||
| `id` | Bahasa Indonesia |
|
||||
| `tr` | Türkçe |
|
||||
| `ca` | Català |
|
||||
| `ta` | தமிழ் |
|
||||
| `nb_NO` | Norsk bokmål |
|
||||
| `eo` | Esperanto |
|
||||
| `ia` | Interlingua |
|
||||
| `ckb` | کوردی |
|
||||
|
||||
---
|
||||
|
||||
## 4. 测试用例清单
|
||||
|
||||
> 13 个测试文件,覆盖核心业务逻辑
|
||||
|
||||
### 4.1 单元测试
|
||||
|
||||
| 文件 | 测试目标 | 测试用例数 |
|
||||
|------|----------|-----------|
|
||||
| `test/habits/habits_manager_test.dart` | HabitsManager CRUD | 13 |
|
||||
| `test/habits/habits_manager_updated_test.dart` | Repository 模式集成 | 8 |
|
||||
| `test/habits/habits_manager_fixed_test.dart` | 归档功能 | 8 |
|
||||
| `test/habits/habits_manager_notifications_test.dart` | 通知调度 | 3 |
|
||||
| `test/habits/backup_enhancement_test.dart` | 备份格式 | 4 |
|
||||
| `test/services/backup_service_test.dart` | 备份服务 | 7 |
|
||||
| `test/services/backup_feature_comprehensive_test.dart` | 备份完整性 | 18 |
|
||||
| `test/services/notification_service_test.dart` | 通知服务 | 11 |
|
||||
| `test/app_test.dart` | 应用初始化 | 4 |
|
||||
| `test/repositories/repository_test.dart` | Repository 模式 | 6 |
|
||||
|
||||
### 4.2 Widget 测试
|
||||
|
||||
| 文件 | 测试目标 | 测试用例数 |
|
||||
|------|----------|-----------|
|
||||
| `test/widgets/habit_details_widget_test.dart` | 习惯详情组件 | 3 |
|
||||
| `test/widgets/habit_list_widget_test.dart` | 习惯列表组件 | 2 |
|
||||
|
||||
### 4.3 集成测试
|
||||
|
||||
| 文件 | 测试目标 | 测试用例数 |
|
||||
|------|----------|-----------|
|
||||
| `test/integration/habit_crud_integration_test.dart` | 完整 CRUD 流程 | 2 |
|
||||
|
||||
### 4.4 测试 Mock 基础设施
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `test/mocks/mock_repositories.dart` | MockHabitRepository, MockEventRepository, MockCategoryRepository, MockBackupRepository + InMemory 实现用于集成测试 |
|
||||
|
||||
### 4.5 关键测试场景摘要
|
||||
|
||||
**HabitsManager 测试**:
|
||||
- 初始化时从 Repository 加载习惯
|
||||
- 空列表正确处理
|
||||
- 创建习惯并分配正确位置
|
||||
- 编辑更新已有习惯
|
||||
- 删除习惯并支持 Undo
|
||||
- 归档/取消归档切换
|
||||
- 活跃/归档习惯正确过滤
|
||||
- 位置排序更新
|
||||
- 通知调度触发
|
||||
|
||||
**备份测试**:
|
||||
- 正确的 JSON 结构验证
|
||||
- 时间戳格式验证
|
||||
- 空数据备份处理
|
||||
- 事件类型保留
|
||||
- 分类关联保留
|
||||
- 大数据集处理
|
||||
- 损坏数据检测
|
||||
- 10MB 文件大小限制
|
||||
- 并发操作处理
|
||||
|
||||
**通知测试**:
|
||||
- 空习惯列表不崩溃
|
||||
- 习惯通知调度
|
||||
- 事件添加/删除触发通知
|
||||
- 多习惯批量通知
|
||||
- 当日/非当日事件区分
|
||||
|
||||
---
|
||||
|
||||
## 5. 备份文件格式规格
|
||||
|
||||
### 5.1 当前格式 (Version 3)
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"habits": [
|
||||
{
|
||||
"id": 1,
|
||||
"position": 0,
|
||||
"title": "Exercise",
|
||||
"twoDayRule": false,
|
||||
"cue": "At 7:00AM",
|
||||
"routine": "Do 50 push ups",
|
||||
"reward": "15 min. of video games",
|
||||
"showReward": true,
|
||||
"advanced": true,
|
||||
"notification": true,
|
||||
"notTime": {"hour": 7, "minute": 0},
|
||||
"events": {
|
||||
"2024-01-01 00:00:00.000": [1, ""],
|
||||
"2024-01-02 00:00:00.000": [2, "Tired"]
|
||||
},
|
||||
"sanction": "Donate 10$ to charity",
|
||||
"showSanction": true,
|
||||
"accountant": "Dan",
|
||||
"habitType": 0,
|
||||
"targetValue": 1.0,
|
||||
"partialValue": 1.0,
|
||||
"unit": ""
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{ "id": 1, "title": "Health", "iconCodePoint": 58718, "fontFamily": "fontAwesomeFlutter" }
|
||||
],
|
||||
"habit_categories": [
|
||||
{ "habit_id": 1, "category_id": 1 }
|
||||
],
|
||||
"metadata": {
|
||||
"import_timestamp": "2024-01-15T10:30:00.000Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 旧版兼容格式 (数组)
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Exercise",
|
||||
"position": 0,
|
||||
"events": {},
|
||||
...
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### 5.3 事件类型编码
|
||||
|
||||
| 值 | DayType | 含义 |
|
||||
|----|---------|------|
|
||||
| 0 | clear | 清除/无事件 |
|
||||
| 1 | check | 完成 |
|
||||
| 2 | fail | 失败 |
|
||||
| 3 | skip | 跳过 |
|
||||
| 4 | progress | 进度(部分完成) |
|
||||
|
||||
---
|
||||
|
||||
## 6. pubspec.yaml 关键配置
|
||||
|
||||
```yaml
|
||||
name: habo
|
||||
version: 3.1.2+5115
|
||||
|
||||
environment:
|
||||
sdk: ">=3.11.0 <4.0.0"
|
||||
flutter: ">=3.41.1"
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
generate: true
|
||||
assets:
|
||||
- assets/
|
||||
- assets/images/
|
||||
- assets/images/onboard/
|
||||
- assets/sounds/
|
||||
- assets/google_fonts/
|
||||
|
||||
flutter_intl:
|
||||
enabled: true
|
||||
|
||||
flutter_native_splash:
|
||||
color: "#FAFAFA"
|
||||
color_dark: "#000000"
|
||||
image: assets/images/splash_icon.png
|
||||
image_dark: assets/images/splash_icon.png
|
||||
ios_content_mode: center
|
||||
android_gravity: center
|
||||
fullscreen: false
|
||||
android_12:
|
||||
color: "#FAFAFA"
|
||||
color_dark: "#000000"
|
||||
image: assets/images/splash_icon.png
|
||||
android: true
|
||||
ios: true
|
||||
web: false
|
||||
```
|
||||
Reference in New Issue
Block a user