Skip to content

DeguShi/What-Manga-APP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

138 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📚 What-Manga

A native Android app for tracking manga and light novel reading progress

Android Kotlin Jetpack Compose Room

FeaturesArchitectureGoogle Drive BackupBuildTesting


Project Status

What-Manga is a personal production app that I actively develop and use. The Android application in this repository is the primary platform. The original web application remains maintained as a separate project and deployed independently.


Overview

What-Manga is a personal manga and light novel tracking application built as a native Android app. It allows users to maintain a comprehensive collection of reading progress with offline-first storage and optional cloud backup via Google Drive.

Origin

This project originated as a Next.js web application. The Android version was built to bring the same functionality to mobile with a truly native experience:

  • Offline-first local storage using Room database
  • Native Material 3 UI with Jetpack Compose
  • Google Drive backup for data portability
  • Smooth animations and haptic feedback

Why It Exists

Tracking hundreds of manga and light novel entries across multiple platforms is cumbersome. What-Manga provides a unified, personal tracker with:

  • Custom indexing — Maintain your personal ordering
  • Progress tracking — Track manga chapters and novel volumes separately
  • CSV import/export — Portable data format for backup and migration
  • Cloud sync — Optional Google Drive backup for cross-device access

Quick Start

Download

The pre-built APK is available in the Releases section.

Sample Data Format

The samples/ folder contains an example CSV (demo_data.csv) showing the expected data format for importing entries into the app.

If your data is in a different format, you can use the original web application to import and convert it:

🌐 What-Manga (Web App)

The original full-stack Next.js web application. It features a Smart Import System that can parse a custom .txt notation format (e.g., 1- Naruto (*72 vol.). {10}) and import it into the database. You can fork this project, adapt the .txt parser to accept your specific notation, import your data, then export it as a CSV compatible with this Android APK.


Features

📊 Collection Management

  • Real-time search across all entries
  • Filter by status (Reading, Completed, Dropped/Hiatus, etc.)
  • Sort by index, score, or title
  • Swipe-to-delete with undo support

✏️ Entry Management

  • Create new manga/novel entries
  • Track manga and novel progress separately
  • Score entries on a 0-10 scale
  • Add personal review notes

📥 Import/Export

  • CSV import with anti-duplication logic
  • CSV export for backup
  • Automatic backup detection (distinguishes backup files from user CSVs)

☁️ Cloud Backup

  • Google Drive integration using OAuth 2.0
  • Automatic backup on data changes (debounced)
  • Manual backup and restore options
  • Local backup history

🎨 Premium UI

  • Material 3 design with custom color palette
  • Dark and light mode support
  • Glassmorphism effects
  • Smooth spring animations
  • Haptic feedback on interactions

Architecture

What-Manga follows a clean architecture pattern with clear separation of concerns.

Layer Overview

flowchart TB
    subgraph UI["UI Layer (Compose)"]
        Screens[Screens]
        Components[Components]
        Theme[Theme System]
    end
    
    subgraph ViewModel["ViewModel Layer"]
        WVM[WorkListViewModel]
        StateFlow[StateFlow + combine]
    end
    
    subgraph Repository["Repository Layer"]
        WR[WorkRepository]
        DCN[DataChangeNotifier]
    end
    
    subgraph Data["Data Layer"]
        Room[(Room Database)]
        DAO[WorkDao]
    end
    
    subgraph Backup["Backup Layer"]
        BM[BackupManager]
        GDB[GoogleDriveBackup]
        CSV[CsvUtils]
    end
    
    UI --> ViewModel
    ViewModel --> Repository
    Repository --> Data
    Repository --> DCN
    DCN --> Backup
    BM --> GDB
    BM --> CSV
Loading

Data Flow

sequenceDiagram
    participant UI as UI
    participant VM as ViewModel
    participant Repo as Repository
    participant DB as Room DB
    participant Notifier as DataChangeNotifier
    participant Backup as BackupManager
    participant Drive as Google Drive

    UI->>VM: User action (create/edit/delete)
    VM->>Repo: Data mutation
    Repo->>DB: Write to Room
    Repo->>Notifier: Emit DataChangeEvent
    Notifier->>Backup: onDataChanged()
    
    alt Source in allowlist
        Backup->>Backup: Debounce (3s)
        Backup->>Drive: Upload CSV backup
    else Source not in allowlist
        Note over Backup: No backup triggered
    end
    
    DB-->>Repo: Flow<List<Work>>
    Repo-->>VM: StateFlow<List<Work>>
    VM-->>UI: Recompose with new data
Loading

Technology Stack

Layer Technology
UI Jetpack Compose, Material 3
State StateFlow, ViewModel
Database Room (SQLite)
Async Kotlin Coroutines, Flow
Backup Google Drive REST API v3
Auth Google Sign-In SDK

Project Structure

android/app/src/main/java/com/whatmanga/app/
├── MainActivity.kt           # Entry point, theme management
├── WhatMangaApp.kt           # Application class, dependency init
├── backup/
│   ├── BackupManager.kt      # Orchestrates backup operations
│   ├── GoogleDriveBackup.kt  # Drive API integration
│   ├── CsvUtils.kt           # CSV parsing/generation
│   └── DataChangeNotifier.kt # Event bus for data mutations
├── data/
│   ├── Work.kt               # Room entity
│   ├── WorkDao.kt            # Data access object
│   ├── WorkRepository.kt     # Repository with mutation tracking
│   └── import/               # Import row models
├── ui/
│   ├── components/           # Reusable UI components
│   ├── screens/              # Full-screen composables
│   └── theme/                # Colors, typography, effects
├── util/                     # Utility functions
└── viewmodel/
    └── WorkListViewModel.kt  # Main screen ViewModel

