π App Introduction: Movie information and recommendation app using TMDB API
π Duration: May 13, 2025 ~ May 15, 2025 (3 days)
π± Platform: Flutter cross-platform app (iOS, Android)
π₯ Team Size: 1 developer (solo project)
πΌ Role: Entire app design and development, API integration, performance optimization
π οΈ Key Technologies: Flutter
Dart
TMDB API
Riverpod
Clean Architecture
Dio
GitHub Actions
Hero Animation
Shimmer
π GitHub: daehan-lim/flutter-film-mind-app
FilmMind is a Flutter mobile app that displays movie information across multiple categories including now playing, popular movies, top-rated films, and upcoming releases using the TMDB API. The app uses Clean Architecture with MVVM pattern, features smooth Hero Animations between screens, and includes Google/Naver search integration for additional movie details.
βββ app/ # App-wide settings, constants, and themes
β βββ constants/ # App constant definitions
β β βββ app_colors.dart # Color constants
β β βββ app_constants.dart # General app constants
β β βββ app_styles.dart # Style definitions
β βββ theme.dart # App theme configuration
βββ core/ # Core functionality and utilities
β βββ exceptions/ # App-wide exception classes
β β βββ data_exceptions.dart # Data-related exception classes
β βββ extensions/ # Extension method definitions
β β βββ date_extensions.dart # Date-related extension methods
β β βββ number_extensions.dart # Number-related extension methods
β βββ providers/ # Common providers
β β βββ repository_providers.dart # Repository providers
β βββ utils/ # Utility functions
β βββ navigation_util.dart # Navigation utilities
β βββ snackbar_util.dart # Snackbar utilities
β βββ dialogue_util.dart # Dialog utilities
βββ data/ # Data layer and data access
β βββ data_source/ # Data source classes
β βββ dto/ # Data Transfer Objects
β βββ repository/ # Repository implementations
βββ domain/ # Business logic and entities
β βββ entity/ # Domain entities
β βββ repository/ # Repository interfaces
β βββ usecase/ # Use cases
βββ presentation/ # UI layer
β βββ pages/ # App screens
β β βββ home/ # Home screen
β β β βββ home_page.dart # Home page widget
β β β βββ home_view_model.dart # Home screen view model
β β β βββ widgets/ # Home screen widgets
β β βββ detail/ # Detail screen
β βββ widgets/ # Common widgets
βββ main.dart # App entry point
Domain
, Data
, and Presentation
layers with clear boundariesRiverpod
and implemented Provider
-based dependency injectionMVVM
pattern for clear separation of UI and business logicRepository
pattern and UseCase
layer to encapsulate business logicDio
HTTP client with Bearer Token
authentication for secure API callsExtensions
Hero Animation
with unique tags per category for smooth poster-to-detail transitionsHero
tag matchingCachedNetworkImage
Shimmer
loading animationsTransform.translate
ListView
and category-specific layouts for efficient space usageDataSource
to ViewModel
, ensuring business logic stabilityMocktail
for dependency mocking and Provider
overrides, eliminating external API dependenciesPull Request
and Push
events, reducing manual review timeExtension
methodsEntity
and DTO
layers1. Hero Animation Tag Duplication Conflict
Problem
Multiple movies appeared in different categories, causing Hero
animation conflicts with the error: There are multiple heroes that share the same tag within a subtree
.
Hero
tags based only on movie ID using format 'movie-image-${movie.id}'
Hero
tags on the same screenHero
tags within a screen must be unique'movie-image-${movie.id}-$categoryName'
Hero
tag regardless of category overlap// Updated Hero tag generation
Hero(
tag: 'movie-image-${movie.id}-$categoryName',
child: AppCachedImage(imageUrl: movie.getPosterUrl()),
)
2. TMDB API Key Security Management in GitHub Actions
Problem
The CI pipeline required TMDB Bearer Token
for successful builds, but the token couldnβt be hardcoded in the repository for security reasons, causing build failures due to missing environment variables.
flutter_dotenv
package requires a .env
file at runtimeGitHub Secrets
TMDB_BEARER_TOKEN
as a Secret in GitHub repository settingsGitHub Actions
workflow to inject the secret as an environment variable and dynamically create the .env
file during builds- name: Create .env file
run: |
echo "TMDB_BEARER_TOKEN=$" > .env
- name: Install dependencies
run: flutter pub get
- name: Run tests
run: flutter test