From ce184b52ca5933607145142f0836e13cb8e61995 Mon Sep 17 00:00:00 2001 From: Erfan Rahmati Date: Fri, 5 Aug 2022 11:16:04 +0430 Subject: [PATCH] Add handler script for the IMDb API limit error --- lib/models/external_sites_model.dart | 57 +++++++++ lib/modules/{ => api}/api_requester.dart | 111 +++++++++++------ lib/modules/get_show_info.dart | 2 +- .../actor/actor_page/get_actor_info.dart | 2 +- .../home/sections/box_office/box_office.dart | 2 +- .../home/sections/companies/get_company.dart | 2 +- .../main/home/sections/imdb_lists/lists.dart | 2 +- lib/pages/main/main_controller.dart | 8 ++ lib/pages/main/search/search.dart | 2 +- .../main/search/search_bar/voice_search.dart | 2 +- .../sections/bottom_bar/bottom_bar.dart | 18 +-- .../external_sites/external_sites.dart | 115 ++++++++++++++++-- .../sections/lists_info/lists_info.dart | 12 +- .../episode_guide/episode_guide_page.dart | 2 +- lib/pages/show/show_page/show_page.dart | 13 +- lib/pages/splash/get_Initial_data.dart | 2 +- test/modules_test/api_requester_test.dart | 2 +- 17 files changed, 270 insertions(+), 84 deletions(-) create mode 100644 lib/models/external_sites_model.dart rename lib/modules/{ => api}/api_requester.dart (66%) diff --git a/lib/models/external_sites_model.dart b/lib/models/external_sites_model.dart new file mode 100644 index 0000000..430e2c9 --- /dev/null +++ b/lib/models/external_sites_model.dart @@ -0,0 +1,57 @@ +// Movie or TV show as result of a search model class +class ExternalSites { + final String officialWebsite; + final String imDb; + final String theMovieDb; + final String rottenTomatoes; + final String metacritic; + final String netflix; + final String googlePlay; + final String filmAffinity; + final String freebase; + final String wikipedia; + + const ExternalSites({ + required this.officialWebsite, + required this.imDb, + required this.theMovieDb, + required this.rottenTomatoes, + required this.metacritic, + required this.netflix, + required this.googlePlay, + required this.filmAffinity, + required this.freebase, + required this.wikipedia, + }); + + factory ExternalSites.fromJson(Map json) { + return ExternalSites( + officialWebsite: json['officialWebsite'] ?? '', + imDb: json['imDb']?['url'] ?? '', + theMovieDb: json['theMovieDb']?['url'] ?? '', + rottenTomatoes: json['rottenTomatoes']?['url'] ?? '', + metacritic: json['metacritic']?['url'] ?? '', + netflix: json['netflix']?['url'] ?? '', + googlePlay: json['googlePlay']?['url'] ?? '', + filmAffinity: json['filmAffinity']?['url'] ?? '', + freebase: json['freebase']?['url'] ?? '', + wikipedia: json['wikipediaUrls']?[0]?['url'] ?? '', + ); + } +} + +List> externalSitesList = [ + {'title': "HomePage", 'imgUrl': ""}, + {'title': "IMDb", 'imgUrl': "assets/images/logos/IMDb.png"}, + {'title': "TMDb", 'imgUrl': "assets/images/logos/TMDb.png"}, + { + 'title': "Rotten Tomatoes", + 'imgUrl': "assets/images/logos/RottenTomatoes.png" + }, + {'title': "Metacritic", 'imgUrl': "assets/images/logos/Metacritic.png"}, + {'title': "Netflix", 'imgUrl': "assets/images/logos/Netflix.png"}, + {'title': "Google Play", 'imgUrl': "assets/images/logos/GooglePlay.png"}, + {'title': "Film Affinity", 'imgUrl': "assets/images/logos/FilmAffinity.png"}, + {'title': "Freebase", 'imgUrl': "assets/images/logos/Freebase.png"}, + {'title': "Wikipedia", 'imgUrl': "assets/images/logos/Wikipedia.png"}, +]; diff --git a/lib/modules/api_requester.dart b/lib/modules/api/api_requester.dart similarity index 66% rename from lib/modules/api_requester.dart rename to lib/modules/api/api_requester.dart index 2b27253..7740f8f 100644 --- a/lib/modules/api_requester.dart +++ b/lib/modules/api/api_requester.dart @@ -3,30 +3,26 @@ import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:http/http.dart' as http; import 'package:movielab/constants/types.dart'; +import 'package:movielab/models/external_sites_model.dart'; import 'package:movielab/modules/cache/cacheholder.dart'; import 'package:movielab/pages/main/home/home_data_controller.dart'; import 'package:movielab/pages/main/search/search_bar/search_bar_controller.dart'; -import '../models/actor_models/full_actor_model.dart'; -import '../models/episode_model.dart'; -import '../models/search_result_model.dart'; -import '../models/show_models/full_show_model.dart'; -import '../models/show_models/show_preview_model.dart'; +import '../../models/actor_models/full_actor_model.dart'; +import '../../models/episode_model.dart'; +import '../../models/search_result_model.dart'; +import '../../models/show_models/full_show_model.dart'; +import '../../models/show_models/show_preview_model.dart'; class APIRequester { static const String imdbBaseUrl = 'https://imdb-api.com/en/API'; // API keys to access the IMDB API: - static const String apiKey = "k_6lgd4s89"; - // static const String apiKey = "k_y9zcdoq3"; - // static const String apiKey = ""; + static const List apiKey = ["k_zld7q6q3", "k_y9zcdoq3", "k_6lgd4s89"]; + static int activeApiKey = 0; // Get recently trending movies from the IMDB API Future getTrendingMovies() async { - final response = await http - .get(Uri.parse('$imdbBaseUrl/MostPopularMovies/$apiKey')) - .timeout( - const Duration(seconds: 10), - ); - + final response = await getUrl( + url: '$imdbBaseUrl/MostPopularMovies/${apiKey[activeApiKey]}'); if (response.statusCode == 200) { if (jsonDecode(response.body)["errorMessage"] != "") { return RequestResult.FAILURE_SERVER_PROBLEM; @@ -46,9 +42,8 @@ class APIRequester { // Get recently trending TV shows from the IMDB API Future getTrendingTVShows() async { - final response = await http - .get(Uri.parse('$imdbBaseUrl/MostPopularTVs/$apiKey')) - .timeout(const Duration(seconds: 10)); + final response = await getUrl( + url: '$imdbBaseUrl/MostPopularTVs/${apiKey[activeApiKey]}'); if (response.statusCode == 200) { if (jsonDecode(response.body)["errorMessage"] != "") { @@ -74,24 +69,20 @@ class APIRequester { http.Response response; switch (listName) { case ImdbList.TOP_250_MOVIES: - response = await http - .get(Uri.parse('$imdbBaseUrl/Top250Movies/$apiKey')) - .timeout(const Duration(seconds: 10)); + response = await getUrl( + url: '$imdbBaseUrl/Top250Movies/${apiKey[activeApiKey]}'); break; case ImdbList.TOP_250_TVS: - response = await http - .get(Uri.parse('$imdbBaseUrl/Top250TVs/$apiKey')) - .timeout(const Duration(seconds: 10)); + response = + await getUrl(url: '$imdbBaseUrl/Top250TVs/${apiKey[activeApiKey]}'); break; case ImdbList.BoxOffice: - response = await http - .get(Uri.parse('$imdbBaseUrl/BoxOffice/$apiKey')) - .timeout(const Duration(seconds: 10)); + response = + await getUrl(url: '$imdbBaseUrl/BoxOffice/${apiKey[activeApiKey]}'); break; case ImdbList.AllTimeBoxOffice: - response = await http - .get(Uri.parse('$imdbBaseUrl/BoxOfficeAllTime/$apiKey')) - .timeout(const Duration(seconds: 10)); + response = await getUrl( + url: '$imdbBaseUrl/BoxOfficeAllTime/${apiKey[activeApiKey]}'); break; } if (response.statusCode == 200) { @@ -123,9 +114,8 @@ class APIRequester { // Get a company's movies from the IMDB API Future getCompany({required String id}) async { - final response = await http - .get(Uri.parse('$imdbBaseUrl/Company/$apiKey/$id')) - .timeout(const Duration(seconds: 10)); + final response = + await getUrl(url: '$imdbBaseUrl/Company/${apiKey[activeApiKey]}/$id'); if (response.statusCode == 200) { var json = jsonDecode(response.body)["items"]; List companyMovies = []; @@ -144,8 +134,8 @@ class APIRequester { // Get results of a search query from the IMDB API Future search({expression}) async { expression ??= Get.find().fieldText; - final response = - await http.get(Uri.parse('$imdbBaseUrl/SearchAll/$apiKey/$expression')); + final response = await getUrl( + url: '$imdbBaseUrl/SearchAll/${apiKey[activeApiKey]}/$expression'); if (response.statusCode == 200) { var json = jsonDecode(response.body)["results"]; @@ -162,8 +152,10 @@ class APIRequester { // Get full details of a show from the IMDB API Future getShow({required String id}) async { - final response = await http.get(Uri.parse( - '$imdbBaseUrl/Title/$apiKey/$id/Posters,Images,Trailer,Ratings,')); + final response = await getUrl( + url: + '$imdbBaseUrl/Title/${apiKey[activeApiKey]}/$id/Posters,Images,Trailer,Ratings,'); + if (response.statusCode == 200) { var showJson = jsonDecode(response.body); FullShow show = FullShow.fromJson(showJson); @@ -177,8 +169,10 @@ class APIRequester { Future getShowEpisodes( {required dynamic show, required int season}) async { final cacheHolder = CacheHolder(); - final response = await http.get( - Uri.parse('$imdbBaseUrl/SeasonEpisodes/$apiKey/${show.id}/$season')); + final response = await getUrl( + url: + '$imdbBaseUrl/SeasonEpisodes/${apiKey[activeApiKey]}/${show.id}/$season'); + if (response.statusCode == 200) { var json = jsonDecode(response.body)["episodes"]; List seasonEpisodes = []; @@ -198,7 +192,9 @@ class APIRequester { // Get full details of a show from the IMDB API Future getActor({required String id}) async { - final response = await http.get(Uri.parse('$imdbBaseUrl/Name/$apiKey/$id')); + final response = + await getUrl(url: '$imdbBaseUrl/Name/${apiKey[activeApiKey]}/$id'); + if (response.statusCode == 200) { var actorJson = jsonDecode(response.body); FullActor actor = FullActor.fromJson(actorJson); @@ -207,4 +203,41 @@ class APIRequester { return null; } } + + // Get external sites of a show from the IMDB API + Future getExternalSites({required String id}) async { + final response = await getUrl( + url: '$imdbBaseUrl/ExternalSites/${apiKey[activeApiKey]}/$id'); + if (response.statusCode == 200) { + var json = jsonDecode(response.body); + late ExternalSites externalSites; + externalSites = ExternalSites.fromJson(json); + return externalSites; + } else { + return null; + } + } + + Future getUrl({required String url}) async { + var response = await http.get(Uri.parse(url)).timeout( + const Duration(seconds: 10), + ); + if (jsonDecode(response.body)['errorMessage'] != "" && + jsonDecode(response.body)['errorMessage'] != null) { + // Here we handle the IMDb API limit error + // If the API key is invalid, change it to the next one + if (kDebugMode) { + activeApiKey++; + print("Server error: ${jsonDecode(response.body)['errorMessage']}"); + print("activeApiKey changed to: $activeApiKey"); + } + await getUrl( + url: url.replaceAll( + apiKey[activeApiKey - 1], apiKey[activeApiKey])) + .then((value) { + response = value; + }); + } + return response; + } } diff --git a/lib/modules/get_show_info.dart b/lib/modules/get_show_info.dart index b676fcc..7c55f27 100644 --- a/lib/modules/get_show_info.dart +++ b/lib/modules/get_show_info.dart @@ -1,5 +1,5 @@ import 'package:flutter/foundation.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/modules/cache/cacheholder.dart'; import '../models/show_models/full_show_model.dart'; diff --git a/lib/pages/actor/actor_page/get_actor_info.dart b/lib/pages/actor/actor_page/get_actor_info.dart index f78d63d..92f7f40 100644 --- a/lib/pages/actor/actor_page/get_actor_info.dart +++ b/lib/pages/actor/actor_page/get_actor_info.dart @@ -1,5 +1,5 @@ import 'package:flutter/foundation.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/modules/cache/cacheholder.dart'; import '../../../models/actor_models/full_actor_model.dart'; diff --git a/lib/pages/main/home/sections/box_office/box_office.dart b/lib/pages/main/home/sections/box_office/box_office.dart index df31a68..c5fbfab 100644 --- a/lib/pages/main/home/sections/box_office/box_office.dart +++ b/lib/pages/main/home/sections/box_office/box_office.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:movielab/constants/types.dart'; import 'package:movielab/pages/main/home/sections/box_office/pages/all_time.dart'; import 'package:movielab/pages/main/home/sections/box_office/pages/box_office.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import '../../../../../modules/navigate.dart'; import 'box.dart'; diff --git a/lib/pages/main/home/sections/companies/get_company.dart b/lib/pages/main/home/sections/companies/get_company.dart index 81e7793..9c34ca1 100644 --- a/lib/pages/main/home/sections/companies/get_company.dart +++ b/lib/pages/main/home/sections/companies/get_company.dart @@ -1,5 +1,5 @@ import 'package:flutter/foundation.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/modules/cache/cacheholder.dart'; Future getCompanyInfo({required String id}) async { diff --git a/lib/pages/main/home/sections/imdb_lists/lists.dart b/lib/pages/main/home/sections/imdb_lists/lists.dart index 4705b04..65cf720 100644 --- a/lib/pages/main/home/sections/imdb_lists/lists.dart +++ b/lib/pages/main/home/sections/imdb_lists/lists.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:movielab/constants/types.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/pages/main/home/sections/imdb_lists/pages/top_tvs.dart'; import 'package:movielab/pages/main/home/sections/imdb_lists/pages/top_movies.dart'; import '../../../../../modules/navigate.dart'; diff --git a/lib/pages/main/main_controller.dart b/lib/pages/main/main_controller.dart index 83a1be0..89cb3ec 100644 --- a/lib/pages/main/main_controller.dart +++ b/lib/pages/main/main_controller.dart @@ -42,4 +42,12 @@ class MainController extends GetxController { ScrollController searchScrollController = ScrollController(); ScrollController collectionScrollController = ScrollController(); ScrollController profileScrollController = ScrollController(); + + // Active API key controller + int activeApiKey = 0; + + changeActiveApiKey(int index) { + activeApiKey = index; + update(); + } } diff --git a/lib/pages/main/search/search.dart b/lib/pages/main/search/search.dart index 78c644a..03035a0 100644 --- a/lib/pages/main/search/search.dart +++ b/lib/pages/main/search/search.dart @@ -1,6 +1,6 @@ import 'package:get/get.dart'; import 'package:movielab/constants/types.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/pages/main/search/search_bar/search_bar_controller.dart'; doSearch() async { diff --git a/lib/pages/main/search/search_bar/voice_search.dart b/lib/pages/main/search/search_bar/voice_search.dart index 69ae10a..4b1af3e 100644 --- a/lib/pages/main/search/search_bar/voice_search.dart +++ b/lib/pages/main/search/search_bar/voice_search.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:movielab/constants/colors.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/pages/main/search/search.dart'; import 'package:movielab/pages/main/search/search_bar/search_bar_controller.dart'; import 'package:speech_to_text/speech_to_text.dart' as stt; diff --git a/lib/pages/show/show_page/sections/bottom_bar/bottom_bar.dart b/lib/pages/show/show_page/sections/bottom_bar/bottom_bar.dart index c318c74..59c02b8 100644 --- a/lib/pages/show/show_page/sections/bottom_bar/bottom_bar.dart +++ b/lib/pages/show/show_page/sections/bottom_bar/bottom_bar.dart @@ -5,7 +5,6 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:movielab/constants/colors.dart'; import 'package:movielab/models/show_models/full_show_model.dart'; import 'package:share_plus/share_plus.dart'; -import 'sections/external_sites/external_sites.dart'; import 'sections/lists_info/lists_info.dart'; class ShowPageBottonBar extends StatefulWidget { @@ -92,22 +91,7 @@ class _ShowPageBottonBarState extends State ), ), onTap: () { - showModalBottomSheet( - context: context, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical( - top: Radius.circular(20), - )), - clipBehavior: Clip.antiAliasWithSaveLayer, - backgroundColor: kSecondaryColor, - transitionAnimationController: AnimationController( - duration: const Duration(milliseconds: 300), vsync: this), - builder: (context) { - return ShowPageExternalSites( - show: widget.show, - ); - }, - ); + Scaffold.of(context).openEndDrawer(); }, ), const SizedBox( diff --git a/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart b/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart index 2bc553e..4d7c127 100644 --- a/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart +++ b/lib/pages/show/show_page/sections/bottom_bar/sections/external_sites/external_sites.dart @@ -1,18 +1,115 @@ import 'package:flutter/material.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:movielab/constants/colors.dart'; +import 'package:movielab/models/external_sites_model.dart'; import 'package:movielab/models/show_models/full_show_model.dart'; +import 'package:movielab/modules/api/api_requester.dart'; +import 'package:movielab/widgets/section_title.dart'; +import 'package:url_launcher/url_launcher.dart'; class ShowPageExternalSites extends StatelessWidget { final FullShow show; - const ShowPageExternalSites({Key? key, required this.show}) : super(key: key); - + ShowPageExternalSites({Key? key, required this.show}) : super(key: key); + late ExternalSites externalSites; @override Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 20), - height: 300, - child: Column( - children: const [], - ), - ); + final APIRequester apiRequester = APIRequester(); + return FutureBuilder( + future: apiRequester.getExternalSites(id: show.id), + builder: (context, snapshot) { + if (snapshot.data != null) { + return SafeArea( + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 10), + child: Stack( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: const [ + SectionTitle( + title: "Open Width", + padding: EdgeInsets.zero, + ), + SectionTitle( + title: "Done", + color: kPrimaryColor, + fontSize: 15, + padding: EdgeInsets.zero, + ), + ], + ), + Column( + children: [ + const SizedBox( + height: 50, + ), + Expanded( + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + itemCount: 10, + itemBuilder: (context, index) { + return Column( + children: [ + index == 0 + ? SectionTitle( + title: "Discover", + fontSize: 15, + color: Colors.white.withOpacity(0.75), + padding: const EdgeInsets.symmetric( + vertical: 5), + ) + : const SizedBox.shrink(), + InkWell( + onTap: () => _launchUrl(Uri.parse( + snapshot.data?.freebase ?? "")), + child: SizedBox( + height: 50, + child: Row( + children: [ + SizedBox( + width: 50, + child: Image.asset( + "assets/images/logos/IMDb.png")), + const SizedBox( + width: 10, + ), + Text( + externalSitesList[index]["title"] ?? + "", + style: const TextStyle( + color: Colors.white), + ), + ], + ), + ), + ), + ], + ); + }, + ), + ) + ], + ), + ], + ), + ), + ); + } + return const SizedBox( + height: 300, + child: Center( + child: SpinKitThreeBounce( + color: Colors.white, + size: 40, + ), + )); + }); + } +} + +Future _launchUrl(url) async { + if (!await launchUrl(url)) { + throw 'Could not launch $url'; } } diff --git a/lib/pages/show/show_page/sections/bottom_bar/sections/lists_info/lists_info.dart b/lib/pages/show/show_page/sections/bottom_bar/sections/lists_info/lists_info.dart index a2f72cb..58f6ce0 100644 --- a/lib/pages/show/show_page/sections/bottom_bar/sections/lists_info/lists_info.dart +++ b/lib/pages/show/show_page/sections/bottom_bar/sections/lists_info/lists_info.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:movielab/constants/colors.dart'; import 'package:movielab/models/hive/convertor.dart'; +import 'package:movielab/models/show_models/full_show_model.dart'; import 'package:movielab/modules/capitalizer.dart'; -import '../../../../../../../constants/colors.dart'; -import '../../../../../../../models/show_models/full_show_model.dart'; -import '../../../../../../../modules/preferences_shareholder.dart'; -import '../../../../../../../widgets/buttons/activeable_button.dart'; -import '../../../../../../../widgets/toast.dart'; -import '../../watchtime.dart'; +import 'package:movielab/modules/preferences_shareholder.dart'; +import 'package:movielab/pages/show/show_page/sections/bottom_bar/watchtime.dart'; +import 'package:movielab/widgets/buttons/activeable_button.dart'; +import 'package:movielab/widgets/toast.dart'; class ShowPageListsInfo extends StatefulWidget { final FullShow show; diff --git a/lib/pages/show/show_page/sections/episode_guide/episode_guide_page.dart b/lib/pages/show/show_page/sections/episode_guide/episode_guide_page.dart index 1b863c7..504567a 100644 --- a/lib/pages/show/show_page/sections/episode_guide/episode_guide_page.dart +++ b/lib/pages/show/show_page/sections/episode_guide/episode_guide_page.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:movielab/constants/colors.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; import 'package:movielab/pages/show/show_page/sections/episode_guide/season_page.dart'; class EpisodeGuidePage extends StatefulWidget { diff --git a/lib/pages/show/show_page/show_page.dart b/lib/pages/show/show_page/show_page.dart index 8e0e071..90f8a7b 100644 --- a/lib/pages/show/show_page/show_page.dart +++ b/lib/pages/show/show_page/show_page.dart @@ -2,15 +2,16 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:movielab/constants/colors.dart'; import 'package:movielab/constants/types.dart'; +import 'package:movielab/modules/get_show_info.dart'; +import 'package:movielab/modules/preferences_shareholder.dart'; import 'package:movielab/modules/system_ui_overlay_style.dart'; import 'package:movielab/pages/show/show_page/sections/media.dart'; import 'package:movielab/pages/show/show_page/sections/other_ratings/other_ratings.dart'; import 'package:movielab/widgets/error.dart'; -import '../../../constants/colors.dart'; -import '../../../modules/preferences_shareholder.dart'; -import '../../../modules/get_show_info.dart'; import 'sections/bottom_bar/bottom_bar.dart'; +import 'sections/bottom_bar/sections/external_sites/external_sites.dart'; import 'sections/index.dart'; import 'sections/bottom_bar/watchtime.dart'; @@ -131,6 +132,12 @@ class _ShowPageState extends State with TickerProviderStateMixin { floatingActionButtonLocation: _isBottomAppBarVisible ? FloatingActionButtonLocation.endDocked : FloatingActionButtonLocation.endFloat, + endDrawerEnableOpenDragGesture: false, + endDrawer: Drawer( + backgroundColor: kSecondaryColor, + width: MediaQuery.of(context).size.width * 0.66, + child: ShowPageExternalSites(show: show), + ), body: SingleChildScrollView( controller: _scrollController, physics: const BouncingScrollPhysics(), diff --git a/lib/pages/splash/get_Initial_data.dart b/lib/pages/splash/get_Initial_data.dart index 6de5309..7669468 100644 --- a/lib/pages/splash/get_Initial_data.dart +++ b/lib/pages/splash/get_Initial_data.dart @@ -1,7 +1,7 @@ import 'package:get/get.dart'; import 'package:movielab/constants/types.dart'; import 'package:movielab/pages/main/home/home_data_controller.dart'; -import '../../modules/api_requester.dart'; +import '../../modules/api/api_requester.dart'; Future getInitialData() async { final apiRequester = APIRequester(); diff --git a/test/modules_test/api_requester_test.dart b/test/modules_test/api_requester_test.dart index 9cd4491..4dac98d 100644 --- a/test/modules_test/api_requester_test.dart +++ b/test/modules_test/api_requester_test.dart @@ -2,7 +2,7 @@ import 'package:get/get.dart'; import 'package:movielab/constants/types.dart'; import 'package:movielab/pages/main/home/home_data_controller.dart'; import 'package:test/test.dart'; -import 'package:movielab/modules/api_requester.dart'; +import 'package:movielab/modules/api/api_requester.dart'; void main() { test('getTrendingMovies', () async {