Google Drive Backup

Google Drive backup is a core architectural feature that ensures data durability and cross-device access.

Why Google Drive?

  • User-owned storage — Data lives in the user's own Drive
  • No backend required — App is fully offline-capable
  • Familiar UX — Users already trust Google with their data
  • drive.file scope — App can only access files it creates

What Gets Backed Up

The backup file is a CSV export of all entries containing:

Field Description
userIndex User's custom ordering
title Entry title
status Reading status
score User rating (0-10)
mangaProgress Manga chapter progress
novelProgress Novel volume/chapter progress
reviewNote Personal notes
timestamps Created/updated times

When Backups Trigger

Backups are triggered by user-initiated data changes, controlled by a MutationSource allowlist:

flowchart LR
    subgraph Triggers["✅ Triggers Backup"]
        A[CREATE_MANUAL]
        B[EDIT_SAVE]
        C[DELETE_SINGLE]
        D[CREATE_IMPORT_USER_CSV]
    end
    
    subgraph NoTrigger["❌ No Backup"]
        E[DELETE_CLEAR_ALL]
        F[RESTORE_BACKUP]
        G[IMPORT_BACKUP_CSV]
    end
    
    Triggers --> Debounce[3-second debounce]
    Debounce --> Upload[Upload to Drive]
Loading

This design prevents:

  • Backup loops (restore → backup → restore)
  • Accidental backup of empty state after "Clear All"
  • Duplicate backups during bulk imports

How Restore Works

sequenceDiagram
    participant User
    participant Settings as Settings Screen
    participant BM as BackupManager
    participant Drive as Google Drive
    participant Repo as Repository

    User->>Settings: Tap "Restore from Drive"
    Settings->>BM: restoreFromDrive()
    BM->>Drive: List backup files
    Drive-->>BM: Latest backup info
    BM->>Drive: Download CSV
    BM->>BM: Parse CSV to Works
    BM->>Repo: restoreFromBackup(works)
    Note over Repo: Uses RESTORE_BACKUP source<br/>(no new backup triggered)
    Repo-->>Settings: Success count
    Settings-->>User: "Restored X entries"
Loading

Debug vs Release Considerations

Important

Google Sign-In requires SHA-1 fingerprint registration in Google Cloud Console.

Build Type SHA-1 Source Notes
Debug ~/.android/debug.keystore Auto-generated by Android Studio
Release Your signing keystore Must register separately

To get your debug SHA-1:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

OAuth Setup Checklist:

  1. Create OAuth consent screen in Google Cloud Console
  2. Add https://www.googleapis.com/auth/drive.file scope
  3. Create Android OAuth client with:
    • Package name: com.whatmanga.app
    • SHA-1 fingerprint (debug AND release)

Build & Release

Requirements

  • Android Studio Hedgehog (2023.1.1) or newer
  • JDK 17
  • Android SDK 34

Debug Build

cd android
./gradlew assembleDebug

APK location: app/build/outputs/apk/debug/app-debug.apk

Release Build

cd android
./gradlew assembleRelease

Caution

Release builds require a signing configuration. Do not commit keystores or passwords.

Signing Configuration

  1. Create a keystore (if you don't have one):

    keytool -genkey -v -keystore whatmanga-release.jks -keyalias whatmanga -keyalg RSA -keysize 2048 -validity 10000
  2. Create keystore.properties (gitignored):

    storeFile=../whatmanga-release.jks
    storePassword=your_store_password
    keyAlias=whatmanga
    keyPassword=your_key_password
  3. Reference in app/build.gradle.kts:

    signingConfigs {
        create("release") {
            // Load from keystore.properties
        }
    }

Testing & Stability

Unit Tests

The app includes unit tests for critical business logic:

cd android
./gradlew test
Test File Coverage
BackupTriggerRulesTest.kt Validates MutationSource allowlist logic
CsvBackupDetectionTest.kt Verifies backup file detection
CsvImportAntiDuplicationTest.kt Tests import deduplication
TitleNormalizerTest.kt Tests title matching normalization

Manual Verification

For pre-release verification:

  1. CRUD Operations

    • Create new entry → appears in list
    • Edit entry → changes persist after restart
    • Delete entry → removed with undo option
  2. Import/Export

    • Export CSV → valid format
    • Import CSV → no duplicates, progress-forward merge
  3. Backup/Restore

    • Sign in to Google
    • Make changes → backup triggers (check Drive)
    • Restore from Drive → data restored correctly

Performance Considerations

  • LazyColumn with key parameter for efficient recomposition
  • StateFlow.combine for derived state (avoids redundant computation)
  • Debounced backup (3-second window) to prevent API spam
  • Stable references for Compose optimizations

Screenshots

Main List

Main list screen

Filter & Sort

Filter and sort options

Entry Detail

Entry detail sheet

Settings

Settings screen

Light Mode

Light mode main screen

Screen Recordings

WhatsApp.Video.2025-12-19.at.15.29.11.mp4
202512191547.mp4

License

GPLv2 © DeguShi


About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages