Skip to content

Commit 569b92f

Browse files
committed
- Integrated celebrity feature
- Added celebrity search functionality - Updated universal search to include celebrities - Removed old movie search widget
1 parent fe6f6da commit 569b92f

File tree

18 files changed

+689
-209
lines changed

18 files changed

+689
-209
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import 'package:dio/dio.dart';
2+
import 'package:flutter_riverpod/flutter_riverpod.dart';
3+
import 'package:flutter_movie_clean_architecture/core/network/dio_provider.dart';
4+
import 'package:flutter_movie_clean_architecture/features/celebrity/data/models/person_list_response.dart';
5+
6+
abstract class CelebrityRemoteDataSource {
7+
Future<PersonListResponse> getPopularPersons(int page);
8+
Future<PersonListResponse> getTrendingPersons(int page);
9+
Future<PersonListResponse> searchPersons(String query, int page);
10+
}
11+
12+
class CelebrityRemoteDataSourceImpl implements CelebrityRemoteDataSource {
13+
final Dio dio;
14+
15+
CelebrityRemoteDataSourceImpl(this.dio);
16+
17+
@override
18+
Future<PersonListResponse> getPopularPersons(int page) async {
19+
final response = await dio.get(
20+
'person/popular',
21+
queryParameters: {'page': page},
22+
);
23+
return PersonListResponse.fromJson(response.data as Map<String, dynamic>);
24+
}
25+
26+
@override
27+
Future<PersonListResponse> getTrendingPersons(int page) async {
28+
final response = await dio.get(
29+
'trending/person/week',
30+
queryParameters: {'page': page},
31+
);
32+
return PersonListResponse.fromJson(response.data as Map<String, dynamic>);
33+
}
34+
35+
@override
36+
Future<PersonListResponse> searchPersons(String query, int page) async {
37+
final response = await dio.get(
38+
'search/person',
39+
queryParameters: {
40+
'query': query,
41+
'page': page,
42+
},
43+
);
44+
return PersonListResponse.fromJson(response.data as Map<String, dynamic>);
45+
}
46+
}
47+
48+
final celebrityRemoteDataSourceProvider = Provider<CelebrityRemoteDataSource>((ref) {
49+
final dio = ref.watch(dioProvider);
50+
return CelebrityRemoteDataSourceImpl(dio);
51+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/data/models/person_model.dart';
3+
4+
part 'person_list_response.freezed.dart';
5+
part 'person_list_response.g.dart';
6+
7+
@freezed
8+
class PersonListResponse with _$PersonListResponse {
9+
const factory PersonListResponse({
10+
@JsonKey(name: 'page') required int page,
11+
@JsonKey(name: 'results') required List<PersonModel> results,
12+
@JsonKey(name: 'total_pages') required int totalPages,
13+
@JsonKey(name: 'total_results') required int totalResults,
14+
}) = _PersonListResponse;
15+
16+
factory PersonListResponse.fromJson(Map<String, dynamic> json) =>
17+
_$PersonListResponseFromJson(json);
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'package:freezed_annotation/freezed_annotation.dart';
2+
3+
part 'person_model.freezed.dart';
4+
part 'person_model.g.dart';
5+
6+
@freezed
7+
class PersonModel with _$PersonModel {
8+
const factory PersonModel({
9+
required bool adult,
10+
@JsonKey(name: 'gender') required int gender,
11+
@JsonKey(name: 'id') required int id,
12+
@JsonKey(name: 'known_for_department') required String knownForDepartment,
13+
@JsonKey(name: 'name') required String name,
14+
@JsonKey(name: 'popularity') required double popularity,
15+
@JsonKey(name: 'profile_path') String? profilePath,
16+
}) = _PersonModel;
17+
18+
factory PersonModel.fromJson(Map<String, dynamic> json) =>
19+
_$PersonModelFromJson(json);
20+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'package:flutter_movie_clean_architecture/features/celebrity/data/datasources/celebrity_remote_data_source.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/data/models/person_model.dart';
3+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/entities/person.dart';
4+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/repositories/celebrity_repository.dart';
5+
6+
class CelebrityRepositoryImpl implements CelebrityRepository {
7+
final CelebrityRemoteDataSource remoteDataSource;
8+
9+
CelebrityRepositoryImpl(this.remoteDataSource);
10+
11+
@override
12+
Future<List<Person>> getPopularPersons(int page) async {
13+
final models = await remoteDataSource.getPopularPersons(page);
14+
return _mapToEntities(models.results);
15+
}
16+
17+
@override
18+
Future<List<Person>> getTrendingPersons(int page) async {
19+
final models = await remoteDataSource.getTrendingPersons(page);
20+
return _mapToEntities(models.results);
21+
}
22+
23+
@override
24+
Future<List<Person>> searchPersons(String query, int page) async {
25+
final models = await remoteDataSource.searchPersons(query, page);
26+
return _mapToEntities(models.results);
27+
}
28+
29+
List<Person> _mapToEntities(List<PersonModel> models) {
30+
return models
31+
.map((model) => Person(
32+
id: model.id,
33+
name: model.name,
34+
profilePath: model.profilePath,
35+
knownForDepartment: model.knownForDepartment,
36+
popularity: model.popularity,
37+
))
38+
.toList();
39+
}
40+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Person {
2+
final int id;
3+
final String name;
4+
final String? profilePath;
5+
final String knownForDepartment;
6+
final double popularity;
7+
8+
Person({
9+
required this.id,
10+
required this.name,
11+
required this.profilePath,
12+
required this.knownForDepartment,
13+
required this.popularity,
14+
});
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/entities/person.dart';
2+
3+
abstract class CelebrityRepository {
4+
Future<List<Person>> getPopularPersons(int page);
5+
Future<List<Person>> getTrendingPersons(int page);
6+
Future<List<Person>> searchPersons(String query, int page);
7+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/entities/person.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/repositories/celebrity_repository.dart';
3+
4+
class GetPopularPersons {
5+
final CelebrityRepository repository;
6+
7+
GetPopularPersons(this.repository);
8+
9+
Future<List<Person>> call(int page) async {
10+
return await repository.getPopularPersons(page);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/entities/person.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/repositories/celebrity_repository.dart';
3+
4+
class GetTrendingPersons {
5+
final CelebrityRepository repository;
6+
7+
GetTrendingPersons(this.repository);
8+
9+
Future<List<Person>> call(int page) async {
10+
return await repository.getTrendingPersons(page);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/entities/person.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/domain/repositories/celebrity_repository.dart';
3+
4+
class SearchPersons {
5+
final CelebrityRepository repository;
6+
7+
SearchPersons(this.repository);
8+
9+
Future<List<Person>> call(String query, int page) async {
10+
return await repository.searchPersons(query, page);
11+
}
12+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_movie_clean_architecture/features/celebrity/presentation/pages/popular_persons_page.dart';
3+
import 'package:flutter_movie_clean_architecture/features/celebrity/presentation/pages/trending_persons_page.dart';
4+
import 'package:flutter_riverpod/flutter_riverpod.dart';
5+
6+
class CelebrityMainPage extends ConsumerStatefulWidget {
7+
const CelebrityMainPage({super.key});
8+
9+
@override
10+
ConsumerState<CelebrityMainPage> createState() => _CelebrityMainPageState();
11+
}
12+
13+
class _CelebrityMainPageState extends ConsumerState<CelebrityMainPage> {
14+
int _selectedIndex = 0;
15+
16+
final _pages = [
17+
const PopularPersonsPage(),
18+
const TrendingPersonsPage(),
19+
];
20+
21+
void _onItemTapped(int index) {
22+
setState(() {
23+
_selectedIndex = index;
24+
});
25+
}
26+
27+
@override
28+
Widget build(BuildContext context) {
29+
return Scaffold(
30+
body: _pages[_selectedIndex],
31+
bottomNavigationBar: BottomNavigationBar(
32+
currentIndex: _selectedIndex,
33+
onTap: _onItemTapped,
34+
type: BottomNavigationBarType.fixed,
35+
items: const [
36+
BottomNavigationBarItem(
37+
icon: Icon(Icons.favorite),
38+
label: 'Popular',
39+
),
40+
BottomNavigationBarItem(
41+
icon: Icon(Icons.trending_up),
42+
label: 'Trending',
43+
),
44+
],
45+
),
46+
);
47+
}
48+
}

0 commit comments

Comments
 (0)