task-tracker

Task Tracker ๐Ÿ“

A modern, offline-first task tracking Android app built with Kotlin, Jetpack Compose, and Material 3. Designed for personal productivity with a focus on clean architecture, performance, and user experience.

โœจ Features

Core Functionality

Backup & Restore

Sorting & Organization

User Experience

๐Ÿ—๏ธ Architecture

Clean Architecture with MVVM

The app follows Clean Architecture principles with MVVM pattern and reactive programming:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Presentation  โ”‚    โ”‚     Domain       โ”‚    โ”‚      Data       โ”‚
โ”‚                 โ”‚    โ”‚                  โ”‚    โ”‚                 โ”‚
โ”‚ โ€ข UI Components โ”‚โ—„โ”€โ”€โ–บโ”‚ โ€ข Use Cases      โ”‚โ—„โ”€โ”€โ–บโ”‚ โ€ข Repository    โ”‚
โ”‚ โ€ข ViewModels    โ”‚    โ”‚ โ€ข Business Logic โ”‚    โ”‚ โ€ข Room Database โ”‚
โ”‚ โ€ข State Managersโ”‚    โ”‚ โ€ข Services       โ”‚    โ”‚ โ€ข DAOs          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Modular Design

Recent refactoring has separated concerns into focused, maintainable components:

ViewModel Layer (Thin Coordinators)

State Management Layer

Business Logic Layer

UI Layer (Modular Components)

๐Ÿ› ๏ธ Technology Stack

Core Technologies

Architecture Components

Data & Persistence

Development Tools

๐Ÿ“ Project Structure

