Skip to content

Commit

Permalink
Merge pull request #14 from jdk-21/development
Browse files Browse the repository at this point in the history
feat: add search screen
  • Loading branch information
jdk-21 authored Dec 21, 2023
2 parents 896e970 + 0ebfd8a commit fce7640
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 12 deletions.
8 changes: 7 additions & 1 deletion lib/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:jellyflix/screens/library_screen.dart';
import 'package:jellyflix/screens/profile_screen.dart';
import 'package:jellyflix/screens/search_screen.dart';

class HomeScreen extends HookConsumerWidget {
const HomeScreen({super.key});
Expand All @@ -24,7 +25,12 @@ class HomeScreen extends HookConsumerWidget {
icon: const Icon(Icons.video_library_outlined),
),
actions: [
IconButton(onPressed: () {}, icon: const Icon(Icons.search_rounded)),
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const SearchScreen()));
},
icon: const Icon(Icons.search_rounded)),
IconButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
Expand Down
2 changes: 1 addition & 1 deletion lib/screens/library_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LibraryScreen extends HookConsumerWidget {
);
},
child: Text(
"Genre: ${genreFilter.value!.map(
"Genre: ${genreFilter.value == null ? "All" : genreFilter.value!.map(
(e) => e.name,
).isEmpty ? "All" : genreFilter.value!.map(
(e) => e.name,
Expand Down
157 changes: 157 additions & 0 deletions lib/screens/search_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:jellyflix/components/item_carousel.dart';
import 'package:jellyflix/models/poster_type.dart';
import 'package:jellyflix/providers/api_provider.dart';
import 'package:jellyflix/screens/detail_screen.dart';
import 'package:openapi/openapi.dart';

class SearchScreen extends HookConsumerWidget {
const SearchScreen({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final searchQuery = useState<String?>(null);

return Scaffold(
appBar: AppBar(
title: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
width: double.infinity,
height: 40,
child: SearchBar(
hintText: "Search",
leading: const Icon(Icons.search_rounded),
onChanged: (value) {
if (value != "") {
searchQuery.value = value;
} else {
searchQuery.value = null;
}
},
),
)),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 20.0),
child: (searchQuery.value ?? "").isEmpty
? const Center(child: Text("Start typing to search"))
: SingleChildScrollView(
child: FutureBuilder(
future: ref
.read(apiProvider)
.getFilterItems(searchTerm: searchQuery.value),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.isEmpty) {
return const Center(child: Text("No results found"));
}
List<BaseItemDto> movieList = snapshot.data!
.where(
(element) => element.type == BaseItemKind.movie)
.toList();
List<BaseItemDto> seriesList = snapshot.data!
.where(
(element) => element.type == BaseItemKind.series)
.toList();
List<BaseItemDto> episodeList = snapshot.data!
.where(
(element) => element.type == BaseItemKind.episode)
.toList();
List<BaseItemDto> collectionList = snapshot.data!
.where(
(element) => element.type == BaseItemKind.boxSet)
.toList();
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
movieList.isEmpty
? const SizedBox()
: ItemCarousel(
imageList: movieList.map((e) {
return e.id!;
}).toList(),
titleList: movieList.map((e) {
return e.name!;
}).toList(),
onTap: (index) {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => DetailScreen(
itemId: movieList[index].id!,
)));
},
title: "Movies",
),
seriesList.isEmpty
? const SizedBox()
: ItemCarousel(
imageList: seriesList.map((e) {
return e.id!;
}).toList(),
titleList: seriesList.map((e) {
return e.name!;
}).toList(),
onTap: (index) {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => DetailScreen(
itemId: seriesList[index].id!,
)));
},
title: "Series",
),
episodeList.isEmpty
? const SizedBox()
: ItemCarousel(
posterType: PosterType.horizontal,
imageList: episodeList.map((e) {
return e.id!;
}).toList(),
titleList: episodeList.map((e) {
return e.name!;
}).toList(),
onTap: (index) {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => DetailScreen(
itemId:
episodeList[index].id!,
)));
},
title: "Episodes",
),
collectionList.isEmpty
? const SizedBox()
: ItemCarousel(
imageList: collectionList.map((e) {
return e.id!;
}).toList(),
titleList: collectionList.map((e) {
return e.name!;
}).toList(),
onTap: (index) {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (context) => DetailScreen(
itemId:
collectionList[index].id!,
)));
},
title: "Collections",
),
],
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),
),
),
);
}
}
24 changes: 14 additions & 10 deletions lib/services/api_service.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import 'package:jellyflix/models/sort_type.dart';
import 'package:jellyflix/models/user.dart';
import 'package:flutter/material.dart';
import 'package:jellyflix/screens/filter_type.dart';
import 'package:jellyflix/screens/library_screen.dart';
import 'package:openapi/openapi.dart';
import 'package:built_collection/built_collection.dart';

Expand Down Expand Up @@ -120,20 +117,27 @@ class ApiService {
}

Future<List<BaseItemDto>> getFilterItems(
{List<BaseItemDto>? genreIds,
List<FilterType>? filters,
SortType? sortType}) async {
{List<BaseItemDto>? genreIds, String? searchTerm}) async {
var folders = await getMediaFolders();
var ids = genreIds == null
? null
: BuiltList<String>.from(genreIds.map((e) => e.id!));
List<BaseItemDto> items = [];
for (var folder in folders) {
var response = await _jellyfinApi!.getItemsApi().getItems(
userId: _user!.id!,
headers: headers,
parentId: folder.id,
genreIds: ids);
userId: _user!.id!,
headers: headers,
parentId: folder.id,
genreIds: ids,
searchTerm: searchTerm,
recursive: true,
includeItemTypes: BuiltList<BaseItemKind>([
BaseItemKind.movie,
BaseItemKind.series,
BaseItemKind.episode,
BaseItemKind.boxSet
]),
);
items.addAll(response.data!.items!);
}
return items;
Expand Down

0 comments on commit fce7640

Please sign in to comment.