Files
FocusBuddy/CLAUDE.md
2025-11-25 11:15:45 +08:00

9.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

FocusBuddy is a Flutter-based focus timer app designed for neurodivergent minds, implementing a "no-punishment" philosophy. The core concept is that distractions during focus sessions are tracked but don't interrupt the timer, providing a gentler approach to productivity tracking.

Commands

Development Setup

# Check Flutter version and environment
flutter doctor

# Get dependencies
flutter pub get

# Generate localization files (required after editing .arb files)
flutter gen-l10n

# Generate Hive adapters (required after modifying model classes)
flutter pub run build_runner build

# Clean build artifacts
flutter clean

Running the App

# List available devices/emulators
flutter devices

# Run on default device
flutter run

# Run on specific device
flutter run -d <device_id>

# Run on Chrome (web)
flutter run -d chrome

# Run with hot reload (default in debug mode)
flutter run --hot

Building

# Build APK for Android
flutter build apk

# Build App Bundle for Google Play
flutter build appbundle

# Build for iOS (requires macOS)
flutter build ios

# Build for Windows
flutter build windows

Testing & Analysis

# Run static analysis
flutter analyze

# Run tests
flutter test

# Check for outdated packages
flutter pub outdated

Architecture

Core Philosophy

The app follows a no-punishment approach to focus tracking:

  • Timer continues running even when user reports a distraction
  • Distractions are tracked via "I got distracted" button
  • Encouragement messages replace negative feedback
  • All distraction counts are for awareness, not judgment

Key Technical Decisions

State Management: Simple StatefulWidget approach (no external state management)

  • Focus session state managed locally in FocusScreen
  • Settings and preferences stored in shared_preferences
  • Historical data stored in Hive local database

Data Persistence:

  • Hive for focus session history (typeId 0 for FocusSession)
  • SharedPreferences for app settings (onboarding status, default duration, locale)
  • Sessions stored with full distraction tracking but continue regardless of interruptions

Notifications:

  • Background notifications when app is inactive during focus session
  • Uses flutter_local_notifications with WidgetsBindingObserver lifecycle tracking
  • Notification updates every 30 seconds when app is backgrounded

Internationalization (i18n):

  • Uses Flutter's official intl package with ARB files
  • 13 supported languages (en, zh, ja, ko, es, de, fr, pt, ru, hi, id, it, ar)
  • Locale can be changed at runtime without app restart via MyApp.updateLocale()
  • Localization files generated in lib/l10n/ via flutter gen-l10n

Project Structure

lib/
├── main.dart                  # Entry point, app initialization
├── models/                    # Data models
│   ├── focus_session.dart     # Hive model for session data
│   ├── focus_session.g.dart   # Generated Hive adapter
│   └── distraction_type.dart  # Enum for distraction categories
├── screens/                   # UI screens
│   ├── onboarding_screen.dart # First-time user guide
│   ├── home_screen.dart       # Main screen with "Start Focus" button
│   ├── focus_screen.dart      # Active timer + distraction button
│   ├── complete_screen.dart   # Post-session summary
│   ├── history_screen.dart    # Past sessions list
│   └── settings_screen.dart   # Duration & locale settings
├── services/                  # Business logic
│   ├── storage_service.dart   # Hive database operations
│   ├── encouragement_service.dart # Random message picker
│   └── notification_service.dart  # Background notifications
├── theme/                     # Design system
│   ├── app_theme.dart         # Material theme config
│   ├── app_colors.dart        # Color palette constants
│   └── app_text_styles.dart   # Typography definitions
└── l10n/                      # Generated localization files
    ├── app_localizations.dart
    └── app_localizations_*.dart

Data Flow

Focus Session Lifecycle:

  1. User selects duration in HomeScreen (loads from SharedPreferences)
  2. FocusScreen starts countdown timer with Timer.periodic
  3. User can tap "I got distracted" → adds to _distractions list, timer continues
  4. Timer completion or manual stop → FocusSession saved to Hive via StorageService
  5. CompleteScreen shows stats fetched from StorageService.getTodaySessions()
  6. HistoryScreen displays all sessions from StorageService.getAllSessions()

Critical Implementation: The distraction button never pauses the timer - this is the app's core differentiator.

FocusSession Model

@HiveType(typeId: 0)
class FocusSession {
  DateTime startTime;
  int durationMinutes;      // Planned (e.g., 25)
  int actualMinutes;        // May be less if stopped early
  int distractionCount;     // Total distractions logged
  bool completed;           // True if timer reached zero
  List<String> distractionTypes; // Categories selected
}

Theme System

Uses Google Fonts (Nunito) with centralized design tokens:

  • Primary Color: #6C63FF (Purple)
  • Background: #F5F7FA (Light Gray)
  • Text Primary: #2D3748 (Dark Gray)
  • Success: #48BB78 (Green - used sparingly)

All UI components reference AppTextStyles and AppColors constants - never use hardcoded values.

MVP Feature Set

Current Implementation (as of git commit 005ad8d):

  • Onboarding flow with "no-punishment" philosophy explanation
  • Configurable session duration (15/25/45 minutes)
  • Background notifications during active sessions
  • Distraction tracking with 4 categories
  • Today's stats on completion screen
  • History view (today's sessions only in MVP)
  • Multi-language support (13 languages)
  • Settings for duration and locale

Intentionally Deferred (see README.md):

  • ⏸️ Variable duration slider (fixed presets preferred for MVP)
  • ⏸️ White noise audio playback
  • ⏸️ Weekly trend charts
  • ⏸️ PDF report export
  • ⏸️ AdMob integration (monetization post-validation)

Working with Localization

Adding/Editing Translations

  1. Translations are defined in l10n/app_en.arb (source locale) and other app_*.arb files
  2. After editing ARB files, regenerate code:
    flutter gen-l10n
    
  3. Use in code:
    final l10n = AppLocalizations.of(context)!;
    Text(l10n.appTitle);
    

Adding a New Language

  1. Create l10n/app_<locale>.arb (copy from app_en.arb)
  2. Add locale to supportedLocales in main.dart
  3. Add to language picker in settings_screen.dart
  4. Run flutter gen-l10n

Modifying Data Models

When changing Hive models (e.g., FocusSession):

  1. Update model class with @HiveField annotations
  2. Regenerate adapters:
    flutter pub run build_runner build --delete-conflicting-outputs
    
  3. Consider migration strategy if changing existing fields (current MVP has no migration logic)

Code Generation

This project uses code generation for:

  • Hive adapters: *.g.dart files for model serialization
  • Localization: lib/l10n/app_localizations*.dart from ARB files

Never edit generated files manually - always modify source files and regenerate.

Platform-Specific Notes

Android

  • Minimum SDK: 21 (Android 5.0)
  • Target SDK: 34 (Android 14)
  • Notification permission auto-requested on Android 13+ via permission_handler

iOS

  • Requires Xcode for building
  • Notification permissions requested via DarwinInitializationSettings
  • See MACOS_BUILD_GUIDE.md for macOS-specific instructions

Web

  • Notifications explicitly disabled on web platform (see NotificationService._initialized)
  • Uses responsive layout but primarily designed for mobile

Design System Guidelines

When adding new UI components:

  1. Use AppColors constants - never hardcode colors
  2. Use AppTextStyles for typography - never inline text styles
  3. Border radius should be 16px for cards/buttons (consistency)
  4. Button minimum height: 56px (touch-friendly)
  5. Padding: Use multiples of 8 (8, 16, 24, 32, 48, 60)
  6. Never use red/destructive colors for distractions (core philosophy)

Testing Strategy

Current implementation focuses on manual testing:

  • Test timer countdown accuracy across different durations
  • Verify background notifications appear when app is minimized
  • Test distraction button during active session (ensure timer continues)
  • Verify data persists after app restart (Hive)
  • Test locale switching without app restart

Known Constraints

  1. No backend server - All data stored locally (intentional for privacy)
  2. No analytics - No Firebase/Amplitude in MVP (intentional)
  3. Single-device only - No cross-device sync
  4. Today-focused - History screen shows minimal data in MVP

Important Implementation Rules

  1. Never pause timer on distraction - This would violate the core philosophy
  2. Never show negative/punitive messaging - Use encouragement instead
  3. Always use localized strings - No hardcoded English text
  4. Always save sessions to Hive - Even if stopped early (actualMinutes < durationMinutes)
  5. Background notifications required - Users need countdown visibility when multitasking