update md
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
|
||||
**Version**: 1.0
|
||||
**Target Platforms**: iOS & Android (responsive)
|
||||
**Framework**: Flutter-friendly
|
||||
**Framework**: Flutter
|
||||
**Design Philosophy**: Calm • Gentle • Accessible • Neurodivergent-Friendly
|
||||
**Implementation Status**: MVP 已完成
|
||||
|
||||
---
|
||||
|
||||
@@ -47,40 +48,40 @@
|
||||
|
||||
## 4. Core Screens
|
||||
|
||||
### 4.1 Home Screen (Start Focus)
|
||||
### 4.1 Home Screen
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ┌───────────────────────────┐ │
|
||||
│ │ Points Card │ │
|
||||
│ │ ┌──────┬──────┬────────┐ │ │
|
||||
│ │ │⚡ 120│🎖️ Lv2│📅 Check │ │ │
|
||||
│ │ └──────┴──────┴────────┘ │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ FocusBuddy │ ← App title (24px, centered)
|
||||
│ │
|
||||
│ │
|
||||
│ [ 25 minutes ] │ ← Duration selector (slider below)
|
||||
│ ◀─────────▶ │ ← Slider: 5min - 60min (step: 5)
|
||||
│ [ 25 minutes ] │ ← Duration display (28px)
|
||||
│ │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ │
|
||||
│ │ Start Focusing │ │ ← Primary button (#A7C4BC)
|
||||
│ │ ▶ │ │ ← 56px height, rounded 16px
|
||||
│ │ Start Focusing ▶ │ │ ← Primary button (#A7C4BC)
|
||||
│ └───────────────────────┘ │
|
||||
│ │
|
||||
│ "Tap 'I got distracted' │ ← Helper text (#8A9B9B)
|
||||
│ anytime — no guilt." │ ← 14px, centered
|
||||
│ │
|
||||
│ │
|
||||
│ 📊 History ⚙️ Settings │ ← Bottom navigation (icons only)
|
||||
│ 📊 History ⚙️ Settings │ ← Bottom navigation (text + icons)
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- Slider adjusts duration in real-time (haptic feedback on iOS)
|
||||
- "Start Focusing" button: Scale animation (0.95 → 1.0) on press
|
||||
- Transitions to "During Focus" screen with fade-in (300ms)
|
||||
|
||||
**Animation:**
|
||||
- Subtle particle floating in background (Lottie: `calm-particles.json`)
|
||||
- Particles: 5-8 dots, opacity 0.1-0.3, slow drift upward
|
||||
- Points card is tappable, navigates to Profile screen
|
||||
|
||||
---
|
||||
|
||||
@@ -91,21 +92,16 @@
|
||||
┌─────────────────────────────────┐
|
||||
│ │
|
||||
│ 24:37 │ ← Timer (64px, #5B6D6D)
|
||||
│ │ ← Breathing animation (scale 1.0-1.02)
|
||||
│ │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ │
|
||||
│ │ I got distracted │ │ ← Secondary button (#E0E0E0)
|
||||
│ │ 🤚 │ │ ← 48px height, rounded 12px
|
||||
│ └───────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ │
|
||||
│ │ ⏸ Pause │ │ ← Tertiary button (outlined)
|
||||
│ └───────────────────────┘ │ ← Border: 1px #A7C4BC
|
||||
│ │
|
||||
│ │
|
||||
│ 🎵 White Noise: Rain ▼ │ ← Dropdown (bottom sheet)
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -113,7 +109,6 @@
|
||||
- **Timer**: Count-down display, updates every second
|
||||
- **"I got distracted"** → Opens bottom sheet with 4 options
|
||||
- **Pause** → Shows "Resume" button + elapsed time badge
|
||||
- **White Noise** → Bottom sheet: Off / Rain / Keyboard / Forest
|
||||
|
||||
**Bottom Sheet: Distraction Types**
|
||||
```
|
||||
@@ -125,13 +120,11 @@
|
||||
│ 😰 Felt overwhelmed │ ← Option 3
|
||||
│ 💭 Just zoned out │ ← Option 4
|
||||
│ │
|
||||
│ [Skip this time] │ ← Text button (optional)
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Feedback after selection:**
|
||||
- Toast message: "It happens. Let's gently come back." (3s)
|
||||
- Soft haptic pulse
|
||||
- Auto-dismiss bottom sheet
|
||||
- Timer continues running
|
||||
|
||||
@@ -143,7 +136,7 @@
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ │
|
||||
│ ✨ │ ← Success icon (animated)
|
||||
│ ✨ │ ← Success icon
|
||||
│ │
|
||||
│ You focused for │ ← Headline (20px, #5B6D6D)
|
||||
│ 24 minutes │ ← Large number (32px, bold)
|
||||
@@ -156,75 +149,51 @@
|
||||
│ │ the battle." │ │ ← Italic, #8A9B9B
|
||||
│ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ 🎁 Achievement Unlocked! │ ← Conditional (if milestone hit)
|
||||
│ "Calm Cloud" theme │ ← Badge animation
|
||||
│ │
|
||||
│ ┌───────────────────────┐ │
|
||||
│ │ Start Another │ │ ← Primary button
|
||||
│ └───────────────────────┘ │
|
||||
│ │
|
||||
│ [View Full Report] │ ← Text link
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- Success icon: Lottie animation (plays once, 2s)
|
||||
- "Start Another" → Resets to Home screen
|
||||
- "View Full Report" → Navigates to History tab
|
||||
|
||||
**Achievement Badge:**
|
||||
- Slides up from bottom with bounce effect
|
||||
- Shimmer animation (gradient sweep)
|
||||
- If ad required: Shows "Watch ad to unlock" button
|
||||
- "Start Another" → Navigates to Home screen
|
||||
- Shows random encouragement message from `assets/encouragements.json`
|
||||
|
||||
---
|
||||
|
||||
### 4.4 History/Report Screen
|
||||
### 4.4 History Screen
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 📊 Your Focus Journey │ ← Header (24px)
|
||||
│ │
|
||||
│ ┌─ Today ──────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ Total: 47 mins │ │ ← Daily summary card
|
||||
│ │ Sessions: 2 │ │
|
||||
│ │ Distractions: 3 │ │
|
||||
│ │ │ │
|
||||
│ │ ▓▓▓▓▓░░░░░ 60% │ │ ← Progress bar
|
||||
│ │ (Goal: 75 mins/day) │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ Today's Summary │ │
|
||||
│ │ Total: 47 mins │ │
|
||||
│ │ Sessions: 2 │ │
|
||||
│ │ Distractions: 3 │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ This Week ─────────────┐ │
|
||||
│ │ Mon ■■■ 24 mins │ │ ← Bar chart (simplified)
|
||||
│ │ Tue ■■■■ 32 mins │ │
|
||||
│ │ Wed ■■ 15 mins │ │
|
||||
│ │ Thu ■■■■■ 47 mins ← │ │ ← Today highlighted
|
||||
│ └──────────────────────────┘ │
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ Session 1: 25 mins │ │
|
||||
│ │ • 2 distractions │ │
|
||||
│ │ • 10:00 AM - 10:25 AM │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ │
|
||||
│ 📈 Top Distraction: │
|
||||
│ 📱 Social media (60%) │ ← Insight card
|
||||
│ │
|
||||
│ [Export PDF Report] │ ← Secondary button (outlined)
|
||||
│ ┌──────────────────────────┐ │
|
||||
│ │ Session 2: 22 mins │ │
|
||||
│ │ • 1 distraction │ │
|
||||
│ │ • 11:00 AM - 11:22 AM │ │
|
||||
│ └──────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- Pull-to-refresh: Animates header particles
|
||||
- Bar chart: Tap day → Shows session details
|
||||
- Export PDF: Generates report with past 7 days data
|
||||
- Requires storage permission (Android)
|
||||
- iOS: Share sheet
|
||||
|
||||
**PDF Report Content:**
|
||||
- Logo + Date range
|
||||
- Total focus time
|
||||
- Session breakdown by day
|
||||
- Distraction type distribution (pie chart)
|
||||
- Encouragement message
|
||||
- Footer: "Generated by FocusBuddy"
|
||||
- Tap session card → Navigates to Session Detail screen
|
||||
- Empty state: Shows message "No sessions yet. Start your first focus session!"
|
||||
|
||||
---
|
||||
|
||||
@@ -235,37 +204,99 @@
|
||||
┌─────────────────────────────────┐
|
||||
│ ⚙️ Settings │
|
||||
│ │
|
||||
│ ┌─ Appearance ──────────────┐ │
|
||||
│ │ Theme: Calm Cloud ▼ │ │ ← Dropdown
|
||||
│ │ [Preview] │ │
|
||||
│ │ │ │
|
||||
│ │ 🔓 Unlock More Themes │ │ ← Ad button
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Focus Settings ──────────┐ │
|
||||
│ │ Default Duration: 25 min │ │
|
||||
│ │ White Noise: Rain │ │
|
||||
│ │ Daily Goal: 75 mins │ │
|
||||
│ │ Default Duration: │ │
|
||||
│ │ • 25 minutes (selected) │ │
|
||||
│ │ • 15 minutes │ │
|
||||
│ │ • 5 minutes │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ Notifications ───────────┐ │
|
||||
│ │ Focus Reminders [ON] │ │ ← Toggle
|
||||
│ │ Encourage Messages [ON] │ │
|
||||
│ ┌─ Language ────────────────┐ │
|
||||
│ │ English (selected) │ │
|
||||
│ │ 中文 │ │
|
||||
│ │ 日本語 │ │
|
||||
│ │ 한국어 │ │
|
||||
│ │ Español │ │
|
||||
│ │ Deutsch │ │
|
||||
│ │ Français │ │
|
||||
│ │ Português │ │
|
||||
│ │ Русский │ │
|
||||
│ │ हिन्दी │ │
|
||||
│ │ Bahasa Indonesia │ │
|
||||
│ │ Italiano │ │
|
||||
│ │ العربية │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ 💎 Remove Ads ($2.99) │ ← IAP button (highlighted)
|
||||
│ │
|
||||
│ Privacy Policy │ ← Links (text buttons)
|
||||
│ About FocusBuddy │
|
||||
│ ┌─ About ───────────────────┐ │
|
||||
│ │ Privacy Policy │ │
|
||||
│ │ Terms of Service │ │
|
||||
│ │ Version 1.0.0 │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- Theme preview: Shows timer screen with selected theme
|
||||
- "Unlock Themes": Shows rewarded ad → Unlocks next theme
|
||||
- IAP button: Opens native purchase dialog
|
||||
- Toggles: Animated switch with haptic feedback
|
||||
- Tap duration option → Updates default duration
|
||||
- Tap language option → Updates app language
|
||||
- Tap links → Opens respective pages
|
||||
|
||||
### 4.6 Profile Screen
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ 🧑 Profile │
|
||||
│ │
|
||||
│ ┌───────────────────────────┐ │
|
||||
│ │ Points: 120 │ │
|
||||
│ │ Level: 2 │ │
|
||||
│ │ Consecutive Check-ins: 5 │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌───────────────────────────┐ │
|
||||
│ │ Achievements │ │
|
||||
│ │ • First Focus Session │ │
|
||||
│ │ • 5 Sessions Completed │ │
|
||||
│ │ • 100 Points Earned │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- Shows user's points, level, and achievements
|
||||
- Shows consecutive check-in streak
|
||||
|
||||
### 4.7 Onboarding Screen
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ │
|
||||
│ FocusBuddy │ ← App title
|
||||
│ │
|
||||
│ ┌───────────────────────────┐ │
|
||||
│ │ │ │
|
||||
│ │ No guilt. │ │
|
||||
│ │ No shame. │ │
|
||||
│ │ Just gentle focus. │ │
|
||||
│ │ │ │
|
||||
│ └───────────────────────────┘ │
|
||||
│ │
|
||||
│ Learn to focus without the │
|
||||
│ pressure of perfection. │
|
||||
│ │
|
||||
│ ┌───────────────────────┐ │
|
||||
│ │ Get Started │ │ ← Primary button
|
||||
│ └───────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Interactions:**
|
||||
- "Get Started" → Navigates to Home screen
|
||||
- Only shown once (first launch)
|
||||
|
||||
---
|
||||
|
||||
@@ -287,18 +318,19 @@ Pressed: opacity 0.9, scale 0.95 (150ms ease-out)
|
||||
Disabled: opacity 0.5, grayscale 100%
|
||||
```
|
||||
|
||||
**Flutter Example:**
|
||||
**Flutter Implementation:**
|
||||
```dart
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFFA7C4BC),
|
||||
backgroundColor: AppColors.primary,
|
||||
minimumSize: Size(double.infinity, 56),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
elevation: 4,
|
||||
),
|
||||
child: Text('Start Focusing'),
|
||||
child: Text('Start Focusing', style: AppTextStyles.buttonText),
|
||||
onPressed: () {},
|
||||
)
|
||||
```
|
||||
|
||||
@@ -329,25 +361,12 @@ Pressed: background #D5D5D5
|
||||
- Color: `#5B6D6D`
|
||||
- Letter spacing: 2px (monospace feel)
|
||||
|
||||
**Animation:**
|
||||
- Breathing effect: Scale 1.0 → 1.02 → 1.0 (4s loop, ease-in-out)
|
||||
- On last 10 seconds: Pulse glow (0.3 opacity) around text
|
||||
|
||||
**Flutter Example:**
|
||||
**Flutter Implementation:**
|
||||
```dart
|
||||
AnimatedScale(
|
||||
scale: _breathingAnimation.value,
|
||||
duration: Duration(seconds: 4),
|
||||
curve: Curves.easeInOut,
|
||||
child: Text(
|
||||
'24:37',
|
||||
style: TextStyle(
|
||||
fontSize: 64,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
)
|
||||
Text(
|
||||
'24:37',
|
||||
style: AppTextStyles.timerDisplay,
|
||||
),
|
||||
```
|
||||
|
||||
---
|
||||
@@ -370,74 +389,59 @@ AnimatedScale(
|
||||
- Slide up: 300ms ease-out
|
||||
- Backdrop: Fade to 0.5 opacity black
|
||||
|
||||
---
|
||||
|
||||
### 5.5 Achievement Badge
|
||||
### 5.5 Points Card
|
||||
|
||||
**Visual:**
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ 🎁 Unlocked! │ ← Emoji + text (14px)
|
||||
│ │
|
||||
│ Calm Cloud │ ← Theme name (18px Bold)
|
||||
│ ▓▓▓▓▓▓▓▓▓▓ │ ← Preview gradient bar
|
||||
└─────────────────┘
|
||||
```
|
||||
- Background: Gradient from `#A7C4BC1A` to `#A7C4BC0D`
|
||||
- Border: 1px solid `#A7C4BC33`
|
||||
- Border radius: 16px
|
||||
- Padding: 16px
|
||||
- Contains points, level, and check-in status
|
||||
|
||||
**Animation:**
|
||||
- Slide up from bottom: 400ms spring
|
||||
- Shimmer sweep: 2s loop (gradient -100% → +100% X)
|
||||
- Auto-dismiss after 5s (slide down)
|
||||
|
||||
**Colors:**
|
||||
- Background: `#FFFFFF`
|
||||
- Border: 2px `#88C9A1` (success color)
|
||||
- Shadow: 0px 8px 24px rgba(136, 201, 161, 0.4)
|
||||
**Flutter Implementation:**
|
||||
```dart
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
AppColors.primary.withOpacity(0.1),
|
||||
AppColors.primary.withOpacity(0.05),
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: AppColors.primary.withOpacity(0.2),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
// Points, level, check-in status
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Animations & Micro-interactions
|
||||
|
||||
### 6.1 Loading States
|
||||
### 6.1 Screen Transitions
|
||||
|
||||
**When app launches:**
|
||||
- Logo fade-in: 500ms
|
||||
- Particles appear one by one (staggered 100ms)
|
||||
- Total: 1s to interactive
|
||||
- **Cross-fade**: 300ms ease-in-out for all screen transitions
|
||||
- **No slide transitions** to avoid motion sickness
|
||||
|
||||
**When switching screens:**
|
||||
- Cross-fade: 300ms ease-in-out
|
||||
- No slide transitions (avoid motion sickness)
|
||||
### 6.2 Button Interactions
|
||||
|
||||
---
|
||||
- **Primary Button**: Scale animation (0.95 → 1.0) on press
|
||||
- **Secondary Button**: Background color change on press
|
||||
- **Text Button**: Underline appears on hover
|
||||
|
||||
### 6.2 Haptic Feedback
|
||||
### 6.3 Loading States
|
||||
|
||||
**iOS UIFeedbackGenerator:**
|
||||
- Slider adjustment: `.selection`
|
||||
- Button press: `.light`
|
||||
- Timer complete: `.success`
|
||||
- Distraction logged: `.soft` (custom if available)
|
||||
|
||||
**Android:**
|
||||
- Use `HapticFeedback.lightImpact()`
|
||||
- Intensity: 30% (gentle)
|
||||
|
||||
---
|
||||
|
||||
### 6.3 Sound Effects
|
||||
|
||||
**Audio Files (CC Licensed):**
|
||||
- `button_tap.mp3`: Soft click (50ms)
|
||||
- `distraction_logged.mp3`: Gentle chime (200ms)
|
||||
- `focus_complete.mp3`: Warm bell (1s)
|
||||
- `white_noise_rain.mp3`: 10min loop
|
||||
- `white_noise_keyboard.mp3`: 10min loop
|
||||
|
||||
**Volume:**
|
||||
- Default: 60%
|
||||
- User adjustable in settings
|
||||
- Respect system silent mode
|
||||
- **App Launch**: Simple circular progress indicator
|
||||
- **Data Loading**: Skeleton screens for list items
|
||||
|
||||
---
|
||||
|
||||
@@ -565,65 +569,73 @@ AnimatedScale(
|
||||
|
||||
---
|
||||
|
||||
## 11. Implementation Notes
|
||||
## 11. Implementation Details
|
||||
|
||||
### 11.1 Flutter Packages
|
||||
|
||||
**Core Dependencies:**
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
hive: ^2.2.3 # Local storage
|
||||
flutter: ^3.10.0-290.4.beta
|
||||
flutter_localizations: ^0.1.0
|
||||
cupertino_icons: ^1.0.8
|
||||
hive: ^2.2.3 # 本地存储
|
||||
hive_flutter: ^1.1.0
|
||||
flutter_local_notifications: ^17.0.0
|
||||
workmanager: ^0.5.2 # Background tasks
|
||||
lottie: ^3.0.0 # Animations
|
||||
just_audio: ^0.9.36 # White noise
|
||||
google_mobile_ads: ^4.0.0 # AdMob
|
||||
path_provider: ^2.1.0
|
||||
pdf: ^3.10.0 # Report export
|
||||
flutter_local_notifications: ^17.0.0 # 通知
|
||||
permission_handler: ^11.0.0 # 权限管理
|
||||
path_provider: ^2.1.0 # 文件路径
|
||||
shared_preferences: ^2.2.0 # 简单键值存储
|
||||
intl: ^0.20.2 # 日期格式化和国际化
|
||||
google_fonts: ^6.1.0 # Google Fonts (Nunito)
|
||||
get_it: ^7.7.0 # 依赖注入框架
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 11.2 Folder Structure
|
||||
|
||||
```
|
||||
lib/
|
||||
├── main.dart
|
||||
├── screens/
|
||||
│ ├── home_screen.dart
|
||||
│ ├── focus_screen.dart
|
||||
│ ├── complete_screen.dart
|
||||
│ ├── history_screen.dart
|
||||
│ └── settings_screen.dart
|
||||
├── widgets/
|
||||
│ ├── primary_button.dart
|
||||
│ ├── timer_display.dart
|
||||
│ ├── distraction_sheet.dart
|
||||
│ └── achievement_badge.dart
|
||||
├── components/
|
||||
│ ├── control_buttons.dart
|
||||
│ ├── distraction_button.dart
|
||||
│ └── timer_display.dart
|
||||
├── l10n/
|
||||
│ ├── app_en.arb
|
||||
│ ├── app_zh.arb
|
||||
│ └── ... (12 more languages)
|
||||
├── models/
|
||||
│ ├── achievement_config.dart
|
||||
│ ├── distraction_type.dart
|
||||
│ ├── focus_session.dart
|
||||
│ └── distraction.dart
|
||||
│ ├── user_progress.dart
|
||||
│ └── *.g.dart (generated files)
|
||||
├── screens/
|
||||
│ ├── complete_screen.dart
|
||||
│ ├── focus_screen.dart
|
||||
│ ├── history_screen.dart
|
||||
│ ├── home_screen.dart
|
||||
│ ├── onboarding_screen.dart
|
||||
│ ├── profile_screen.dart
|
||||
│ ├── session_detail_screen.dart
|
||||
│ └── settings_screen.dart
|
||||
├── services/
|
||||
│ ├── storage_service.dart
|
||||
│ ├── achievement_service.dart
|
||||
│ ├── di.dart
|
||||
│ ├── encouragement_service.dart
|
||||
│ ├── notification_service.dart
|
||||
│ └── audio_service.dart
|
||||
├── theme/
|
||||
│ ├── app_colors.dart
|
||||
│ └── app_text_styles.dart
|
||||
└── assets/
|
||||
├── animations/
|
||||
├── sounds/
|
||||
└── fonts/
|
||||
│ ├── points_service.dart
|
||||
│ ├── service_locator.dart
|
||||
│ └── storage_service.dart
|
||||
└── theme/
|
||||
├── app_colors.dart
|
||||
├── app_text_styles.dart
|
||||
└── app_theme.dart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 11.3 Theme Definition
|
||||
|
||||
**AppColors Class:**
|
||||
```dart
|
||||
// lib/theme/app_colors.dart
|
||||
class AppColors {
|
||||
static const primary = Color(0xFFA7C4BC);
|
||||
static const background = Color(0xFFF8F6F2);
|
||||
@@ -631,9 +643,17 @@ class AppColors {
|
||||
static const textSecondary = Color(0xFF8A9B9B);
|
||||
static const distractionButton = Color(0xFFE0E0E0);
|
||||
static const success = Color(0xFF88C9A1);
|
||||
static const white = Color(0xFFFFFFFF);
|
||||
|
||||
// Method to create color with custom alpha
|
||||
static Color withValues({required double alpha}) {
|
||||
return Color.fromRGBO(255, 255, 255, alpha);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
// lib/theme/app_text_styles.dart
|
||||
**AppTextStyles Class:**
|
||||
```dart
|
||||
class AppTextStyles {
|
||||
static const appTitle = TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
@@ -654,24 +674,13 @@ class AppTextStyles {
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
color: AppColors.white,
|
||||
);
|
||||
|
||||
static const bodyText = TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColors.textPrimary,
|
||||
);
|
||||
|
||||
static const helperText = TextStyle(
|
||||
fontFamily: 'Nunito',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w300,
|
||||
color: AppColors.textSecondary,
|
||||
);
|
||||
// Additional text styles...
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -679,26 +688,25 @@ class AppTextStyles {
|
||||
|
||||
### 12.1 Visual QA
|
||||
|
||||
- [ ] All colors match design system
|
||||
- [ ] Fonts render correctly on iOS/Android
|
||||
- [ ] Animations run at 60fps
|
||||
- [ ] No pixel shifts when rotating
|
||||
- [ ] Safe areas respected on all devices
|
||||
- [x] All colors match design system
|
||||
- [x] Fonts render correctly on iOS/Android
|
||||
- [x] Animations run smoothly
|
||||
- [x] No pixel shifts when rotating
|
||||
- [x] Safe areas respected on all devices
|
||||
|
||||
### 12.2 Interaction QA
|
||||
|
||||
- [ ] Buttons have press states
|
||||
- [ ] Haptics fire at correct moments
|
||||
- [ ] Sound effects play (and respect mute)
|
||||
- [ ] Timer counts down accurately
|
||||
- [ ] Bottom sheet dismisses on backdrop tap
|
||||
- [x] Buttons have press states
|
||||
- [x] Timer counts down accurately
|
||||
- [x] Bottom sheet dismisses on backdrop tap
|
||||
- [x] Settings persist after app restart
|
||||
- [x] Language changes apply immediately
|
||||
|
||||
### 12.3 Accessibility QA
|
||||
|
||||
- [ ] Screen reader announces all elements
|
||||
- [ ] High contrast mode works
|
||||
- [ ] Font scaling doesn't break layout
|
||||
- [ ] Minimum touch target: 44×44 (iOS) / 48×48 (Android)
|
||||
- [x] Screen reader announces all elements
|
||||
- [x] Font scaling doesn't break layout
|
||||
- [x] Minimum touch target: 44×44 (iOS) / 48×48 (Android)
|
||||
|
||||
---
|
||||
|
||||
@@ -730,6 +738,6 @@ Store in `assets/encouragements.json`:
|
||||
|
||||
---
|
||||
|
||||
**Document Status:** ✅ Complete
|
||||
**Last Updated:** November 22, 2025
|
||||
**Next Steps:** Create Figma prototype → Share with ADHD community for feedback
|
||||
**Document Status:** ✅ MVP 已实现
|
||||
**Last Updated:** 2025年11月27日
|
||||
**Next Steps:** 上架应用商店
|
||||
Reference in New Issue
Block a user