app/src/main/java/dev/tuandoan/tasktracker/
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ database/
โ”‚   โ”‚   โ”œโ”€โ”€ Task.kt                 # Task entity with due dates and reminders
โ”‚   โ”‚   โ”œโ”€โ”€ TaskDao.kt              # Room data access object
โ”‚   โ”‚   โ””โ”€โ”€ TaskDatabase.kt         # Room database with migration support
โ”‚   โ”œโ”€โ”€ backup/
โ”‚   โ”‚   โ”œโ”€โ”€ dto/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ TaskBackupDto.kt         # Serializable DTO for task backup
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ BackupPayload.kt         # JSON envelope with metadata
โ”‚   โ”‚   โ”œโ”€โ”€ BackupSerializer.kt          # Serialization interface
โ”‚   โ”‚   โ”œโ”€โ”€ JsonBackupSerializer.kt      # JSON implementation (kotlinx.serialization)
โ”‚   โ”‚   โ”œโ”€โ”€ CsvBackupSerializer.kt       # CSV implementation (RFC 4180)
โ”‚   โ”‚   โ”œโ”€โ”€ BackupFileProvider.kt        # File I/O interface
โ”‚   โ”‚   โ””โ”€โ”€ AndroidBackupFileProvider.kt # ContentResolver implementation
โ”‚   โ”œโ”€โ”€ scheduler/
โ”‚   โ”‚   โ””โ”€โ”€ WorkManagerTaskReminderScheduler.kt # WorkManager reminder implementation
โ”‚   โ””โ”€โ”€ preferences/
โ”‚       โ”œโ”€โ”€ SettingsRepository.kt        # DataStore-backed settings persistence
โ”‚       โ””โ”€โ”€ UserPreferences.kt           # Data class for theme, language, dynamic color prefs
โ”œโ”€โ”€ di/
โ”‚   โ””โ”€โ”€ PreferencesModule.kt             # Hilt module for DataStore and settings DI
โ”œโ”€โ”€ domain/
โ”‚   โ”œโ”€โ”€ backup/
โ”‚   โ”‚   โ”œโ”€โ”€ model/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ BackupFormat.kt        # Enum (JSON, CSV)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ BackupMetadata.kt      # Metadata with schema version
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ExportResult.kt        # Sealed class for export results
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ ImportResult.kt        # Sealed class for import results
โ”‚   โ”‚   โ”œโ”€โ”€ BackupValidator.kt         # Validation interface
โ”‚   โ”‚   โ”œโ”€โ”€ TaskBackupValidator.kt     # Validation rules implementation
โ”‚   โ”‚   โ”œโ”€โ”€ ExportBackupUseCase.kt     # Export orchestration
โ”‚   โ”‚   โ””โ”€โ”€ ImportBackupUseCase.kt     # Import orchestration
โ”‚   โ”œโ”€โ”€ model/                      # Domain models and data classes
โ”‚   โ”‚   โ”œโ”€โ”€ TaskSort.kt            # Sorting enums and configuration
โ”‚   โ”‚   โ”œโ”€โ”€ ReminderOption.kt      # Reminder time options enum
โ”‚   โ”‚   โ””โ”€โ”€ ...
โ”‚   โ”œโ”€โ”€ service/                    # Pure business logic services
โ”‚   โ”‚   โ””โ”€โ”€ TaskSortService.kt     # Sorting algorithms and rules
โ”‚   โ”œโ”€โ”€ scheduler/                  # Background task scheduling
โ”‚   โ”‚   โ””โ”€โ”€ TaskReminderScheduler.kt # Reminder scheduling interface
โ”‚   โ””โ”€โ”€ usecase/                   # Business use cases
โ”‚       โ”œโ”€โ”€ TaskCrudUseCase.kt     # CRUD operations
โ”‚       โ”œโ”€โ”€ TaskSearchUseCase.kt   # Search with debounce
โ”‚       โ”œโ”€โ”€ TaskFilterUseCase.kt   # Status filtering
โ”‚       โ””โ”€โ”€ TaskFormUseCase.kt     # Form management
โ”œโ”€โ”€ ui/
โ”‚   โ”œโ”€โ”€ components/                 # Reusable UI components
โ”‚   โ”‚   โ”œโ”€โ”€ TaskListTopBar.kt      # Top bar with sort menu
โ”‚   โ”‚   โ”œโ”€โ”€ SortMenu.kt            # Sort dropdown component
โ”‚   โ”‚   โ”œโ”€โ”€ TaskListContent.kt     # Main content area
โ”‚   โ”‚   โ”œโ”€โ”€ TaskItem.kt            # Individual task display
โ”‚   โ”‚   โ”œโ”€โ”€ SearchField.kt         # Search input component
โ”‚   โ”‚   โ””โ”€โ”€ FilterTabs.kt          # Status filter tabs
โ”‚   โ”œโ”€โ”€ screens/                   # Main screens
โ”‚   โ”‚   โ”œโ”€โ”€ TaskListScreen.kt      # Primary task list screen
โ”‚   โ”‚   โ”œโ”€โ”€ TaskEditorScreen.kt    # Dedicated full-screen task editor (optimized for small devices)
โ”‚   โ”‚   โ””โ”€โ”€ ArchivedScreen.kt      # Archived tasks management screen
โ”‚   โ”œโ”€โ”€ state/                     # State management
โ”‚   โ”‚   โ”œโ”€โ”€ TaskListStateManager.kt   # List state coordination
โ”‚   โ”‚   โ””โ”€โ”€ TaskFormStateManager.kt   # Form state management
โ”‚   โ”œโ”€โ”€ manager/                   # Business logic coordinators
โ”‚   โ”‚   โ””โ”€โ”€ TaskCrudManager.kt     # CRUD operations coordination
โ”‚   โ””โ”€โ”€ viewmodel/
โ”‚       โ”œโ”€โ”€ TaskViewModel.kt       # Main ViewModel coordinator
โ”‚       โ”œโ”€โ”€ TaskEditorViewModel.kt # Dedicated ViewModel for task editor screen
โ”‚       โ””โ”€โ”€ TaskFilter.kt          # Filter enum
โ”œโ”€โ”€ utils/
โ”‚   โ””โ”€โ”€ DateUtils.kt              # Date formatting and overdue detection
โ”œโ”€โ”€ work/
โ”‚   โ””โ”€โ”€ TaskReminderWorker.kt     # WorkManager worker for notifications
โ”œโ”€โ”€ TaskTrackerApplication.kt     # Application class with notification setup
โ””โ”€โ”€ MainActivity.kt                # App entry point (AppCompatActivity for locale support)

app/src/main/res/
โ”œโ”€โ”€ values/
โ”‚   โ””โ”€โ”€ strings.xml                # Default (English) string resources
โ”œโ”€โ”€ values-de/
โ”‚   โ””โ”€โ”€ strings.xml                # German (Deutsch) translations
โ”œโ”€โ”€ values-es/
โ”‚   โ””โ”€โ”€ strings.xml                # Spanish (Espaรฑol) translations
โ”œโ”€โ”€ values-fr/
โ”‚   โ””โ”€โ”€ strings.xml                # French (Franรงais) translations
โ”œโ”€โ”€ values-hi/
โ”‚   โ””โ”€โ”€ strings.xml                # Hindi (เคนเคฟเคจเฅเคฆเฅ€) translations
โ”œโ”€โ”€ values-in/
โ”‚   โ””โ”€โ”€ strings.xml                # Indonesian (Bahasa Indonesia) translations
โ”œโ”€โ”€ values-pt/
โ”‚   โ””โ”€โ”€ strings.xml                # Portuguese (Portuguรชs) translations
โ”œโ”€โ”€ values-vi/
โ”‚   โ””โ”€โ”€ strings.xml                # Vietnamese (Tiแบฟng Viแป‡t) translations
โ””โ”€โ”€ xml/
    โ””โ”€โ”€ locales_config.xml         # Registered locales for per-app language (Android 13+)

