Skip to content

Commit 746fd0b

Browse files
authored
Merge pull request #4 from piashcse/feature-movie-detail
Implemented movie detail page with dynamic data
2 parents 9988383 + 8122094 commit 746fd0b

File tree

13 files changed

+475
-270
lines changed

13 files changed

+475
-270
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@ app.*.map.json
4343
/android/app/debug
4444
/android/app/profile
4545
/android/app/release
46+
47+
# Freezed and JSON Serializable generated files
48+
*.freezed.dart
49+
*.g.dart

lib/features/movie/data/datasources/movie_remote_data_source.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:dio/dio.dart';
2+
import 'package:flutter_movie_clean_architecture/features/movie/data/models/movie_detail_model.dart';
23
import 'package:flutter_movie_clean_architecture/features/movie/data/models/movie_model.dart';
34

45
class MovieRemoteDataSource {
@@ -30,4 +31,13 @@ class MovieRemoteDataSource {
3031
.map((e) => MovieModel.fromJson(e))
3132
.toList();
3233
}
34+
35+
Future<MovieDetailModel> getMovieDetail(int id) async {
36+
final response = await dio.get('/movie/$id');
37+
if (response.statusCode == 200 && response.data != null && response.data is Map<String, dynamic>) {
38+
return MovieDetailModel.fromJson(response.data as Map<String, dynamic>);
39+
} else {
40+
throw Exception('Failed to load movie detail: Invalid response');
41+
}
42+
}
3343
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
3+
part 'movie_detail_model.freezed.dart';
4+
part 'movie_detail_model.g.dart';
5+
6+
@freezed
7+
class MovieDetailModel with _$MovieDetailModel {
8+
const factory MovieDetailModel({
9+
required int id,
10+
required String title,
11+
required String overview,
12+
@JsonKey(name: 'poster_path') required String posterPath,
13+
@JsonKey(name: 'release_date') required String releaseDate,
14+
@JsonKey(name: 'vote_average') required double voteAverage,
15+
required int runtime,
16+
@JsonKey(name: 'original_language') String? originalLanguage,
17+
List<Genre>? genres,
18+
@JsonKey(name: 'production_companies') List<ProductionCompany>? productionCompanies,
19+
}) = _MovieDetailModel;
20+
21+
factory MovieDetailModel.fromJson(Map<String, dynamic> json) =>
22+
_$MovieDetailModelFromJson(json);
23+
}
24+
25+
@freezed
26+
class Genre with _$Genre {
27+
const factory Genre({
28+
required int id,
29+
required String? name,
30+
}) = _Genre;
31+
32+
factory Genre.fromJson(Map<String, dynamic> json) => _$GenreFromJson(json);
33+
}
34+
35+
@freezed
36+
class ProductionCompany with _$ProductionCompany {
37+
const factory ProductionCompany({
38+
required int id,
39+
String? name,
40+
@JsonKey(name: 'logo_path') String? logoPath,
41+
}) = _ProductionCompany;
42+
43+
factory ProductionCompany.fromJson(Map<String, dynamic> json) =>
44+
_$ProductionCompanyFromJson(json);
45+
}

lib/features/movie/data/models/movie_model.freezed.dart

Lines changed: 0 additions & 236 deletions
This file was deleted.

lib/features/movie/data/models/movie_model.g.dart

Lines changed: 0 additions & 23 deletions
This file was deleted.

lib/features/movie/data/repositories/movie_repository_impl.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:flutter_movie_clean_architecture/features/movie/data/datasources/movie_remote_data_source.dart';
22
import 'package:flutter_movie_clean_architecture/features/movie/domain/entities/movie.dart';
3+
import 'package:flutter_movie_clean_architecture/features/movie/domain/entities/movie_detail.dart';
34
import 'package:flutter_movie_clean_architecture/features/movie/domain/repositories/entities/movie_repository.dart';
45

56
class MovieRepositoryImpl implements MovieRepository {
@@ -58,4 +59,22 @@ class MovieRepositoryImpl implements MovieRepository {
5859
))
5960
.toList();
6061
}
62+
63+
@override
64+
Future<MovieDetail> getMovieDetail(int movieId) async {
65+
final model = await remoteDataSource.getMovieDetail(movieId);
66+
67+
return MovieDetail(
68+
id: model.id,
69+
title: model.title,
70+
overview: model.overview,
71+
posterPath: model.posterPath ?? "",
72+
releaseDate: model.releaseDate ?? "",
73+
voteAverage: model.voteAverage ?? 0,
74+
runtime: model.runtime ?? 0,
75+
originalLanguage: model.originalLanguage ?? "N/A",
76+
genres: model.genres?.map((genre) => genre.name ?? "").toList() ?? [],
77+
productionCompanies: model.productionCompanies?.map((company) => company.name ?? "").toList() ?? [],
78+
);
79+
}
6180
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class MovieDetail {
2+
final int id;
3+
final String title;
4+
final String overview;
5+
final String posterPath;
6+
final String releaseDate;
7+
final double voteAverage;
8+
final int runtime;
9+
final String originalLanguage;
10+
final List<String> genres;
11+
final List<String> productionCompanies;
12+
13+
MovieDetail({
14+
required this.id,
15+
required this.title,
16+
required this.overview,
17+
required this.posterPath,
18+
required this.releaseDate,
19+
required this.voteAverage,
20+
required this.runtime,
21+
required this.originalLanguage,
22+
required this.genres,
23+
required this.productionCompanies,
24+
});
25+
}

0 commit comments

Comments
 (0)