This commit moves the `model:data` module to a top-level `data` module.
Additionally, a `README.md` file has been added to the project root, providing an overview of the project, architecture, build instructions, current limitations, and suggested improvements.
Key changes:
- Renamed Gradle module `model:data` to `data`.
- Updated `settings.gradle.kts` to reflect the new module path.
- Updated `app/build.gradle.kts` to depend on `projects.data` instead of `projects.model.data`.
- All source files, including `QuizRepositoryImpl`, `QuizMapper`, and `RepositoryModule`, were moved from `model/data/src` to `data/src`.
- Configuration files (`detekt.yml`, `lint-baseline.xml`, `build.gradle.kts`) were moved from `model/data` to `data`.
- Added a new `README.md` file at the project root.
This commit refactors how `ScreenUiState` is produced in `QuizScreenViewModel` by extracting the logic into a private `screenUiState` function that combines various flows. It also introduces `Result` sealed interface and `asResult()` Flow extension for handling asynchronous operations. Additionally, lint baseline files have been added to all modules and a Detekt configuration file for the `ui:quiz` module.
Key changes:
- **ViewModel Refactoring (`ui:quiz` module):**
- Introduced `Result.kt` with a sealed interface for `Success`, `Error`, and `Loading` states, along with an `asResult()` extension function for `Flow` to wrap emissions in `Result`.
- In `QuizScreenViewModel.kt`:
- The `quiz` state flow now uses `asResult()` and maps the `Result` to `QuizUiState`, handling potential error states by defaulting to `QuizUiState.Loading` (actual error UI handling is noted as a TODO).
- The logic for combining flows to produce `ScreenUiState` has been extracted into a new private function `screenUiState()`. This function takes the necessary flows as parameters and returns a `Flow<ScreenUiState>`.
- The `uiState` flow now uses this new `screenUiState()` function for its production.
- **Lint and Detekt Configuration:**
- Added `lint-baseline.xml` files to the following modules to establish a baseline for lint warnings:
- `app`
- `core/designsystem`
- `core/network`
- `domain`
- `model/data`
- `ui/quiz`
- Added `config/detekt/detekt.yml` to the `ui:quiz` module to configure Detekt rules, including exceptions for Jetpack Compose naming conventions, complexity rules for Composable functions, and style guidelines for magic numbers and unused private members. It also enables trailing commas for call sites and declaration sites.
- **Binary File:**
- Added `App.apk`.
This commit refactors the placement of the background image, moving it from `QuizScreen` to the main `KahootQuizApp` composable. This ensures the background is consistently applied across the app.
Additionally, this commit includes:
- Removal of unused Detekt configuration file (`ui/quiz/config/detekt/detekt.yml`).
- Minor code cleanup:
- Removed commented-out code in `Theme.kt` and `Type.kt`.
- Removed trailing blank lines in various domain model files.
- Added `@file:Suppress("TooManyFunctions")` to `QuizMapper.kt`.
- Added `@file:Suppress("MatchingDeclarationName")` to `QuizNavigation.kt`.
- Used `1.seconds` instead of `1000` (Long) for delay in `QuizScreenViewModel`.
This commit applies automated code formatting using Spotless across multiple modules. The changes primarily involve adjustments to trailing commas, spacing, and import statements to ensure consistency with the project's coding style.
Key changes include:
- **Kotlin Files:**
- Added trailing commas to multi-line parameter lists, argument lists, and collection literals in various Kotlin files across `app`, `core:designsystem`, `core:network`, `domain`, and `model:data` modules.
- Standardized spacing around operators and keywords.
- Optimized import statements in test files (`ExampleUnitTest.kt`, `ExampleInstrumentedTest.kt`).
- **XML Files:**
- Reformatted XML attributes in drawable vector files (`ic_*.xml`) within the `core:designsystem` module for better readability.
- **JSON Files:**
- Reformatted `sample_quiz.json` in `core:network` test resources for consistent structure.
- **Detekt Configuration:**
- Updated `detekt.yml` files in `app` and `core:designsystem` to adjust ignored annotations lists, ensuring proper spacing (e.g., `['Composable']` to `[ 'Composable' ]`).
This commit significantly revamps the `QuizScreen` UI to display question details including image and text, and introduces a new `core:designsystem` module to centralize theme, colors, typography, and drawable resources.
Key changes:
- **UI Layer (`ui:quiz` module):**
- Updated `QuizScreen.kt`:
- Implemented a background image for the screen.
- Added a `Toolbar` composable to display question progress and type.
- Created `QuestionContent` composable to show the question image (using Coil for image loading) and text.
- Added a placeholder `Choices` composable (currently an empty `LazyVerticalGrid`).
- Applied `fillMaxSize()` to the main `QuizScreen` modifier.
- Included a `@Preview` for `QuizScreen` with sample data.
- Modified `QuizScreenViewModel.kt` to update `QuizUiState` with the first `Question` from the fetched quiz.
- Added a `quiz` string resource in `strings.xml`.
- Added dependencies for Coil (compose and okhttp) in `ui/quiz/build.gradle.kts`.
- **Core Design System (`core:designsystem` module):**
- Created a new Android library module `core:designsystem`.
- Moved `Color.kt`, `Theme.kt`, and `Type.kt` from `app/src/main/java/dev/adriankuta/kahootquiz/ui/theme` to this new module.
- Added a new `Grey` color to `Color.kt`.
- Added `bg_image.webp` and `ic_type.xml` drawable resources.
- Configured the module with `kahootquiz.android.library.compose` plugin.
- **App Module (`app` module):**
- Updated `MainActivity.kt` to import `KahootQuizTheme` from the new `core.designsystem` package.
- Added `implementation(projects.core.designsystem)` dependency in `app/build.gradle.kts`.
- **Domain Layer (`domain` module):**
- Made several fields in `Question.kt` and `Choice.kt` nullable and provided default null values to accommodate potential missing data from the API.
- Specifically, `Question.image` is now non-nullable (`String`).
- **Build System:**
- Added `coilCompose` and `coilNetworkOkhttp` versions to `gradle/libs.versions.toml`.
- Included `:core:designsystem` in `settings.gradle.kts`.
This commit introduces the `QuizScreen` composable, its associated `QuizScreenViewModel`, and sets up the basic navigation graph for the application.
Key changes:
- **UI Layer (`ui:quiz` module):**
- Added `QuizScreen.kt` with a basic composable structure.
- Implemented `QuizScreenViewModel.kt` which fetches quiz data using `GetQuizUseCase` and exposes it via `QuizUiState`.
- Created `QuizUiState` data class to hold the quiz data for the UI.
- Added `navigation/QuizNavigation.kt` to define the `QuizRoute` and `quizScreen` navigation extension.
- Updated `ui/quiz/build.gradle.kts` to include dependencies for Hilt navigation and Timber.
- **App Module (`app` module):**
- Created `KahootQuizApp.kt` which sets up the main `Scaffold` and includes the navigation graph.
- Added `KahootQuizNavGraph.kt` to define the `NavHost` and integrate the `quizScreen`.
- Modified `MainActivity.kt` to call the new `KahootQuizApp` composable, removing the previous direct use case call and UI.
- **Data Layer (`model:data` module):**
- Updated `QuizMapper.kt` to convert `time` from `Long?` to `Duration?` (using `milliseconds`) when mapping `QuestionDto` to the domain `Question` model.
This commit significantly expands the domain models to fully represent the quiz structure and implements the complete mapping logic in `QuizMapper` to convert `QuizResponseDto` and its nested DTOs to their corresponding domain models.
Key changes:
- **Domain Layer (`domain` module):**
- Introduced a `QuizId` value class for type safety.
- Added comprehensive domain models for all aspects of a quiz, including:
- `Quiz`: Updated to include all fields from the DTO.
- `Question`, `Choice`, `Video`, `ImageMetadata`, `MediaItem`, `ChoiceRange`: For question details.
- `CoverMetadata`, `ExtractedColor`, `Crop`, `Point`: For cover image information.
- `ContentTags`: For curriculum and generated codes.
- `Metadata`, `Access`, `FeaturedListMembership`, `LastEdit`, `VersionMetadata`: For quiz metadata.
- `LanguageInfo`, `Channel`: Common reusable models.
- Organized domain models into separate files for better maintainability (e.g., `Question.kt`, `CoverMetadata.kt`).
- Added a placeholder `QuestionModels.kt` to indicate that models were moved.
- **Data Layer (`model:data` module):**
- Implemented a complete `toDomainModel()` extension function in `QuizMapper.kt` to map all fields from `QuizResponseDto` and its nested DTOs (like `CoverMetadataDto`, `QuestionDto`, etc.) to the new domain models.
- This includes mapping for lists and nullable fields.
- **App Module (`app` module):**
- Updated `MainActivity` to access `quizId.value` due to `QuizId` being a value class.
- **Network Layer (`core:network` module):**
- Changed `QuizResponseDto.uuid` to be non-nullable (`String`) as it's essential for mapping to `QuizId`.
- Removed `QuizResponse.kt` as DTOs were previously split into individual files.
This commit introduces the data layer, including the `QuizRepository` and its implementation, and integrates it with the domain layer's `GetQuizUseCase`. It also sets up Hilt for dependency injection in the app module and makes preliminary UI changes to display fetched quiz data.
Key changes include:
- **Data Layer (`model:data` module):**
- Added `QuizRepositoryImpl` which implements `QuizRepository` from the domain layer.
- Implemented `getQuiz()` in `QuizRepositoryImpl` to fetch quiz data from `QuizApi` and map it to the domain `Quiz` model using `QuizMapper`.
- Created `QuizMapper` to convert `QuizResponseDto` to the domain `Quiz` model.
- Added `RepositoryModule` for Hilt to provide `QuizRepository` bindings.
- **Domain Layer (`domain` module):**
- Created `Quiz` domain model.
- Defined `QuizRepository` interface.
- Implemented `GetQuizUseCase` to interact with `QuizRepository`.
- **App Module (`app` module):**
- Added `MyApplication` class annotated with `@HiltAndroidApp`.
- Updated `AndroidManifest.xml` to use `MyApplication` and add internet permission.
- In `MainActivity`:
- Injected `GetQuizUseCase`.
- Used `LaunchedEffect` to call the use case and update a mutable state `quizId`.
- Modified the `Greeting` composable to display the fetched `quizId`.
- Added dependency on the `domain` module in `app/build.gradle.kts`.
- **Network Layer (`core:network` module):**
- Moved DTOs from `core.network.model` package to `core.network.models`.
- Made `NetworkModule` internal.
- Removed unused `QuizService` interface and `QuizServiceImpl` class.
- **Testing (`core:network` test):**
- Updated import path for `QuizResponseDto` in `QuizResponseDtoParsingTest`.
This commit introduces the foundational structure of the Kahoot Quiz application and implements the core network layer.
Key changes include:
- Added new Gradle modules: `core:network`, `domain`, `model:data`, and `ui:quiz`.
- Configured Detekt for static code analysis in the new modules.
- Implemented Retrofit and Gson for network communication and JSON parsing.
- Defined DTOs for the Kahoot quiz API response, splitting them into logical files (QuizResponseDto, CommonDtos, CoverDtos, QuestionDtos, MetadataDtos, ContentTagsDto) for better organization.
- Created `QuizApi` interface with a GET request for fetching quiz data.
- Added `QuizService` interface and its initial implementation `QuizServiceImpl`.
- Set up Hilt for dependency injection in the network module, providing Retrofit and QuizApi instances.
- Included a `sample_quiz.json` file for testing and development.
- Added unit tests (`QuizResponseDtoParsingTest`) to verify the correct parsing of the sample JSON into DTOs.
- Updated `.gitignore` to exclude additional generated files and IDE specific folders.
- Modified `settings.gradle.kts` to include the new modules.
- Updated `app/build.gradle.kts` to include dependencies on the new `ui:quiz` and `model:data` modules and removed unused dependencies.