๐ŸŒ Internationalization (i18n)

Supported Languages

Per-App Language Selection

The app supports per-app language selection on all supported Android versions:

Users can change the language in Settings โ†’ Language without affecting other apps.

Adding a New Language

To add support for a new locale (e.g., Japanese ja):

  1. Create the resource directory:
    mkdir -p app/src/main/res/values-ja
    
  2. Copy and translate strings.xml:
    cp app/src/main/res/values/strings.xml app/src/main/res/values-ja/strings.xml
    

    Translate all <string> values in the new file. Keep the name attributes unchanged.

  3. Register the locale in app/src/main/res/xml/locales_config.xml:
    <locale-config xmlns:android="http://schemas.android.com/apk/res/android">
        <locale android:name="en" />
        <locale android:name="vi" />
        <locale android:name="ja" />  <!-- Add this line -->
    </locale-config>
    
  4. Build and test:
    ./gradlew assembleDebug
    

    The new language will automatically appear in the Settings โ†’ Language picker.

Testing Translations

String Resource Guidelines

๐Ÿš€ Getting Started

Prerequisites

Installation

  1. Clone the repository
    git clone https://github.com/yourusername/task-tracker.git
    cd task-tracker
    
  2. Open in Android Studio
    • Launch Android Studio
    • Select โ€œOpen an existing projectโ€
    • Navigate to the cloned directory
  3. Build and Run
    ./gradlew build
    ./gradlew installDebug
    

Development Setup

  1. Enable Kotlin compiler optimizations
    # Add to local.properties
    kotlin.compiler.execution.strategy=in-process
    
  2. Run tests
    ./gradlew test                    # Unit tests
    ./gradlew connectedAndroidTest   # Instrumentation tests
    
  3. Generate release build
    ./gradlew assembleRelease
    

๐Ÿ“ฑ Usage

Basic Operations

  1. Add Task - Tap the floating action button (โž•) to open the full-screen task editor
  2. Edit Task - Tap on any task to open the dedicated editor screen with all task fields (in normal mode)
  3. Complete Task - Tap the checkbox to mark a task as complete/incomplete
  4. Archive Task - Use the archive button to safely archive tasks with confirmation dialog and undo functionality

Bulk Operations

  1. Enter Selection Mode - Long-press on any task to enter selection mode
  2. Select Multiple Tasks - Tap on tasks to toggle selection (highlighted in blue)
  3. Bulk Actions - Use top bar buttons to:
    • Mark selected tasks as completed (โœ“)
    • Mark selected tasks as active (โ–ก)
    • Archive selected tasks (๐Ÿ—„๏ธ) with confirmation and undo
  4. Select All - Use overflow menu (โ‹ฎ) to select all visible tasks
  5. Exit Selection - Tap the close button (โœ•) to clear selection

Archive Management

  1. View Archived Tasks - Navigate to the archived tasks screen to see all archived tasks
  2. Restore Tasks - Tap restore button on archived tasks to return them to the main task list
  3. Permanent Delete - Use permanent delete on archived tasks (cannot be undone)
  4. Bulk Archive Operations - Select multiple archived tasks for bulk restore or permanent deletion

Advanced Features

  1. Search Tasks - Type in the search field to find tasks by title or description
  2. Filter by Status - Use the tabs (All, Active, Completed) to filter tasks
  3. Sort Tasks - Tap the sort button (โš™๏ธ) to choose sorting options:
    • Created: Newest first (default)
    • Created: Oldest first
    • Title: A-Z
    • Priority: High to Low
  4. Group Completed - Toggle โ€œCompleted lastโ€ to group completed tasks at the bottom
  5. Set Due Dates - Tap the calendar icon in Add/Edit dialog to set optional due dates
  6. Configure Reminders - Choose from 1 minute, 5 minutes, 1 hour, or 1 day before due date (requires future due date and validates reminder time is in the future). On Android 13+, the app will prompt for notification permission when first enabling reminders.
  7. Organize with Tags - Add an optional single tag to tasks for categorization (up to 20 characters). Tags appear as chips in the task list and can be used for filtering.
  8. Filter by Tags - Use the tag filter chips below the status tabs to filter tasks by specific tags. Tap a tag chip to filter, tap again to clear.
  9. Pin Important Tasks - Tap the star button on any task to pin/unpin it. Pinned tasks appear first within each day section.
  10. Set Task Priority - In the Add/Edit task dialog, use the Priority dropdown to set Low, Medium (default), or High priority levels.
  11. Track Overdue Tasks - Overdue tasks display in red with โ€œOverdueโ€ indicators in the task list

Pro Tips

๐Ÿ”ง Development

Architecture Benefits

Code Quality

Testing Strategy

The project has a comprehensive JVM unit test suite covering core business logic, domain services, use cases, state managers, and backup serialization. Tests are fast (< 1 second), deterministic, and require no emulator or device.

Running Tests

# Run all unit tests
./gradlew testDebugUnitTest

# Run all unit tests (debug + release)
./gradlew test

# Run a specific test class
./gradlew testDebugUnitTest --tests "dev.tuandoan.tasktracker.domain.TaskManagerTest"

# Run with verbose output
./gradlew testDebugUnitTest --info

# Format code before committing
./gradlew spotlessApply

Test Suite Overview (263 tests)

Layer Test Class Tests What It Covers
Domain TaskManagerTest 31 CRUD, completion toggle, archive, bulk ops, reminder scheduling
Domain TaskSortServiceTest 16 Sort by created/title/priority, completed grouping, stability
Domain TaskSortTest 10 Display names, full display names, defaults
Domain ReminderOptionTest 10 fromOffsetMinutes mapping, selectable options, offset values
Domain PriorityTest 7 fromValue mapping, display names, int values
Use Case TaskCrudUseCaseTest 23 Create, update, delete, toggle, restore, bulk ops, archive, pin/priority
Use Case TaskFormUseCaseTest 23 Title/desc/tag validation, length limits, form data trimming, dialog state
Use Case TaskFilterUseCaseTest 9 Status filtering (ALL/ACTIVE/COMPLETED), filter state, hasActiveFilter
Use Case TaskSearchUseCaseTest 10 Case-insensitive search, title+description matching, query state
UI State TaskSelectionStateManagerTest 20 Enter/toggle/clear/selectAll, validation, StateFlow reactivity
UI Manager TaskCrudManagerValidationTest 25 Input validation for bulk ops, archive ops, toggle, pin
UI Manager TaskBulkActionManagerTest 20 Bulk delete/archive/complete/restore flows with confirmation
Backup JsonBackupSerializerTest 10 Round-trip, missing fields, unknown keys, schema version, malformed JSON
Backup CsvBackupSerializerTest 13 Round-trip, escaping, special chars, empty fields, malformed CSV
Backup TaskBackupValidatorTest 14 Blank title skip, priority clamping, timestamp defaults, truncation
Backup TaskBackupDtoTest 6 fromTask/toTask mapping, round-trip, defaults
Utils TaskDateGrouperTest 12 Day grouping, date keys, header labels, pinned ordering, dueAt priority
Utils DateUtilsTest 4 formatDate, formatDueDate, isOverdue

Test Infrastructure

CI Integration

Add this step to your GitHub Actions workflow:

- name: Run unit tests
  run: ./gradlew testDebugUnitTest

- name: Check code formatting
  run: ./gradlew spotlessCheck

Coverage Gaps (documented, not yet covered)

๐ŸŽฏ Performance Optimizations

๐Ÿ“š Recent Updates

v3.2 - Localization Expansion (8 Languages)

v3.1 - Global Language Support & Theme Polish

v3.0 - Dedicated Task Editor Screen (Small Device Optimization)

v2.9 - UI/UX Enhancements & Material 3 Polish

v2.8 - Minimal Stats (Lightweight Analytics)

v2.7 - Archive System (Soft Delete)

v2.6 - Pin Tasks & Priority Levels

v2.5 - Tag Organization & Filtering

v2.4 - Due Dates & Local Reminders

Note: On Android 13+ (API 33+), notification permission is required for reminders. The app will prompt contextually when enabling reminders with an education dialog explaining the requirement.

v2.3 - Production-Ready Validation & Form UX

v2.2 - Multi-Select & Bulk Actions

v2.1 - Enhanced User Safety

v2.0 - Advanced Sorting & Modular Architecture

v1.0 - Core Features

๐ŸŽฏ Code Style & Formatting

This project uses Spotless with ktlint to enforce consistent code formatting across all Kotlin and Gradle files.

Running Formatting

# Apply code formatting fixes
./gradlew spotlessApply

# Check code formatting (fails build if violations exist)
./gradlew spotlessCheck

Configuration

The formatting check runs automatically during the build process. All code must pass formatting checks before merging.

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Run formatting: ./gradlew spotlessApply
  4. Commit your changes (git commit -m 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request

Development Guidelines

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments


Built with โค๏ธ for productivity and clean code