From 7ba34c7043a6e384fe4e2ca515a70360d0f1ca7c Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Sun, 4 Feb 2024 21:11:13 +0530 Subject: [PATCH] Implemented - multi search system --- .../cubits/fetch_search_results.dart | 86 +++++++- lib/routes_and_consts/routes.dart | 2 +- lib/screens/screen/search_screen.dart | 188 ++++++++++++------ .../screen/search_views/search_page.dart | 12 +- 4 files changed, 220 insertions(+), 68 deletions(-) diff --git a/lib/repository/cubits/fetch_search_results.dart b/lib/repository/cubits/fetch_search_results.dart index 603432d..eacf223 100644 --- a/lib/repository/cubits/fetch_search_results.dart +++ b/lib/repository/cubits/fetch_search_results.dart @@ -1,6 +1,8 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'dart:developer'; +import 'package:Bloomee/model/saavnModel.dart'; +import 'package:Bloomee/repository/Saavn/saavn_api.dart'; import 'package:bloc/bloc.dart'; import 'package:Bloomee/model/MediaPlaylistModel.dart'; @@ -12,6 +14,15 @@ import 'package:Bloomee/repository/Youtube/yt_music_api.dart'; enum LoadingState { initial, loading, loaded, noInternet } +enum SourceEngine { eng_YTM, eng_YTV, eng_JIS } + +class LastSearch { + String query; + final SourceEngine sourceEngine; + List mediaItemList = List.empty(growable: true); + LastSearch({required this.query, required this.sourceEngine}); +} + class FetchSearchResultsState extends MediaPlaylist { LoadingState loadingState = LoadingState.initial; FetchSearchResultsState( @@ -57,9 +68,82 @@ final class FetchSearchResultsLoaded extends FetchSearchResultsState { class FetchSearchResultsCubit extends Cubit { FetchSearchResultsCubit() : super(FetchSearchResultsInitial()); + + LastSearch last_YTM_search = + LastSearch(query: "", sourceEngine: SourceEngine.eng_YTM); + LastSearch last_YTV_search = + LastSearch(query: "", sourceEngine: SourceEngine.eng_YTV); + LastSearch last_JIS_search = + LastSearch(query: "", sourceEngine: SourceEngine.eng_JIS); + List _mediaItemList = List.empty(growable: true); - Future search(String query) async { + Future searchYTM(String query) async { + log("Youtube Music Search", name: "FetchSearchRes"); + + last_YTM_search.query = query; + emit(FetchSearchResultsLoading()); + final searchResults = await YtMusicService().search(query, filter: "songs"); + last_YTM_search.mediaItemList = + fromYtSongMapList2MediaItemList(searchResults[0]['items']); + emit(FetchSearchResultsState( + mediaItems: last_YTM_search.mediaItemList, + albumName: "Search", + loadingState: LoadingState.loaded)); + log("got all searches ${last_YTM_search.mediaItemList.length}", + name: "FetchSearchRes"); + } + + Future searchYTV(String query) async { + log("Youtube Video Search", name: "FetchSearchRes"); + + last_YTV_search.query = query; + emit(FetchSearchResultsLoading()); + + final searchResults = await YouTubeServices().fetchSearchResults(query); + last_YTV_search.mediaItemList = + (fromYtVidSongMapList2MediaItemList(searchResults[0]['items'])); + emit(FetchSearchResultsState( + mediaItems: last_YTV_search.mediaItemList, + albumName: "Search", + loadingState: LoadingState.loaded)); + log("got all searches ${last_YTV_search.mediaItemList.length}", + name: "FetchSearchRes"); + } + + Future searchJIS(String query) async { + emit(FetchSearchResultsLoading()); + log("JIOSaavn Search", name: "FetchSearchRes"); + final searchResults = + await SaavnAPI().fetchSongSearchResults(searchQuery: query); + last_JIS_search.mediaItemList = + fromSaavnSongMapList2MediaItemList(searchResults['songs']); + + emit(FetchSearchResultsState( + mediaItems: last_JIS_search.mediaItemList, + albumName: "Search", + loadingState: LoadingState.loaded)); + + log("got all searches ${last_JIS_search.mediaItemList.length}", + name: "FetchSearchRes"); + // log(" Results ${searchResults}", name: "FetchSearchRes"); + } + + Future search(String query, + {SourceEngine sourceEngine = SourceEngine.eng_YTM}) async { + if (sourceEngine == SourceEngine.eng_YTM) { + searchYTM(query); + } else if (sourceEngine == SourceEngine.eng_YTV) { + searchYTV(query); + } else if (sourceEngine == SourceEngine.eng_JIS) { + searchJIS(query); + } else { + log("Invalid Source Engine", name: "FetchSearchRes"); + searchYTM(query); + } + } + + Future search2(String query) async { emit(FetchSearchResultsLoading()); final searchResults = await YtMusicService().search(query, filter: "songs"); _mediaItemList = fromYtSongMapList2MediaItemList(searchResults[0]['items']); diff --git a/lib/routes_and_consts/routes.dart b/lib/routes_and_consts/routes.dart index a32723c..91c14a2 100644 --- a/lib/routes_and_consts/routes.dart +++ b/lib/routes_and_consts/routes.dart @@ -16,7 +16,7 @@ class GlobalRoutes { static final globalRouterKey = GlobalKey(); final globalRouter = GoRouter( - initialLocation: '/${GlobalStrConsts.exploreScreen}', + initialLocation: '/${GlobalStrConsts.searchScreen}', navigatorKey: globalRouterKey, routes: [ GoRoute( diff --git a/lib/screens/screen/search_screen.dart b/lib/screens/screen/search_screen.dart index 999ad5a..8563ddb 100644 --- a/lib/screens/screen/search_screen.dart +++ b/lib/screens/screen/search_screen.dart @@ -1,6 +1,7 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:Bloomee/repository/Saavn/cubit/saavn_repository_cubit.dart'; import 'package:Bloomee/repository/cubits/fetch_search_results.dart'; import 'package:Bloomee/screens/screen/search_views/search_page.dart'; import 'package:Bloomee/screens/widgets/horizontalSongCard_widget.dart'; @@ -14,6 +15,58 @@ class SearchScreen extends StatefulWidget { } class _SearchScreenState extends State { + int _selectedSearchEngine = 0; + SourceEngine _sourceEngine = SourceEngine.eng_JIS; + final TextEditingController _textEditingController = TextEditingController(); + + Widget sourceEngineRadioButton( + String text, int index, SourceEngine sourceEngine) { + return Padding( + padding: const EdgeInsets.only(right: 10), + child: SizedBox( + height: 30, + child: AnimatedContainer( + duration: const Duration(seconds: 1), + curve: accelerateEasing, + child: OutlinedButton( + onPressed: () { + setState(() { + _selectedSearchEngine = index; + _sourceEngine = sourceEngine; + if (_textEditingController.text.toString().length > 0) { + log("Search Engine ${sourceEngine.toString()}", + name: "SearchScreen"); + context.read().search( + _textEditingController.text.toString(), + sourceEngine: sourceEngine); + } + }); + }, + style: OutlinedButton.styleFrom( + backgroundColor: _selectedSearchEngine == index + ? Default_Theme.accentColor2 + : Colors.transparent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20)), + side: const BorderSide( + color: Default_Theme.accentColor2, + style: BorderStyle.solid, + width: 2)), + child: Text( + text, + style: TextStyle( + color: _selectedSearchEngine == index + ? Default_Theme.primaryColor2 + : Default_Theme.accentColor2, + fontSize: 15) + .merge(Default_Theme.secondoryTextStyleMedium), + ), + ), + ), + ), + ); + } + @override Widget build(BuildContext context) { return GestureDetector( @@ -22,7 +75,70 @@ class _SearchScreenState extends State { FocusManager.instance.primaryFocus?.unfocus(), child: Scaffold( appBar: AppBar( - title: SizedBox(height: 50.0, child: SearchBoxWidget()), + shadowColor: Colors.black, + bottom: PreferredSize( + preferredSize: const Size(100, 20), + child: SizedBox( + height: 35, + width: MediaQuery.of(context).size.width, + child: Padding( + padding: const EdgeInsets.only( + left: 18, right: 18, top: 5, bottom: 5), + child: Row( + children: [ + sourceEngineRadioButton("JIS", 0, SourceEngine.eng_JIS), + sourceEngineRadioButton("YTM", 1, SourceEngine.eng_YTM), + sourceEngineRadioButton("YTV", 2, SourceEngine.eng_YTV), + // const Spacer() + ], + ), + ), + ), + ), + title: SizedBox( + height: 50.0, + child: InkWell( + onTap: () { + showSearch( + context: context, + delegate: searchPageDelegate(_sourceEngine), + query: _textEditingController.text) + .then((value) { + if ((value as String) != 'null') { + _textEditingController.text = value.toString(); + } + }); + }, + child: TextField( + controller: _textEditingController, + enabled: false, + textAlign: TextAlign.center, + style: TextStyle( + color: Default_Theme.primaryColor1.withOpacity(0.55)), + textInputAction: TextInputAction.search, + decoration: InputDecoration( + filled: true, + suffixIcon: Icon( + Icons.search, + color: Default_Theme.primaryColor1.withOpacity(0.4), + ), + fillColor: Default_Theme.primaryColor2.withOpacity(0.07), + contentPadding: const EdgeInsets.only(top: 20), + hintText: "Find your next song obsession...", + hintStyle: TextStyle( + color: Default_Theme.primaryColor1.withOpacity(0.4), + fontFamily: "Gilroy"), + disabledBorder: OutlineInputBorder( + borderSide: const BorderSide(style: BorderStyle.none), + borderRadius: BorderRadius.circular(50)), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: + Default_Theme.primaryColor1.withOpacity(0.7)), + borderRadius: BorderRadius.circular(50))), + ), + ), + ), backgroundColor: Default_Theme.themeColor, ), backgroundColor: Default_Theme.themeColor, @@ -45,16 +161,13 @@ class _SearchScreenState extends State { return ListView.builder( itemCount: state.mediaItems.length, itemBuilder: (context, index) { - return InkWell( - onTap: () {}, - child: Padding( - padding: - const EdgeInsets.only(left: 18, bottom: 5, right: 18), - child: HorizontalSongCardWidget( - index: index, - mediaPlaylist: state, - showLiked: true, - ), + return Padding( + padding: + const EdgeInsets.only(left: 18, bottom: 5, right: 18), + child: HorizontalSongCardWidget( + index: index, + mediaPlaylist: state, + showLiked: true, ), ); }, @@ -92,54 +205,3 @@ class _SearchScreenState extends State { ); } } - -class SearchBoxWidget extends StatelessWidget { - SearchBoxWidget({ - super.key, - }); - final TextEditingController _textEditingController = TextEditingController(); - // final _focusNode = FocusNode(); - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: () { - showSearch( - context: context, - delegate: searchPageDelegate(), - query: _textEditingController.text) - .then((value) { - if ((value as String) != 'null') { - _textEditingController.text = value.toString(); - } - }); - }, - child: TextField( - controller: _textEditingController, - enabled: false, - textAlign: TextAlign.center, - style: TextStyle(color: Default_Theme.primaryColor1.withOpacity(0.55)), - textInputAction: TextInputAction.search, - decoration: InputDecoration( - filled: true, - suffixIcon: Icon( - Icons.search, - color: Default_Theme.primaryColor1.withOpacity(0.4), - ), - fillColor: Default_Theme.primaryColor2.withOpacity(0.07), - contentPadding: const EdgeInsets.only(top: 20), - hintText: "What you want to listen?", - hintStyle: TextStyle( - color: Default_Theme.primaryColor1.withOpacity(0.4), - fontFamily: "Gilroy"), - disabledBorder: OutlineInputBorder( - borderSide: const BorderSide(style: BorderStyle.none), - borderRadius: BorderRadius.circular(50)), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: Default_Theme.primaryColor1.withOpacity(0.7)), - borderRadius: BorderRadius.circular(50))), - ), - ); - } -} diff --git a/lib/screens/screen/search_views/search_page.dart b/lib/screens/screen/search_views/search_page.dart index 6882023..c196d9d 100644 --- a/lib/screens/screen/search_views/search_page.dart +++ b/lib/screens/screen/search_views/search_page.dart @@ -1,14 +1,18 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; + import 'package:Bloomee/repository/Youtube/youtube_api.dart'; import 'package:Bloomee/repository/cubits/fetch_search_results.dart'; import 'package:Bloomee/theme_data/default.dart'; class searchPageDelegate extends SearchDelegate { List searchList = []; - + SourceEngine _sourceEngine = SourceEngine.eng_YTM; + searchPageDelegate( + this._sourceEngine, + ); @override - // TODO: implement searchFieldLabel String? get searchFieldLabel => "What you want to listen?"; @override @@ -40,7 +44,9 @@ class searchPageDelegate extends SearchDelegate { @override void showResults(BuildContext context) { if (query.isNotEmpty) { - context.read().search(query); + context + .read() + .search(query, sourceEngine: _sourceEngine); } close(context, query); }