- Overview
- Key Features
- Application Architecture
- Internal Architecture & Code Explanation
- Technical Stack
- Code Structure
- Data Flow
- File-by-File Project Structure & Roles
- Installation
- Usage Guide
- Contributing
- Testing
- License
- API & Data Model Documentation
- Configuration & Environment
- Troubleshooting & FAQ
- Accessibility
- Performance
- Internationalization
- Release Notes
- Security
- Third-Party Libraries
- Roadmap
- Quick Start
- Demo Video
- Contribution Guidelines
- Code of Conduct
- Issue & PR Templates
- Detailed License
- Contact & Community
- Known Limitations
- Architecture Diagrams
Cards is a cutting-edge flashcard application designed to enhance learning and memorization through active recall technique. The application employs cognitive science principles to optimize retention and learning efficiency, making it perfect for students, language learners, and professionals needing to master large volumes of information.
"Learning is not a spectator sport." - D. Blocher
- 📝 Dynamic Flashcards: Create and edit dual-sided flashcards with rich text formatting
- 🎤 Audio Integration: Record and playback pronunciation for language learning
- 🗂️ Smart Organization: Categorize and tag cards for efficient study sessions
- 🎮 Interactive Quiz Mode: Test your knowledge with various question formats
- 📊 Learning Analytics: Track your progress with detailed performance metrics
- 🌓 Personalized Themes: Choose between light/dark modes or customize your own
- ♿ Accessibility Features: Support for colorblind users, text scaling, and screen readers
- 💾 Data Portability: Import/export your flashcards in CSV format
- 🔄 Cross-Platform Sync: Access your cards on multiple devices (requires account)
- ⚡ Offline Mode: Study anywhere, even without internet connection
- 🎨 Modern UI: Beautiful and responsive design with engaging animations
Cards follows a feature-first architecture pattern with a clear separation of concerns:
┌─────────────────────────────────────┐
│ Presentation │
│ ┌─────────┐ ┌────────┐ ┌──────┐ │
│ │ Screens │ │Widgets │ │ Views│ │
│ └────┬────┘ └───┬────┘ └──┬───┘ │
│ │ │ │ │
│ └───────────┼──────────┘ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Business Logic │ │
│ │ (Controllers) │ │
│ └────────┬─────────┘ │
│ │ │
│ ┌────────┼─────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────┐ ┌─────────┐ │
│ │ Services │ │Models│ │Providers│ │
│ └────┬─────┘ └──────┘ └────┬────┘ │
│ │ │ │
└───────┼─────────────────────┼───────┘
│ │
▼ ▼
┌───────────────┐ ┌──────────────┐
│ Local Data │ │ External │
│ (SQLite/Web) │ │ Services │
└───────────────┘ └──────────────┘
The application uses a provider pattern for state management and dependency injection, ensuring a clean and testable codebase.
Cards is built with a strong focus on maintainability, modularity, and cross-platform support. Below is a detailed explanation of how the application is structured, how the main files interact, and how the core logic works under the hood.
The project follows a feature-first and layered architecture. Here is a breakdown of the main folders and their responsibilities:
lib/
main.dart # Application entry point, sets up providers and launches the app
core/ # Core utilities and managers (theme, accessibility, constants)
config/ # App and Firebase configuration files
features/ # Main business features, each in its own folder
flashcards/ # Flashcard domain: models, widgets, screens
quiz/ # Quiz logic: widgets, helpers, screens
statistics/ # Analytics and statistics screens
sync/ # Synchronization logic and helpers
services/ # Global services (database, Firebase, sync, audio)
database/ # Database providers (SQLite, WebStorage), interfaces, models
shared/ # Shared UI widgets and utilities (buttons, dialogs, backgrounds)
utils/ # Utility classes (CSV, logger, helpers)
views/ # Main app screens (home, quiz, statistics, import/export, sync)
- main.dart: Initializes the app, sets up dependency injection with
Provider, configures platform-specific settings, and launches the root widget. - core/theme/theme_manager.dart: Manages theme state (light/dark/custom), exposes theme data to the app.
- core/accessibility/accessibility_manager.dart: Handles accessibility settings (text scaling, high contrast, etc.).
- features/flashcards/models/flashcard.dart: Defines the
Flashcarddata model, including serialization, deserialization, and utility methods. - services/database_helper.dart: Singleton service that abstracts all database operations, choosing the right provider (SQLite or WebStorage) based on the platform.
- services/database/database_provider.dart: Interface for database providers, ensuring consistent CRUD operations.
- services/database/sqlite_provider.dart: Implements the database provider for mobile/desktop using SQLite.
- services/database/web_storage_provider.dart: Implements the provider for web using LocalStorage.
- services/firebase_manager.dart: Handles all Firebase/Firestore operations for cloud sync.
- features/quiz/widgets/: Contains all quiz-related UI components.
- views/home_view.dart: Main dashboard, handles card listing, filtering, and navigation.
- views/quiz_view.dart: Quiz mode logic and UI, manages quiz state and user interactions.
- views/statistics_view.dart: Displays learning analytics and statistics.
- views/sync_view.dart: UI and logic for cloud synchronization.
- utils/csv_parser.dart: Parses and generates CSV files for import/export.
- shared/widgets/: Reusable UI components (buttons, dialogs, animated backgrounds, etc.).
- The app starts in
main.dart, initializing platform-specific settings (window size, SQLite FFI, Firebase if enabled). - Providers for theme, accessibility, database, and optionally Firebase are injected at the root using
MultiProvider. - The root widget (
MyApp) sets up the MaterialApp and loads theHomeView.
- The app uses the
Providerpackage for state management. ThemeManagerandAccessibilityManagerareChangeNotifierclasses, exposing state and methods to update it.- The database and Firebase managers are injected as singleton services.
- UI widgets listen to these providers and rebuild automatically when state changes.
- All flashcard data is persisted locally using SQLite (mobile/desktop) or LocalStorage (web).
- The
DatabaseHelpersingleton abstracts all CRUD operations, so the rest of the app does not need to know which backend is used. - Data models (like
Flashcard) are immutable and provide methods for serialization (to/from Map, CSV, JSON).
- Flashcard CRUD: Adding, editing, and deleting cards is handled via forms and dialogs in the UI, which call methods on
DatabaseHelper. - Quiz Mode: The quiz logic loads cards from the database, tracks user answers, manages timers, and updates card status (known/unknown) after each answer.
- Statistics: The statistics view queries the database for card status and review history, then displays analytics using custom widgets.
- Synchronization: If enabled, the sync service compares local and remote data, resolves conflicts, and updates both sides as needed.
- Import/Export: CSV import/export is handled by utility classes, with user dialogs for file selection and column mapping.
- The UI is built with custom widgets and Material Design principles.
- Navigation between screens is handled with
Navigatorand custom transitions (e.g., fade transitions). - The desktop version includes a native-like menu bar with keyboard shortcuts.
- Accessibility and theme settings are available from the main UI and are persisted across sessions.
- User clicks the "+" button in the HomeView.
- The
AddCardViewscreen is shown, with a form for front/back text, category, and optional audio. - On save, the form creates a new
Flashcardobject and callsDatabaseHelper.saveCard(). - The database provider inserts the card into SQLite or LocalStorage.
- The HomeView reloads the card list and displays the new card.
- User selects "Quiz" mode from the HomeView.
- The
QuizViewloads cards (optionally filtered by category) from the database. - The quiz logic presents cards one by one, tracks answers, and updates card status.
- At the end, results and statistics are shown, and the user can restart or return to the dashboard.
- User opens the SyncView and clicks "Synchronize".
- The sync service fetches local changes and remote changes from Firebase.
- It merges changes, resolves conflicts (using timestamps), and updates both local and remote stores.
- Sync status and statistics are displayed to the user.
- The codebase uses immutability for data models, clear separation of concerns, and dependency injection for testability.
- All business logic is separated from UI code, making it easy to test and maintain.
- The project includes unit and widget tests for all critical components.
- The code follows the Dart style guide and uses meaningful naming conventions.
- To add a new feature, create a new folder in
features/and follow the same structure (models, widgets, screens). - To add a new database provider, implement the
DatabaseProviderinterface and register it inDatabaseHelper. - To add new UI components, place them in
shared/widgets/for reuse across the app.
This detailed section should help any developer understand how Cards is built, how the code is organized, and how the main features work internally. For more details, refer to the code comments and the test files in the test/ directory.
- Frontend Framework: Flutter 3.7+
- Programming Language: Dart 3.7+
- State Management: Provider
- Local Database: SQLite (mobile/desktop) & LocalStorage (web)
- Audio Processing: just_audio & record packages
- UI Components: Custom widgets with Material Design influence
- Analytics: Firebase Analytics (optional)
- Authentication: Firebase Auth (optional)
- Testing: Flutter Test framework & Mockito
Cards employs a feature-first architecture that organizes code by domain rather than technical layers:
lib/
├── main.dart # Application entry point
├── core/ # Core application functionality
│ ├── accessibility/ # Accessibility settings & services
│ ├── theme/ # Theme management
│ └── constants/ # App-wide constants
├── features/ # Feature modules
│ ├── flashcards/ # Flashcard domain
│ │ ├── models/ # Data models (Flashcard class etc.)
│ │ ├── widgets/ # UI components for flashcards
│ │ └── screens/ # Screens related to flashcards
│ ├── quiz/ # Quiz functionality
│ │ ├── widgets/ # Quiz-specific components
│ │ └── screens/ # Quiz screens
│ ├── settings/ # App settings
│ └── statistics/ # Learning statistics & analytics
├── services/ # Global services
│ ├── database/ # Database operations
│ ├── audio/ # Audio recording & playback
│ └── firebase/ # Firebase integration
├── shared/ # Shared resources
│ ├── widgets/ # Reusable UI components
│ └── utils/ # Utility functions & helpers
└── config/ # Configuration files
Key principles of the code organization:
- Separation of Concerns: Each module has a single responsibility
- Encapsulation: Features are isolated and self-contained
- Reusability: Common elements are abstracted into shared components
- Testability: Code is structured to facilitate unit and widget testing
The application follows a unidirectional data flow pattern:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Action │──────► │ State │──────► │ UI │
│ (Events) │ │ (Providers)│ │ (Widgets) │
└─────────────┘ └─────────────┘ └─────────────┘
▲ │
│ │
└───────────────────────────────────────────────┘
User Input
- User Interaction: The user interacts with the UI
- Action Dispatch: Actions/events are dispatched to providers
- State Update: Providers update the application state
- UI Refresh: Widgets listen to state changes and rebuild when needed
- Cycle Continues: The user sees the updated UI and can interact again
Below is a detailed breakdown of the main files and folders in the Cards project, explaining the purpose and role of each. This section is designed to help new contributors and maintainers quickly understand where to find and place code, and how the application is organized internally.
- README.md: This documentation file. Explains the project, architecture, usage, and contribution guidelines.
- pubspec.yaml: Flutter/Dart project manifest. Lists dependencies, assets, and project metadata.
- pubspec.lock: Auto-generated lockfile for dependency versions.
- analysis_options.yaml: Linting and static analysis rules for Dart code quality.
- devtools_options.yaml: Configuration for Flutter DevTools.
- projet.iml: IntelliJ/IDEA project file.
- build/: Generated build artifacts for all platforms (do not edit manually).
- web/: Web-specific assets and entry points (e.g.,
index.html, icons, manifest). - windows/, macos/: Platform-specific code and build files for desktop targets.
- main.dart: The entry point of the app. Initializes providers, configures platform-specific settings, and launches the root widget (
MyApp).
- Shared UI components used across multiple screens (e.g., custom menus, buttons, dialogs).
- app_config.dart: Centralizes app-wide configuration (app name, version, feature flags, platform defaults).
- firebase_config.dart: Firebase/Firestore configuration for cloud sync (API keys, project IDs, etc.).
- theme/theme_manager.dart: Manages theme state (light/dark/custom), exposes theme data.
- accessibility/accessibility_manager.dart: Handles accessibility settings (text scaling, high contrast, etc.).
- constants/: App-wide constants (colors, keys, etc.).
- flashcards/: All logic and UI for flashcard management.
- models/flashcard.dart: The main data model for a flashcard, with serialization and utility methods.
- widgets/: UI components for displaying and editing flashcards.
- screens/: Screens for listing, adding, and editing flashcards.
- quiz/: Quiz and study mode logic.
- widgets/: Quiz UI components (question cards, results, etc.).
- helpers/: Quiz logic helpers (audio, shortcuts, loaders).
- screens/: Quiz mode screens.
- statistics/: Analytics and statistics logic and UI.
- sync/: Synchronization logic and helpers for cloud sync.
- settings/: User settings screens and logic.
- (If present) Shared data models used across features.
- database_helper.dart: Singleton service for all database operations. Chooses the correct provider (SQLite or WebStorage) based on platform.
- firebase_manager.dart: Handles all Firebase/Firestore operations for cloud sync.
- sync_service.dart: Manages bidirectional sync between local and remote data, conflict resolution, and batch operations.
- database/: Contains database provider implementations:
- database_provider.dart: Abstract interface for database providers.
- sqlite_provider.dart: SQLite implementation for mobile/desktop.
- web_storage_provider.dart: LocalStorage implementation for web.
- models/import_result.dart: Data model for import/export results.
- audio/: Audio recording and playback services.
- widgets/: Reusable UI widgets (buttons, dialogs, animated backgrounds, etc.).
- utils/: Utility classes (CSV parser, logger, helpers, file pickers).
- home_view.dart: Main dashboard, handles card listing, filtering, and navigation.
- add_card_view.dart: UI and logic for adding a new flashcard.
- edit_card_view.dart: UI and logic for editing an existing flashcard.
- quiz_view.dart: Quiz mode logic and UI, manages quiz state and user interactions.
- statistics_view.dart: Displays learning analytics and statistics.
- sync_view.dart: UI and logic for cloud synchronization.
- import_export_view.dart: UI for importing/exporting cards as CSV.
- database_helper_test.dart: Unit tests for database operations and provider logic.
- flashcard_model_test.dart: Unit tests for the Flashcard data model (serialization, equality, etc.).
- widget_test.dart: Widget and integration tests for UI components and flows.
- firebase_cpp_sdk_windows_11.10.0.zip: Firebase C++ SDK for Windows (used for desktop sync, if enabled).
- CMakeLists.txt: CMake build configuration for Windows/desktop.
- .iml, .sln, .vcxproj: IDE and build system files for various platforms.
This section, combined with the rest of the documentation, provides a comprehensive map of the Cards project. Each file and folder has a clear purpose, making it easy for developers to navigate, extend, and maintain the codebase. For more details, refer to the code comments and the technical explanations above.
Cards uses a relational database structure with the following key entities:
┌─────────────────┐ ┌─────────────────┐
│ Flashcard │ │ Category │
├─────────────────┤ ├─────────────────┤
│ id │ │ id │
│ uuid │ │ name │
│ front │ │ color │
│ back │ │ icon │
│ category_id │◄──────┤ created_at │
│ audio_path │ └─────────────────┘
│ is_known │
│ created_at │ ┌─────────────────┐
│ last_modified │ │ Statistics │
│ review_count │ ├─────────────────┤
│ is_deleted │◄──────┤ card_id │
└─────────────────┘ │ review_time │
│ is_correct │
│ timestamp │
└─────────────────┘
- Flutter SDK: ^3.7.0
- Dart SDK: ^3.7.0
- Git
-
Clone the repository
git clone https://github.com/yourusername/cards-app.git cd cards-app -
Install dependencies
flutter pub get
-
Run the application
flutter run
- ✅ Android
- ✅ iOS
- ✅ Web
- ✅ Windows
- ✅ macOS
- ✅ Linux
- Navigate to the Flashcards tab
- Tap the + button to create a new card
- Enter front and back content
- Optionally add audio recording
- Select or create a category
- Save the card
- Select a category or deck
- Choose between Browse, Quiz, or Spaced Repetition
- Review cards and mark them as known/unknown
- View your performance statistics after completion
- Go to Settings
- Adjust theme preferences
- Configure accessibility options
- Set study reminders
- Manage data synchronization
Cards includes comprehensive test coverage:
# Run all tests
flutter test
# Run specific test files
flutter test test/database_helper_test.dart
flutter test test/flashcard_model_test.dart- Unit Tests: For testing individual classes and functions
- Widget Tests: For testing UI components
- Integration Tests: For testing feature workflows
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes: Follow the coding style and add tests
- Run tests: Ensure all tests pass
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - **Open a Pull Request`
- Follow the Dart style guide
- Use meaningful variable and function names
- Add documentation comments to public APIs
- Keep functions small and focused
This project is licensed under the MIT License - see the LICENSE file for details.
The core data structure is the Flashcard model. Below are its fields, types, and validation rules:
| Field | Type | Description | Validation/Notes |
|---|---|---|---|
| id | int? | Local auto-incremented ID | Optional, set by database |
| uuid | String? | Global unique identifier (for sync) | Required for sync/cloud |
| front | String | Front text of the card | Required, non-empty |
| back | String | Back text of the card | Required, non-empty |
| isKnown | bool | Whether the card is marked as known | Defaults to false |
| category | String? | Category name | Optional |
| audioPath | String? | Path to audio file (if any) | Optional |
| lastModified | int? | Last modified timestamp (ms since epoch) | Set automatically |
| isDeleted | bool | Soft delete flag | Defaults to false |
| reviewCount | int | Number of times reviewed | Defaults to 0 |
| lastReviewed | int? | Last review timestamp | Optional |
| difficultyScore | int | Difficulty score (0-100) | Defaults to 50 |
| customData | Map<String, dynamic>? | Custom user data (JSON) | Optional |
final card = Flashcard(
front: 'What is Flutter?',
back: 'A UI toolkit for building natively compiled apps.',
isKnown: false,
category: 'Programming',
);Currently, Cards does not expose a public HTTP API. All data access is local (SQLite/LocalStorage) or via Firebase Firestore (if enabled). If you enable sync, the app will use Firestore collections named flashcards for cloud storage. See services/firebase_manager.dart for details.
- Firebase: Set your Firebase project credentials in
lib/config/firebase_config.dart. - Analytics: If using analytics, add your keys in the same config file.
- Other: For custom environment variables, you can use Dart's
String.fromEnvironmentor a.envloader package.
You can enable/disable features in lib/config/app_config.dart:
class AppConfig {
static const bool useFirebase = false; // Enable cloud sync
static const bool enableAudioFeatures = true; // Enable audio recording
static const bool enableStatistics = true; // Enable statistics view
static const bool enableQuizMode = true; // Enable quiz mode
// ...
}Change these flags and rebuild the app to enable/disable features.
- Build fails on Windows: Ensure you have all required build tools (Visual Studio, CMake, etc.).
- Database errors: Delete the local database file if schema changes cause issues.
- Sync not working: Check your Firebase credentials and network connection.
- Audio not recording: Make sure microphone permissions are granted.
- How do I reset all data?
- Delete the app's local storage/database file and restart the app.
- How do I import/export cards?
- Use the Import/Export menu in the app (CSV format supported).
- Can I use my own Firebase project?
- Yes, update
firebase_config.dartwith your project details.
- Yes, update
- How do I add a new feature?
- Create a new folder in
features/and follow the existing structure.
- Create a new folder in
- Colorblind Mode: Daltonian-friendly color palettes are available in settings.
- Keyboard Navigation: All main actions are accessible via keyboard shortcuts (see tooltips in the UI).
- Screen Reader Support: UI widgets use semantic labels for compatibility with screen readers.
- Text Scaling: Users can adjust font size in the settings for better readability.
- Large Decks: Use category filters and search to limit the number of cards loaded at once.
- Database Maintenance: Periodically export and re-import your cards to clean up old/deleted entries.
- Sync Best Practices: Sync regularly and resolve conflicts promptly to avoid data loss.
- Disable Unused Features: Turn off features you don't use in
app_config.dartto reduce resource usage.
- Cards is designed for easy localization. To add a new language:
- Add your translation files to the
lib/l10n/directory (e.g.,intl_en.arb,intl_fr.arb). - Update the
pubspec.yamlto include your new language. - Use the
Intlpackage in your widgets for localized strings.
- Add your translation files to the
- To switch languages, change the locale in the app settings (if implemented) or set the device language.
See CHANGELOG.md for a full list of changes. Major recent updates:
- v1.0.0: Initial public release with flashcards, quiz, statistics, import/export, and sync support.
- v1.1.0: Added accessibility features and performance improvements.
- v1.2.0: Improved database schema and added advanced filtering.
- Data Storage: All user data is stored locally on device or in your private Firebase project.
- Privacy: No data is sent to third parties unless you enable cloud sync.
- Permissions: The app only requests permissions required for its features (e.g., microphone for audio).
- Data Deletion: Users can delete all their data at any time via the app interface.
- provider: State management (simple, robust, and recommended by Flutter).
- sqflite / sqflite_common_ffi: SQLite database for persistent local storage.
- just_audio: Audio playback for card pronunciation.
- file_picker: File import/export dialogs.
- uuid: Unique ID generation for cards and sync.
- firebase_core / cloud_firestore: Cloud sync and analytics (optional).
- intl: Internationalization and localization support.
- flutter_test / mockito: Testing and mocking utilities.
- Short Term:
- Add spaced repetition algorithms (SM-2, Anki-style)
- Improve mobile and web accessibility
- Add more statistics and progress charts
- Medium Term:
- REST API for remote access and integrations
- Real-time collaboration and shared decks
- In-app marketplace for public decks
- Long Term:
- AI-powered card generation and smart suggestions
- Native desktop and mobile notifications
- Plugin system for custom study modes
Get Cards up and running in just a few steps:
- Clone the repository
git clone https://github.com/yourusername/cards-app.git cd cards-app - Install dependencies
flutter pub get
- Run the app
flutter run
For more details, see the Installation section.
Watch a demo of Cards in action:
We welcome contributions! Please read our CONTRIBUTING.md for detailed instructions on how to:
- Propose new features
- Report bugs
- Submit pull requests
- Review code style and commit message conventions
We are committed to fostering a welcoming and inclusive community. Please read our CODE_OF_CONDUCT.md before participating.
To streamline collaboration, we use GitHub issue and pull request templates. When opening an issue or PR, please follow the provided format to help us address your contribution efficiently.
Cards is licensed under the MIT License. You are free to use, modify, and distribute the software, provided you include the original copyright and license.
- See the full license in LICENSE.
- Discord: Join our Discord
- Slack: Join our Slack
- Forum: Community Forum
- Email: support@cards-app.dev
Feel free to reach out for support, feature requests, or to connect with other users and contributors!
- No public REST API (local and Firebase sync only)
- No built-in spaced repetition algorithm (planned)
- No real-time collaboration (planned)
- Some advanced accessibility features may be limited on web
- Desktop builds require additional setup on Windows/macOS/Linux
- Only English and French localizations are currently available
+-------------------+
| User Interface |
+-------------------+
|
v
+-------------------+
| State Providers |
+-------------------+
|
v
+-------------------+
| Business Logic |
+-------------------+
|
v
+-------------------+
| Persistence Layer |
+-------------------+
| |
v v
SQLite Firebase
(Web) (Cloud)
User -> UI: Clicks "Add Card"
UI -> AddCardView: Opens form
AddCardView -> DatabaseHelper: saveCard(card)
DatabaseHelper -> Provider: Insert into DB
Provider -> Database: Store card
Database -> Provider: Success
Provider -> UI: Update card list
[User] -> [UI Widgets] -> [Providers] -> [Services] -> [Database/Cloud]
For more technical diagrams, see the /docs folder (if available) or contact the maintainers.
