Android · Projet personnel · Play Store / En développement actif

Checkd

Tracker de médias Android - livres, films, séries, anime, manga et jeux dans une seule interface. Stack Kotlin moderne, 8 APIs externes, graphiques maison en Canvas Compose, CI/CD GitHub Actions. Conçu pour une publication sur le Play Store.

📚 Livres
🎬 Films
📺 Séries
Anime
🗒 Manga
🎮 Jeux

Fonctionnalités

  • Catalogue complet - 6 types de médias, 7 statuts personnalisés (REWATCHING, ON_HOLD, LIBRARY…). Quick +1 pour progression rapide.
  • Couvertures et métadonnées auto - récupération depuis APIs externes pour chaque type
  • Import multi-sources - MAL XML, Goodreads CSV, StoryGraph CSV, sync Steam et AniList
  • Stats avancées - heatmap d'activité, streaks, distribution de notes, bar chart 12 mois en Canvas Compose natif (zéro lib graphique tierce)
  • 5 thèmes dark/light avec icône adaptative par thème via activity-alias
  • Widget homescreen Jetpack Glance
  • Notifications background via WorkManager

Solutions techniques notables

ARCH Sealed class polymorphique sérialisée dans Room +
MediaDetails est une sealed class sérialisée en JSON dans un unique champ details: String de Room. Évite toute migration de schéma à chaque nouveau type de média. Polymorphisme géré via RuntimeTypeAdapterFactory Gson — désérialisation vers le bon sous-type sans switch manuel.
UI Graphiques maison - Canvas Compose sans dépendance +
Heatmap d'activité et bar chart 12 mois entièrement dessinés en Canvas Compose. Zéro librairie graphique tierce - contrôle total du rendu, du thème et des animations. Résultat : cohérence visuelle parfaite avec le système de thèmes de l'app.
PERF Zéro flash de thème au démarrage +
Problème classique avec DataStore : le thème se charge de manière asynchrone, provoquant un flash light→dark au premier frame. Résolu via SharingStarted.Eagerly dans ThemeViewModel - le DataStore est lu avant le premier recomposition Compose, sans bloquer le thread principal.
DI Glance widget sans injection Hilt +
Les AppWidget Android ne sont pas dans le graphe de dépendances Hilt — impossible d'injecter directement. Résolu via singleton AppDatabase.getInstance(context) dans le widget, isolé du reste de l'architecture DI de l'app.
COMPOSE Smart cast impossible sur délégués Compose +
Le compilateur Kotlin refuse le smart cast sur les propriétés déléguées (comme les state de Compose) - la valeur peut changer entre la vérification et l'utilisation. Pattern documenté : capture systématique en variable locale avant tout null check ou cast. Appliqué uniformément dans le projet.

APIs intégrées

TMDB

Films · Séries

IGDB

Jeux vidéo

Twitch OAuth

AniList

Anime · Manga

GraphQL · migration Jikan

MangaDex

Manga

OpenLibrary

Livres

Steam

Jeux · Import