Skip to content

ankit-verma-209171/AniFlow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AniFlow

A modern Android anime browsing application built with Jetpack Compose and implementing an offline-first architecture with local Room caching and network sync via Paging 3 RemoteMediator.

Features

  • 🎬 Top Anime Browsing β€” Browse a curated list of top-rated anime with detailed information
  • πŸ“± Offline-First Architecture β€” Works seamlessly with or without internet connectivity
  • πŸ”„ Automatic Network Sync β€” Paging 3 RemoteMediator syncs data when connectivity is restored
  • πŸ’Ύ Local Persistence β€” Room database caches anime data for instant access
  • 🎨 Modern UI β€” Built with Jetpack Compose and Material Design 3
  • πŸš€ Type-Safe Navigation β€” AndroidX Navigation 3 with serializable destinations
  • πŸ”Œ Dependency Injection β€” Hilt + Dagger 2 for clean dependency management

Tech Stack

  • UI Framework: Jetpack Compose + Material Design 3
  • Navigation: AndroidX Navigation 3 (type-safe routes with @Serializable destinations)
  • Architecture: MVVM (ViewModel + Repository pattern)
  • Networking: Retrofit 3 + OkHttp 5 + KotlinX Serialization
  • Data Persistence: Room 2.8 with RemoteMediator for offline-first paging
  • Paging: Paging 3 with lazy loading and remote sync
  • Image Loading: Coil 3
  • Dependency Injection: Hilt + Dagger 2 (KSP code generation)
  • Build System: Gradle with Kotlin 2.3.10 + KSP compiler
  • Testing: JUnit 4, Espresso, Mockk

API: Jikan API v4 (anime database REST API)

Architecture Overview

AniFlow follows Clean Architecture principles with three layers:

πŸ“¦ Core Layers

  • core/data: Data layer containing network requests, local database, repositories, and mappers

    • network/: Retrofit service, DTOs, custom ApiResult<T> wrapper for error handling
    • local/: Room database, entities, DAOs
    • repository/: Repository implementations (interface in core/domain)
    • paging/: RemoteMediator for Paging 3 synchronization
    • di/: Hilt dependency injection modules
  • core/domain: Domain layer containing business logic and contracts

    • Models: Pure Kotlin data class representations of domain entities
    • Repository interfaces: Defined in domain, implemented in data layer
    • Use cases: Business logic independent of UI framework

🎯 Feature Layers

  • feature/anime/: Feature-specific UI and presentation logic
    • home/: Home screen with anime list display
    • components/: Reusable feature-specific composables
    • navigation/: Destinations and navigation graph registration

🎨 Global UI

  • ui/: Shared UI components and theming
    • navigation/: Root navigation host configuration
    • theme/: Material 3 color tokens, typography, shapes

Project Structure

app/src/main/java/com/codeitsolo/aniflow/
β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ data/                          # Data layer
β”‚   β”‚   β”œβ”€β”€ network/
β”‚   β”‚   β”‚   β”œβ”€β”€ service/AnimeService.kt
β”‚   β”‚   β”‚   β”œβ”€β”€ dto/                   # API DTOs
β”‚   β”‚   β”‚   β”œβ”€β”€ model/ApiResult<T>     # Success/Error/Exception wrapper
β”‚   β”‚   β”‚   └── adapter/               # Retrofit call adapter
β”‚   β”‚   β”œβ”€β”€ local/
β”‚   β”‚   β”‚   β”œβ”€β”€ db/AniFlowDatabase.kt
β”‚   β”‚   β”‚   β”œβ”€β”€ entity/                # Room entities
β”‚   β”‚   β”‚   └── dao/                   # Data Access Objects
β”‚   β”‚   β”œβ”€β”€ repository/                # Repository implementations
β”‚   β”‚   β”œβ”€β”€ mapper/                    # DTO/Entity ↔ Domain mappers
β”‚   β”‚   β”œβ”€β”€ paging/TopAnimeRemoteMediator.kt
β”‚   β”‚   └── di/                        # Hilt modules
β”‚   └── domain/
β”‚       β”œβ”€β”€ model/                     # Domain models
β”‚       └── repository/                # Repository interfaces
β”œβ”€β”€ feature/
β”‚   └── anime/
β”‚       β”œβ”€β”€ home/                      # Home screen
β”‚       β”œβ”€β”€ components/                # Feature composables
β”‚       └── navigation/
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ navigation/AppNavHost.kt
β”‚   β”œβ”€β”€ theme/                         # Material 3 tokens
β”‚   └── components/                    # Global components
β”œβ”€β”€ AniFlowApp.kt                      # @HiltAndroidApp entry
└── MainActivity.kt                    # Compose activity host

Getting Started

Prerequisites

  • Android Studio Jellyfish or newer
  • Android SDK 26+ (API 26 - Android 8.0)
  • JDK 11 or higher
  • Git

Setup

  1. Clone the repository:

    git clone https://github.com/yourusername/AniFlow.git
    cd AniFlow
  2. Open in Android Studio:

    • File β†’ Open β†’ Select the AniFlow directory
    • Let Gradle sync complete
  3. (Optional) Configure local.properties:

    • Create local.properties in the root directory
    • Add SDK path: sdk.dir=/path/to/android/sdk

Building & Running

Build Debug APK

./gradlew :app:assembleDebug

Install & Run on Connected Device

./gradlew :app:installDebug

Quick Kotlin Compilation Check

./gradlew :app:compileDebugKotlin

Build Release APK

./gradlew :app:assembleRelease

Clean & Force Regeneration (KSP/Room)

./gradlew clean

Testing

Run JVM Unit Tests

./gradlew :app:testDebugUnitTest

Run Instrumentation Tests (Android device/emulator required)

./gradlew :app:connectedDebugAndroidTest

Run All Tests

./gradlew :app:testDebugUnitTest :app:connectedDebugAndroidTest

Key Design Patterns

1. Offline-First Data Architecture

  • Local Room database is the source of truth for UI
  • RemoteMediator syncs from API on demand (REFRESH, APPEND)
  • Pager combines local DB + remote sync into Flow<PagingData<Anime>>

2. ApiResult Error Handling

Custom sealed interface wrapping Retrofit responses:

when (result) {
    is ApiSuccess -> { /* handle success */ }
    is ApiError -> { /* handle API error */ }
    is ApiException -> { /* handle exception */ }
}

3. Type-Safe Navigation

Destinations are @Serializable data objects, not string routes:

@Serializable
data object Home : NavKey

@Serializable
data object Details : NavKey

4. RemoteMediator + Paging 3

Handles pagination with automatic database sync via RemoteMediator.load()

5. ViewModel + StateFlow

ViewModels expose Flow<PagingData<T>> for composables to consume

Configuration

Build Configuration

  • Namespace: com.codeitsolo.aniflow
  • Min SDK: 26 (Android 8.0)
  • Target SDK: 36 (Android 15)
  • Java: Version 11
  • Kotlin: 2.3.10

Dependency Versions

All versions centralized in gradle/libs.versions.toml:

  • Reference as libs.retrofit, libs.room.runtime, etc.
  • Update in .toml file, not in build.gradle.kts

Troubleshooting

Issue Solution
Navigation fails to compile Ensure all destinations extend NavKey and are @Serializable
Hilt injection not found Add @AndroidEntryPoint to Activity, @HiltViewModel to ViewModel
RemoteMediator not triggered Verify it's passed to Pager() with correct pagingSourceFactory
Paging shows duplicates Ensure RemoteMediator uses database.withTransaction{} correctly
JSON deserialization fails Verify DTO field names match API response, check ignoreUnknownKeys
KSP cache issues Run ./gradlew clean then rebuild

License

MIT License Β© 2026 CodeItSolo

About

AniFlow - A modern Android anime browsing application built with Jetpack Compose and implementing an offline-first architecture with local Room caching and network sync via Paging 3 RemoteMediator.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages