From 2c78f26d736732d050cbe9fa2c0660378bd289a7 Mon Sep 17 00:00:00 2001 From: omarkhaled2001 Date: Fri, 23 Dec 2022 23:20:20 +0200 Subject: [PATCH 1/3] Saved Posts Page Ready to Real API Back End Calls --- reddit/lib/app_router.dart | 22 ++ .../cubit/cubit/saved_posts_cubit.dart | 28 ++ .../cubit/cubit/saved_posts_state.dart | 12 + reddit/lib/constants/strings.dart | 4 + reddit/lib/data/model/saved_posts_model.dart | 98 +++++ .../lib/data/repository/saved_posts_repo.dart | 32 ++ .../saved_posts_web_services.dart | 43 +++ reddit/lib/main.dart | 1 - .../lib/presentation/screens/saved_posts.dart | 358 ++++++++++++++++++ .../presentation/screens/saved_tab_bar.dart | 45 +++ .../nav_bars/app_bar_web_loggedin.dart | 3 + 11 files changed, 645 insertions(+), 1 deletion(-) create mode 100644 reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart create mode 100644 reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart create mode 100644 reddit/lib/data/model/saved_posts_model.dart create mode 100644 reddit/lib/data/repository/saved_posts_repo.dart create mode 100644 reddit/lib/data/web_services/saved_posts_web_services.dart create mode 100644 reddit/lib/presentation/screens/saved_posts.dart create mode 100644 reddit/lib/presentation/screens/saved_tab_bar.dart diff --git a/reddit/lib/app_router.dart b/reddit/lib/app_router.dart index 5ffc1533..e7146b2a 100644 --- a/reddit/lib/app_router.dart +++ b/reddit/lib/app_router.dart @@ -147,6 +147,10 @@ import 'package:reddit/data/repository/message_screen_repository.dart'; import 'package:reddit/data/web_services/message_screen_web_services.dart'; import 'package:reddit/business_logic/cubit/cubit/inbox_screen_cubit.dart'; import 'package:reddit/business_logic/cubit/cubit/sent_screen_cubit.dart'; +import 'package:reddit/presentation/screens/saved_posts.dart'; +import 'package:reddit/data/repository/saved_posts_repo.dart'; +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; +import 'package:reddit/business_logic/cubit/cubit/saved_posts_cubit.dart'; class AppRouter { // platform @@ -222,6 +226,10 @@ class AppRouter { late PostFlairCubit postFlairCubit; late CreatePostWebServices postWebServices; + late SavedPostsWebServices savedPostsWebServices; + late SavedPostsRepository savedPostsRepository; + late SavedPostsCubit savedPostsCubit; + late SortCubit subredditSortCubit; AppRouter() { // initialise repository and cubit objects @@ -295,6 +303,10 @@ class AppRouter { postSubredditPreviewCubit = PostSubredditPreviewCubit(postRepository); postFlairCubit = PostFlairCubit(postRepository); subredditSortCubit = SortCubit(); + savedPostsWebServices = SavedPostsWebServices(); + savedPostsRepository = + SavedPostsRepository(savedPostsWebServices: savedPostsWebServices); + savedPostsCubit = SavedPostsCubit(savedPostsRepository); } Route? generateRoute(RouteSettings settings) { final arguments = settings.arguments; @@ -833,6 +845,16 @@ class AppRouter { } else { break; } + case savedPostsRoute: + if (true /*!isMobile*/) { + return MaterialPageRoute( + builder: (_) => BlocProvider( + create: (BuildContext context) => savedPostsCubit, + child: const SavedPosts(), + )); + } else { + break; + } case createPostScreenRoute: return MaterialPageRoute( builder: (_) => BlocProvider( diff --git a/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart b/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart new file mode 100644 index 00000000..86b53c8c --- /dev/null +++ b/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart @@ -0,0 +1,28 @@ +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; +import 'package:reddit/data/repository/saved_posts_repo.dart'; +import 'package:reddit/data/model/saved_posts_model.dart'; + +part 'saved_posts_state.dart'; + +class SavedPostsCubit extends Cubit { + late List savedPosts; + final SavedPostsRepository savedPostsRepository; + + SavedPostsCubit(this.savedPostsRepository) : super(SavedPostsInitial()); + + void getAllSavedPosts() { + // To avoid state error when you leave the settings page + if (isClosed) return; + savedPostsRepository.getAllSavedPosts().then((savedPosts) { + this.savedPosts = savedPosts.savedPosts!; + print('saved Posts after Cubit'); + print(this.savedPosts.length); + for (var savedPost in this.savedPosts) { + print(savedPost.printfunc()); + } + emit(SavedPostsLoaded(savedPosts.savedPosts!)); + this.savedPosts = savedPosts.savedPosts!; + }); + } +} diff --git a/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart b/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart new file mode 100644 index 00000000..f7e7b0c8 --- /dev/null +++ b/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart @@ -0,0 +1,12 @@ +part of 'saved_posts_cubit.dart'; + +@immutable +abstract class SavedPostsState {} + +class SavedPostsInitial extends SavedPostsState {} + +class SavedPostsLoaded extends SavedPostsState { + final List savedPosts; + + SavedPostsLoaded(this.savedPosts); +} diff --git a/reddit/lib/constants/strings.dart b/reddit/lib/constants/strings.dart index bd3e50cb..3e7c8d9f 100644 --- a/reddit/lib/constants/strings.dart +++ b/reddit/lib/constants/strings.dart @@ -114,3 +114,7 @@ const sentRoute = '/sent'; // ----------Post Page Route------------- //--------------------------------------- const postPageRoute = "/post_page"; +//--------------------------------------- +// ----------Saved Posts Route----------- +//--------------------------------------- +const savedPostsRoute = "/saved_Posts"; diff --git a/reddit/lib/data/model/saved_posts_model.dart b/reddit/lib/data/model/saved_posts_model.dart new file mode 100644 index 00000000..24ffeac4 --- /dev/null +++ b/reddit/lib/data/model/saved_posts_model.dart @@ -0,0 +1,98 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +/// Model for Getting savedPosts from "/api/user/post/save". +class SavedPostsModel { + late String id; + late String text; + late int commentCount; + late String title; + late String publishedDate; + late String subredditName; + late String subredditId; + late int votesCount; + late String userName; + late String userPhoto; + late String userId; + + SavedPostsModel({ + required this.id, + required this.text, + required this.commentCount, + required this.title, + required this.publishedDate, + required this.subredditName, + required this.subredditId, + required this.votesCount, + required this.userName, + required this.userPhoto, + required this.userId, + }); + + @override + // ignore: hash_and_equals + bool operator ==(Object other) => + identical(this, other) || + other is SavedPostsModel && + id == other.id && + text == other.text && + commentCount == other.commentCount && + title == other.title && + publishedDate == other.publishedDate && + subredditName == other.subredditName && + subredditId == other.subredditId && + votesCount == other.votesCount && + userName == other.userName && + userPhoto == other.userPhoto && + userId == other.userId; + + SavedPostsModel.fromJson(Map json) { + id = json['_id']; + text = json['text']; + commentCount = json['commentCount']; + title = json['title']; + publishedDate = json['publishedDate']; + votesCount = json['votesCount']; + subredditFromJson(json['subredditInfo']); + userFromJson(json['user']); + } + + subredditFromJson(Map json) { + subredditName = json['name']; + subredditId = json['id']; + } + + userFromJson(Map json) { + userName = json['username']; + String tempUserPhoto = json['photo']; + userPhoto = tempUserPhoto.substring(1); + userId = json['id']; + } + + printfunc() { + print( + 'Post: id =$id ,text=$text , commentCount =$commentCount ,title=$title ,publishedDate=$publishedDate , subredditId =$subredditId ,subredditName=$subredditName , votesCount =$votesCount ,userName=$userName ,userPhoto=$userPhoto,userId =$userId '); + } +} + +class SavedPostsModelling { + List? savedPosts; + SavedPostsModelling() { + savedPosts = []; + } + copysavedPostsFromJson(List jsons) { + savedPosts = []; + if (savedPosts != null) { + for (var json in jsons) { + savedPosts!.add(SavedPostsModel.fromJson((json))); + } + print('Saved Posts after Modilling'); + print(savedPosts!.length); + for (var post in savedPosts!) { + print(post.printfunc()); + } + } + } + + datafromJson(Map json) { + copysavedPostsFromJson(json['data']); + } +} diff --git a/reddit/lib/data/repository/saved_posts_repo.dart b/reddit/lib/data/repository/saved_posts_repo.dart new file mode 100644 index 00000000..5bc1a176 --- /dev/null +++ b/reddit/lib/data/repository/saved_posts_repo.dart @@ -0,0 +1,32 @@ +// ignore_for_file: avoid_print + +import 'dart:convert'; + +import 'package:reddit/data/model/saved_posts_model.dart'; + +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; + +/// Repo for Reciveng data from Web Server. +/// +/// Then Model it. +/// Then Sending it to Cubit. +class SavedPostsRepository { + final SavedPostsWebServices savedPostsWebServices; + SavedPostsModelling savedPostsModelling = SavedPostsModelling(); + + SavedPostsRepository({ + required this.savedPostsWebServices, + }); + + Future getAllSavedPosts() async { + final savedPosts = await savedPostsWebServices.getAllSavedPosts(); + print("All saved Posts from repo:"); + print("$savedPosts"); + if (savedPosts != []) { + savedPostsModelling.datafromJson(savedPosts); + return savedPostsModelling; + } else { + return SavedPostsModelling(); + } + } +} diff --git a/reddit/lib/data/web_services/saved_posts_web_services.dart b/reddit/lib/data/web_services/saved_posts_web_services.dart new file mode 100644 index 00000000..c874721f --- /dev/null +++ b/reddit/lib/data/web_services/saved_posts_web_services.dart @@ -0,0 +1,43 @@ +// ignore_for_file: avoid_print, duplicate_ignore + +import 'package:dio/dio.dart'; +import 'package:reddit/constants/strings.dart'; +import 'package:flutter/foundation.dart'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/cupertino.dart'; +import 'package:http_parser/http_parser.dart'; + +import '../model/auth_model.dart'; + +class SavedPostsWebServices { + late Dio dio; + String mockUrl = + "https://595283e6-1374-49a3-abc2-32091303998c.mock.pstmn.io/"; + + ///Setting Dio Options. + SavedPostsWebServices() { + BaseOptions options = BaseOptions( + baseUrl: baseUrl, // mockUrl, + receiveDataWhenStatusError: true, + connectTimeout: 20 * 1000, //20 secs + receiveTimeout: 20 * 1000, + ); + dio = Dio(options); + } + dynamic getAllSavedPosts() async { + try { + // Response response = await dio.get('user/post/save'); + Response response = await dio.get('user/post/save', + options: Options( + headers: {"Authorization": "Bearer ${UserData.user!.token}"}, + )); + debugPrint('status code : ${response.statusCode}'); + print(response.data); + return response.data; + } catch (e) { + print(e); + return {}; + } + } +} diff --git a/reddit/lib/main.dart b/reddit/lib/main.dart index 74debd83..3b333d46 100644 --- a/reddit/lib/main.dart +++ b/reddit/lib/main.dart @@ -56,7 +56,6 @@ class MyApp extends StatelessWidget { // arguments: {"isLoggedIn": isLoggedIn}))!, // ]; // }, - ); } } diff --git a/reddit/lib/presentation/screens/saved_posts.dart b/reddit/lib/presentation/screens/saved_posts.dart new file mode 100644 index 00000000..1efe5987 --- /dev/null +++ b/reddit/lib/presentation/screens/saved_posts.dart @@ -0,0 +1,358 @@ +import 'package:flutter/material.dart'; +import 'package:reddit/constants/theme_colors.dart'; +import 'package:reddit/presentation/screens/saved_tab_bar.dart'; +import 'package:reddit/presentation/widgets/nav_bars/app_bar_web_loggedin.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:reddit/constants/colors.dart'; + +import 'package:reddit/data/model/saved_posts_model.dart'; +import 'package:reddit/business_logic/cubit/cubit/saved_posts_cubit.dart'; + +class SavedPosts extends StatefulWidget { + const SavedPosts({super.key}); + + @override + State createState() => _SavedPostsState(); +} + +class _SavedPostsState extends State { + late List savedPosts; + @override + void initState() { + super.initState(); + BlocProvider.of(context).getAllSavedPosts(); + } + + Widget createAllSavedPostsContainer( + String id, + String title, + int votesCount, + int commentCount, + String subredditId, + String subredditName, + String userName, + String userId, + String userPhoto, + String publishedDate, + String text, + Color c) { + return Container( + color: const Color.fromARGB(0, 0, 0, 0), + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + child: Row( + children: [ + Expanded( + flex: 1, + child: Container( + color: const Color.fromARGB(0, 0, 0, 0), + ), + ), + Expanded( + flex: 70, + child: Container( + color: c, + child: Row( + children: [ + Expanded( + flex: 1, + child: Container( + color: c, + ), + ), + Expanded( + flex: 100, + child: Column( + children: [ + Row(children: [ + //Title Row + Expanded( + child: SizedBox( + child: ListTile( + leading: CircleAvatar( + backgroundColor: Colors.red, + child: Logo( + Logos.reddit, + color: Colors.white, + size: 25, + ), + ), + title: Column( + children: [ + Row(children: [ + //Massage info Row + Padding( + padding: const EdgeInsets.all(1.0), + child: Text( + "r/$subredditName ", + style: const TextStyle( + fontSize: 12, + color: Color.fromARGB( + 255, 15, 116, 12), + ), + )), + ]), + Row(children: [ + //Massage info Row + Padding( + padding: const EdgeInsets.all(1.0), + child: Text( + "u/$userName ", + style: const TextStyle( + fontSize: 12, + color: Color.fromARGB( + 255, 15, 116, 12), + ), + )), + Padding( + padding: const EdgeInsets.all(2.0), + child: Text( + " . $publishedDate ago", + style: const TextStyle( + fontSize: 12, + color: Color.fromARGB( + 255, 105, 105, 105), + ), + )), + ]), + ], + ), + ), + ), + ) + ]), + Column( + children: [ + SingleChildScrollView( + child: Container( + margin: const EdgeInsets.only(left: 50), + child: Column( + children: [ + Row(children: [ + //Post title Row + Expanded( + child: SizedBox( + child: Text( + title, + style: const TextStyle( + fontSize: 15, + color: Color.fromARGB( + 255, 213, 208, 208), + ), + )), + ), + ]), + Row(children: [ + //Post Body Row + Expanded( + child: SizedBox( + child: Text( + text, + style: const TextStyle( + fontSize: 15, + color: Color.fromARGB( + 255, 213, 208, 208), + ), + )), + ), + ]), + ], + ), + ), + ), + Container( + margin: + const EdgeInsets.only(left: 5, bottom: 30), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon(Icons.arrow_upward, + color: Colors.grey)), + Text("$votesCount", + style: + const TextStyle(fontSize: 17)), + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.arrow_downward, + color: Colors.grey)), + const SizedBox(width: 10), + ]), + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.comment_outlined, + color: Colors.grey)), + Text("$commentCount Comments", + style: + const TextStyle(fontSize: 17)), + ]), + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon(Icons.share, + color: Colors.grey)), + const Text("Share", + style: TextStyle(fontSize: 17)), + ]), + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon(Icons.save, + color: Colors.grey)), + const Text("Unsave", + style: TextStyle(fontSize: 17)), + ]), + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon( + Icons.remove_red_eye, + color: Colors.grey)), + const Text("Hide", + style: TextStyle(fontSize: 17)), + ]), + Row(children: [ + IconButton( + onPressed: () {}, + icon: const Icon(Icons.flag, + color: Colors.grey)), + const Text("Report", + style: TextStyle(fontSize: 17)), + ]), + ]), + ), + ], + ) + ], + ), + ), + Expanded( + flex: 10, + child: Container( + color: c, + ), + ), + ], + ), + ), + ), + Expanded( + flex: 1, + child: Container( + color: const Color.fromARGB(255, 0, 0, 0), + ), + ), + ], + ), + ), + ); + } + + Widget getAllSavedPostsContainerWidgets( + List savedPostsList) { + return Column( + children: savedPostsList + .map((savedPost) => createAllSavedPostsContainer( + savedPost.id, + savedPost.title, + savedPost.votesCount, + savedPost.commentCount, + savedPost.subredditId, + savedPost.subredditName, + savedPost.userName, + savedPost.userId, + savedPost.userPhoto, + savedPost.publishedDate, + savedPost.text, + const Color.fromARGB(255, 27, 26, 26))) + .toList()); + } + + Widget getAllSavedPosts(List savedPostsList) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only(top: 20, bottom: 100), + child: Column(children: [ + getAllSavedPostsContainerWidgets(savedPostsList) + ]), + ), + ); + } + + Widget _savedPostsBody(context, List savedPosts) { + return Padding( + padding: const EdgeInsets.all(15), + child: Row( + children: [ + SizedBox( + width: MediaQuery.of(context).size.width - 1200 > 0 + ? MediaQuery.of(context).size.width - 1200 + : 0), + Container( + padding: const EdgeInsets.all(15), + width: MediaQuery.of(context).size.width - 1200 > 0 + ? 800 + : MediaQuery.of(context).size.width - 30, + decoration: BoxDecoration( + color: cardsColor, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + getAllSavedPosts(savedPosts), + ], + ), + ), + SizedBox( + width: MediaQuery.of(context).size.width - 1200 > 0 + ? MediaQuery.of(context).size.width - 1200 + : 0), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + shape: + const Border(bottom: BorderSide(color: Colors.grey, width: 0.5)), + automaticallyImplyLeading: false, + backgroundColor: defaultAppbarBackgroundColor, + title: const AppBarWebLoggedIn(screen: 'Saved')), + body: BlocBuilder( + builder: (context, state) { + if (state is SavedPostsLoaded) { + savedPosts = (state).savedPosts; + return SingleChildScrollView( + child: Column( + children: [ + SavedTabBar(index: 0), + _savedPostsBody(context, savedPosts), + ], + ), + ); + } else { + return SingleChildScrollView( + child: Column( + children: [ + SavedTabBar(index: 0), + Container(), + ], + ), + ); + } + }, + ), + ); + } +} diff --git a/reddit/lib/presentation/screens/saved_tab_bar.dart b/reddit/lib/presentation/screens/saved_tab_bar.dart new file mode 100644 index 00000000..5a10b36f --- /dev/null +++ b/reddit/lib/presentation/screens/saved_tab_bar.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:reddit/constants/colors.dart'; +import 'package:reddit/constants/strings.dart'; + +class SavedTabBar extends StatelessWidget { + final int index; + SavedTabBar({required this.index, super.key}); + + @override + Widget build(BuildContext context) { + return Container( + color: cardsColor, + padding: EdgeInsets.fromLTRB( + 30, + 20, + MediaQuery.of(context).size.width - 500 > 0 + ? MediaQuery.of(context).size.width - 500 + : 20, + 20), + child: Row(children: [ + TextButton( + onPressed: () => + Navigator.pushReplacementNamed(context, savedPostsRoute), + child: Text( + 'Saved Posts ', + style: TextStyle( + fontWeight: index == 0 ? FontWeight.bold : FontWeight.normal, + fontSize: 16, + color: index == 0 ? Colors.white : Colors.grey), + )), + const SizedBox(width: 30), + TextButton( + onPressed: () => + Navigator.pushReplacementNamed(context, savedPostsRoute), + child: Text( + 'Saved Comments ', + style: TextStyle( + fontWeight: index == 1 ? FontWeight.bold : FontWeight.normal, + fontSize: 16, + color: index == 1 ? Colors.white : Colors.grey), + )), + ]), + ); + } +} diff --git a/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart b/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart index b1d95665..2227e813 100644 --- a/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart +++ b/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart @@ -66,6 +66,9 @@ class _AppBarWebLoggedInState extends State { case 'Messages': Navigator.pushNamed(context, sendMessageRoute, arguments: ''); break; + case 'Saved': + Navigator.pushNamed(context, savedPostsRoute); + break; case 'Create Community': createCommunityDialog(); break; From cf45f556864208d38a9f89b09d1de774e61106e6 Mon Sep 17 00:00:00 2001 From: omarkhaled2001 Date: Fri, 23 Dec 2022 23:34:02 +0200 Subject: [PATCH 2/3] Saved Posts Page Final Ready to Real API Back End Calls --- .../nav_bars/app_bar_web_loggedin.dart | 494 +++++++++--------- 1 file changed, 248 insertions(+), 246 deletions(-) diff --git a/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart b/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart index 2227e813..fd21f842 100644 --- a/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart +++ b/reddit/lib/presentation/widgets/nav_bars/app_bar_web_loggedin.dart @@ -1,246 +1,248 @@ -import 'package:dropdown_button2/dropdown_button2.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:icons_plus/icons_plus.dart'; -import 'package:reddit/business_logic/cubit/create_community_cubit.dart'; -import 'package:reddit/constants/strings.dart'; -import 'package:reddit/constants/theme_colors.dart'; -import 'package:reddit/data/model/auth_model.dart'; -import 'package:reddit/data/repository/create_community_repository.dart'; -import 'package:reddit/data/web_services/create_community_web_services.dart'; -import 'package:reddit/presentation/screens/create_community_screen.dart'; -import 'package:reddit/presentation/widgets/nav_bars/popup_menu_logged_in.dart'; - -class AppBarWebLoggedIn extends StatefulWidget { - final String screen; - const AppBarWebLoggedIn({Key? key, required this.screen}) : super(key: key); - - @override - State createState() => _AppBarWebLoggedInState(); -} - -class _AppBarWebLoggedInState extends State { - void createCommunityDialog() { - showDialog( - context: context, - barrierDismissible: false, - builder: (_) => BlocProvider( - create: (context) => CreateCommunityCubit( - CreateCommunityRepository(CreateCommunityWebServices())), - child: const CreateCommunityScreen(), - )); - } - - late FocusNode searchFocusNode; - - @override - void initState() { - super.initState(); - searchFocusNode = FocusNode(); - searchFocusNode.addListener(_onFocusChangeSearch); - } - - void _onFocusChangeSearch() { - if (searchFocusNode.hasFocus) { - searchFocusNode.unfocus(); - Navigator.pushNamed(context, searchRouteWeb); - } - debugPrint("Focus on search: ${searchFocusNode.hasFocus}"); - } - - @override - void dispose() { - super.dispose(); - searchFocusNode.dispose(); - searchFocusNode.removeListener(_onFocusChangeSearch); - } - - void routeToPage(val) { - switch (val) { - case 'Home': - Navigator.pushNamed(context, homePageRoute); - break; - case 'Popular': - Navigator.pushNamed(context, popularPageRoute); - break; - case 'Messages': - Navigator.pushNamed(context, sendMessageRoute, arguments: ''); - break; - case 'Saved': - Navigator.pushNamed(context, savedPostsRoute); - break; - case 'Create Community': - createCommunityDialog(); - break; - case 'r/subreddit': - // Navigator.pushNamed(context, subredditPageScreenRoute, - // arguments: {'sId': ''}); - - break; - case 'User settings': - Navigator.pushNamed(context, settingsTabsRoute); - break; - default: - } - } - - DropdownMenuItem dropDownMenuTitle(String title) { - return DropdownMenuItem( - enabled: false, - child: Text(title, - style: const TextStyle(fontSize: 12, color: Colors.grey))); - } - - DropdownMenuItem dropDownMenuItem(String title, IconData icon, - {String imgUrl = ''}) { - return DropdownMenuItem( - value: title, - key: Key(title), - child: Row(children: [ - imgUrl == '' - ? Icon(icon, size: 20) - : CircleAvatar( - radius: 15, - backgroundImage: NetworkImage( - imgUrl, - )), - const SizedBox(width: 8), - MediaQuery.of(context).size.width < 930 - ? const SizedBox(width: 0) - : Text(title, style: const TextStyle(fontSize: 15)) - ])); - } - - List> createItems(BuildContext context) { - return [ - dropDownMenuTitle('YOUR COMMUNITIES'), - dropDownMenuItem('Create Community', Icons.add), - dropDownMenuItem('r/subreddit', Icons.person, imgUrl: ''), - - dropDownMenuTitle('FEEDS'), - dropDownMenuItem('Home', Icons.home_filled), - dropDownMenuItem('Popular', Icons.arrow_circle_up_outlined), - // dropDownMenuItem('All',FontAwesomeIcons.chartBar), - - dropDownMenuTitle('FOLLOWING'), - dropDownMenuItem('u/user_name', Icons.person, imgUrl: ''), - - dropDownMenuTitle('OTHER'), - dropDownMenuItem('User settings', Icons.person, - imgUrl: UserData.user!.profilePic!), - dropDownMenuItem('Messages', Icons.person, - imgUrl: UserData.user!.profilePic!), - dropDownMenuItem('Create Post', Icons.add), - ]; - } - - Widget appBardIcon(IconData icon, Function func) { - return InkWell( - onTap: () => func, - child: SizedBox( - width: 40, - height: 40, - child: Icon( - icon, - size: 25, - )), - ); - } - - @override - Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - InkWell( - onTap: () => Navigator.pushNamed(context, homePageRoute), - hoverColor: Colors.transparent, - child: Row( - children: [ - CircleAvatar( - backgroundColor: Colors.red, - child: Logo(Logos.reddit, color: Colors.white, size: 28)), - const SizedBox(width: 10), - MediaQuery.of(context).size.width < 940 - ? const SizedBox(width: 0) - : const Text('reddit'), - ], - ), - ), - Container( - decoration: BoxDecoration( - color: defaultAppbarBackgroundColor, - ), - child: DropdownButton2( - dropdownDecoration: const BoxDecoration( - color: Color.fromRGBO(30, 30, 30, 1), - ), - key: const Key('dropdown'), - alignment: Alignment.center, - buttonHeight: 40, - buttonWidth: 0.17 * MediaQuery.of(context).size.width, - buttonPadding: const EdgeInsets.only(left: 10), - underline: const SizedBox(), - style: const TextStyle(fontSize: 14, color: Colors.white), - items: createItems(context), - value: widget.screen, - onChanged: (val) { - routeToPage(val); - }), - ), - SizedBox( - key: const Key('search-bar'), - width: 0.25 * MediaQuery.of(context).size.width, - height: 40, - child: TextField( - focusNode: searchFocusNode, - textAlignVertical: TextAlignVertical.center, - decoration: InputDecoration( - border: OutlineInputBorder( - borderSide: const BorderSide( - width: 1, color: Color.fromRGBO(50, 50, 50, 100)), - borderRadius: BorderRadius.circular(50.0), - ), - filled: true, - hintText: "Search Reddit", - isDense: true, - hoverColor: const Color.fromRGBO(70, 70, 70, 100), - fillColor: const Color.fromRGBO(50, 50, 50, 100), - prefixIcon: const Icon( - Icons.search, - size: 25, - ), - ), - ), - ), - Row(children: [ - MediaQuery.of(context).size.width < 740 - ? const SizedBox(width: 0) - : Row(children: [ - appBardIcon(Icons.arrow_circle_up_rounded, () { - Navigator.pushReplacementNamed(context, popularPageRoute); - }), - appBardIcon(Icons.circle_outlined, () {}), - appBardIcon(Icons.chat, () {}), - Container( - height: 30, - width: 1, - decoration: BoxDecoration( - border: Border.all(color: Colors.grey))), - ]), - Row( - children: [ - appBardIcon(Icons.shield_outlined, () {}), - appBardIcon(Icons.message_outlined, () {}), - appBardIcon(Icons.notifications_outlined, () {}), - appBardIcon(Icons.add, () {}), - ], - ), - ]), - MediaQuery.of(context).size.width < 520 - ? const SizedBox(width: 0) - : const PopupMenuLoggedIn(), - ], - ); - } -} +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:icons_plus/icons_plus.dart'; +import 'package:reddit/business_logic/cubit/create_community_cubit.dart'; +import 'package:reddit/constants/strings.dart'; +import 'package:reddit/constants/theme_colors.dart'; +import 'package:reddit/data/model/auth_model.dart'; +import 'package:reddit/data/repository/create_community_repository.dart'; +import 'package:reddit/data/web_services/create_community_web_services.dart'; +import 'package:reddit/presentation/screens/create_community_screen.dart'; +import 'package:reddit/presentation/widgets/nav_bars/popup_menu_logged_in.dart'; + +class AppBarWebLoggedIn extends StatefulWidget { + final String screen; + const AppBarWebLoggedIn({Key? key, required this.screen}) : super(key: key); + + @override + State createState() => _AppBarWebLoggedInState(); +} + +class _AppBarWebLoggedInState extends State { + void createCommunityDialog() { + showDialog( + context: context, + barrierDismissible: false, + builder: (_) => BlocProvider( + create: (context) => CreateCommunityCubit( + CreateCommunityRepository(CreateCommunityWebServices())), + child: const CreateCommunityScreen(), + )); + } + + late FocusNode searchFocusNode; + + @override + void initState() { + super.initState(); + searchFocusNode = FocusNode(); + searchFocusNode.addListener(_onFocusChangeSearch); + } + + void _onFocusChangeSearch() { + if (searchFocusNode.hasFocus) { + searchFocusNode.unfocus(); + Navigator.pushNamed(context, searchRouteWeb); + } + debugPrint("Focus on search: ${searchFocusNode.hasFocus}"); + } + + @override + void dispose() { + super.dispose(); + searchFocusNode.dispose(); + searchFocusNode.removeListener(_onFocusChangeSearch); + } + + void routeToPage(val) { + switch (val) { + case 'Home': + Navigator.pushNamed(context, homePageRoute); + break; + case 'Popular': + Navigator.pushNamed(context, popularPageRoute); + break; + case 'Messages': + Navigator.pushNamed(context, sendMessageRoute, arguments: ''); + break; + case 'Saved': + Navigator.pushNamed(context, savedPostsRoute); + break; + case 'Create Community': + createCommunityDialog(); + break; + case 'r/subreddit': + // Navigator.pushNamed(context, subredditPageScreenRoute, + // arguments: {'sId': ''}); + + break; + case 'User settings': + Navigator.pushNamed(context, settingsTabsRoute); + break; + default: + } + } + + DropdownMenuItem dropDownMenuTitle(String title) { + return DropdownMenuItem( + enabled: false, + child: Text(title, + style: const TextStyle(fontSize: 12, color: Colors.grey))); + } + + DropdownMenuItem dropDownMenuItem(String title, IconData icon, + {String imgUrl = ''}) { + return DropdownMenuItem( + value: title, + key: Key(title), + child: Row(children: [ + imgUrl == '' + ? Icon(icon, size: 20) + : CircleAvatar( + radius: 15, + backgroundImage: NetworkImage( + imgUrl, + )), + const SizedBox(width: 8), + MediaQuery.of(context).size.width < 930 + ? const SizedBox(width: 0) + : Text(title, style: const TextStyle(fontSize: 15)) + ])); + } + + List> createItems(BuildContext context) { + return [ + dropDownMenuTitle('YOUR COMMUNITIES'), + dropDownMenuItem('Create Community', Icons.add), + dropDownMenuItem('r/subreddit', Icons.person, imgUrl: ''), + + dropDownMenuTitle('FEEDS'), + dropDownMenuItem('Home', Icons.home_filled), + dropDownMenuItem('Popular', Icons.arrow_circle_up_outlined), + // dropDownMenuItem('All',FontAwesomeIcons.chartBar), + + dropDownMenuTitle('FOLLOWING'), + dropDownMenuItem('u/user_name', Icons.person, imgUrl: ''), + + dropDownMenuTitle('OTHER'), + dropDownMenuItem('User settings', Icons.person, + imgUrl: UserData.user!.profilePic!), + dropDownMenuItem('Messages', Icons.person, + imgUrl: UserData.user!.profilePic!), + dropDownMenuItem('Saved', Icons.person, + imgUrl: UserData.user!.profilePic!), + dropDownMenuItem('Create Post', Icons.add), + ]; + } + + Widget appBardIcon(IconData icon, Function func) { + return InkWell( + onTap: () => func, + child: SizedBox( + width: 40, + height: 40, + child: Icon( + icon, + size: 25, + )), + ); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + InkWell( + onTap: () => Navigator.pushNamed(context, homePageRoute), + hoverColor: Colors.transparent, + child: Row( + children: [ + CircleAvatar( + backgroundColor: Colors.red, + child: Logo(Logos.reddit, color: Colors.white, size: 28)), + const SizedBox(width: 10), + MediaQuery.of(context).size.width < 940 + ? const SizedBox(width: 0) + : const Text('reddit'), + ], + ), + ), + Container( + decoration: BoxDecoration( + color: defaultAppbarBackgroundColor, + ), + child: DropdownButton2( + dropdownDecoration: const BoxDecoration( + color: Color.fromRGBO(30, 30, 30, 1), + ), + key: const Key('dropdown'), + alignment: Alignment.center, + buttonHeight: 40, + buttonWidth: 0.17 * MediaQuery.of(context).size.width, + buttonPadding: const EdgeInsets.only(left: 10), + underline: const SizedBox(), + style: const TextStyle(fontSize: 14, color: Colors.white), + items: createItems(context), + value: widget.screen, + onChanged: (val) { + routeToPage(val); + }), + ), + SizedBox( + key: const Key('search-bar'), + width: 0.25 * MediaQuery.of(context).size.width, + height: 40, + child: TextField( + focusNode: searchFocusNode, + textAlignVertical: TextAlignVertical.center, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: const BorderSide( + width: 1, color: Color.fromRGBO(50, 50, 50, 100)), + borderRadius: BorderRadius.circular(50.0), + ), + filled: true, + hintText: "Search Reddit", + isDense: true, + hoverColor: const Color.fromRGBO(70, 70, 70, 100), + fillColor: const Color.fromRGBO(50, 50, 50, 100), + prefixIcon: const Icon( + Icons.search, + size: 25, + ), + ), + ), + ), + Row(children: [ + MediaQuery.of(context).size.width < 740 + ? const SizedBox(width: 0) + : Row(children: [ + appBardIcon(Icons.arrow_circle_up_rounded, () { + Navigator.pushReplacementNamed(context, popularPageRoute); + }), + appBardIcon(Icons.circle_outlined, () {}), + appBardIcon(Icons.chat, () {}), + Container( + height: 30, + width: 1, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey))), + ]), + Row( + children: [ + appBardIcon(Icons.shield_outlined, () {}), + appBardIcon(Icons.message_outlined, () {}), + appBardIcon(Icons.notifications_outlined, () {}), + appBardIcon(Icons.add, () {}), + ], + ), + ]), + MediaQuery.of(context).size.width < 520 + ? const SizedBox(width: 0) + : const PopupMenuLoggedIn(), + ], + ); + } +} From 6768caab81fdaa71fc8e5f1db8bdbd806d1f1394 Mon Sep 17 00:00:00 2001 From: omarkhaled2001 Date: Sat, 24 Dec 2022 21:17:22 +0200 Subject: [PATCH 3/3] Unit Tests & Documentation --- .../cubit/cubit/inbox_screen_cubit.dart | 61 ++-- .../cubit/cubit/inbox_screen_state.dart | 25 +- .../cubit/cubit/saved_posts_cubit.dart | 6 + .../cubit/cubit/saved_posts_state.dart | 1 + .../cubit/cubit/sent_screen_cubit.dart | 61 ++-- .../cubit/cubit/sent_screen_state.dart | 25 +- .../lib/data/model/message_screen_model.dart | 336 ++++++++++-------- reddit/lib/data/model/saved_posts_model.dart | 219 +++++++----- .../repository/message_screen_repository.dart | 98 ++--- .../lib/data/repository/saved_posts_repo.dart | 68 ++-- .../message_screen_web_services.dart | 128 ++++--- .../saved_posts_web_services.dart | 92 ++--- reddit/test/inbox_test.dart | 118 ++++++ reddit/test/saved_posts_test.dart | 118 ++++++ reddit/test/sent_test.dart | 118 ++++++ 15 files changed, 974 insertions(+), 500 deletions(-) create mode 100644 reddit/test/inbox_test.dart create mode 100644 reddit/test/saved_posts_test.dart create mode 100644 reddit/test/sent_test.dart diff --git a/reddit/lib/business_logic/cubit/cubit/inbox_screen_cubit.dart b/reddit/lib/business_logic/cubit/cubit/inbox_screen_cubit.dart index 1cf9c61f..3bd8379f 100644 --- a/reddit/lib/business_logic/cubit/cubit/inbox_screen_cubit.dart +++ b/reddit/lib/business_logic/cubit/cubit/inbox_screen_cubit.dart @@ -1,27 +1,34 @@ -import 'package:bloc/bloc.dart'; -import 'package:meta/meta.dart'; -import 'package:reddit/data/repository/message_screen_repository.dart'; -import 'package:reddit/data/model/message_screen_model.dart'; - -part 'inbox_screen_state.dart'; - -class InboxScreenCubit extends Cubit { - final MessageScreenRepository messageScreenRepository; - late List messagesInbox; - - InboxScreenCubit(this.messageScreenRepository) : super(InboxScreenInitial()); - void getAllMessageInboxModel() { - // To avoid state error when you leave the settings page - if (isClosed) return; - messageScreenRepository.getAllMessageInboxModel().then((messagesInbox) { - this.messagesInbox = messagesInbox.messages!; - print('Inbox data after Cubit'); - print(this.messagesInbox.length); - for (var message in this.messagesInbox) { - print(message.printfunc()); - } - emit(InboxScreenLoaded(messagesInbox.messages!)); - this.messagesInbox = messagesInbox.messages!; - }); - } -} +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; +import 'package:reddit/data/repository/message_screen_repository.dart'; +import 'package:reddit/data/model/message_screen_model.dart'; + +part 'inbox_screen_state.dart'; + +/// This Class Send Inbox Massages Data from Repo to UI using request to the endpoint `baseUrl/message/me/message` From Real API. +class InboxScreenCubit extends Cubit { + final MessageScreenRepository messageScreenRepository; + late List messagesInbox; + + InboxScreenCubit(this.messageScreenRepository) : super(InboxScreenInitial()); + + /// This function Send Inbox Massages Data from Repo to UI. + /// + /// This function emits: + /// state [InboxScreenLoaded] after successfully Recieving the Data. + /// This function calls the function [MessageScreenRepository.getAllMessageInboxModel] to prepare the PATCH request. + void getAllMessageInboxModel() { + // To avoid state error when you leave the settings page + if (isClosed) return; + messageScreenRepository.getAllMessageInboxModel().then((messagesInbox) { + this.messagesInbox = messagesInbox.messages!; + print('Inbox data after Cubit'); + print(this.messagesInbox.length); + for (var message in this.messagesInbox) { + print(message.printfunc()); + } + emit(InboxScreenLoaded(messagesInbox.messages!)); + this.messagesInbox = messagesInbox.messages!; + }); + } +} diff --git a/reddit/lib/business_logic/cubit/cubit/inbox_screen_state.dart b/reddit/lib/business_logic/cubit/cubit/inbox_screen_state.dart index e3dbf950..a3110419 100644 --- a/reddit/lib/business_logic/cubit/cubit/inbox_screen_state.dart +++ b/reddit/lib/business_logic/cubit/cubit/inbox_screen_state.dart @@ -1,12 +1,13 @@ -part of 'inbox_screen_cubit.dart'; - -@immutable -abstract class InboxScreenState {} - -class InboxScreenInitial extends InboxScreenState {} - -class InboxScreenLoaded extends InboxScreenState { - final List messagesInbox; - - InboxScreenLoaded(this.messagesInbox); -} +part of 'inbox_screen_cubit.dart'; + +@immutable +abstract class InboxScreenState {} + +class InboxScreenInitial extends InboxScreenState {} + +/// Messages Inbox [messagesInbox]is Recieved successfully +class InboxScreenLoaded extends InboxScreenState { + final List messagesInbox; + + InboxScreenLoaded(this.messagesInbox); +} diff --git a/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart b/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart index 86b53c8c..81a1a28c 100644 --- a/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart +++ b/reddit/lib/business_logic/cubit/cubit/saved_posts_cubit.dart @@ -5,12 +5,18 @@ import 'package:reddit/data/model/saved_posts_model.dart'; part 'saved_posts_state.dart'; +/// This Class Send Saved Posts Data from Repo to UI using request to the endpoint `baseUrl/user/post/save` From Real API. class SavedPostsCubit extends Cubit { late List savedPosts; final SavedPostsRepository savedPostsRepository; SavedPostsCubit(this.savedPostsRepository) : super(SavedPostsInitial()); + /// This function Send Saved Posts Data from Repo to UI. + /// + /// This function emits: + /// state [SavedPostsLoaded] after successfully Recieving the Data. + /// This function calls the function [SavedPostsRepository.getAllSavedPosts] to prepare the PATCH request. void getAllSavedPosts() { // To avoid state error when you leave the settings page if (isClosed) return; diff --git a/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart b/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart index f7e7b0c8..1d084e4a 100644 --- a/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart +++ b/reddit/lib/business_logic/cubit/cubit/saved_posts_state.dart @@ -5,6 +5,7 @@ abstract class SavedPostsState {} class SavedPostsInitial extends SavedPostsState {} +/// Saved Posts [savedPosts]is Recieved successfully class SavedPostsLoaded extends SavedPostsState { final List savedPosts; diff --git a/reddit/lib/business_logic/cubit/cubit/sent_screen_cubit.dart b/reddit/lib/business_logic/cubit/cubit/sent_screen_cubit.dart index 9ca02c7c..20e8691b 100644 --- a/reddit/lib/business_logic/cubit/cubit/sent_screen_cubit.dart +++ b/reddit/lib/business_logic/cubit/cubit/sent_screen_cubit.dart @@ -1,27 +1,34 @@ -import 'package:bloc/bloc.dart'; -import 'package:meta/meta.dart'; -import 'package:reddit/data/repository/message_screen_repository.dart'; -import 'package:reddit/data/model/message_screen_model.dart'; - -part 'sent_screen_state.dart'; - -class SentScreenCubit extends Cubit { - final MessageScreenRepository messageScreenRepository; - late List sentMessages; - SentScreenCubit(this.messageScreenRepository) : super(SentScreenInitial()); - - void getAllSentMessages() { - // To avoid state error when you leave the settings page - if (isClosed) return; - messageScreenRepository.getAllSentMessageModel().then((sentMessages) { - this.sentMessages = sentMessages.messages!; - print('Sent data after Cubit'); - print(this.sentMessages.length); - for (var message in this.sentMessages) { - print(message.printfunc()); - } - emit(SentScreenLoaded(sentMessages.messages!)); - this.sentMessages = sentMessages.messages!; - }); - } -} +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; +import 'package:reddit/data/repository/message_screen_repository.dart'; +import 'package:reddit/data/model/message_screen_model.dart'; + +part 'sent_screen_state.dart'; + +/// This Class Send Massages Sent Data from Repo to UI using request to the endpoint `baseUrl/message/me/sent` From Real API. +class SentScreenCubit extends Cubit { + final MessageScreenRepository messageScreenRepository; + late List sentMessages; + + SentScreenCubit(this.messageScreenRepository) : super(SentScreenInitial()); + + /// This function Send Massages Sent Data from Repo to UI. + /// + /// This function emits: + /// state [SentScreenLoaded] after successfully Recieving the Data. + /// This function calls the function [MessageScreenRepository.getAllSentMessageModel] to prepare the PATCH request. + void getAllSentMessages() { + // To avoid state error when you leave the settings page + if (isClosed) return; + messageScreenRepository.getAllSentMessageModel().then((sentMessages) { + this.sentMessages = sentMessages.messages!; + print('Sent data after Cubit'); + print(this.sentMessages.length); + for (var message in this.sentMessages) { + print(message.printfunc()); + } + emit(SentScreenLoaded(sentMessages.messages!)); + this.sentMessages = sentMessages.messages!; + }); + } +} diff --git a/reddit/lib/business_logic/cubit/cubit/sent_screen_state.dart b/reddit/lib/business_logic/cubit/cubit/sent_screen_state.dart index 21a547bf..180d3ef1 100644 --- a/reddit/lib/business_logic/cubit/cubit/sent_screen_state.dart +++ b/reddit/lib/business_logic/cubit/cubit/sent_screen_state.dart @@ -1,12 +1,13 @@ -part of 'sent_screen_cubit.dart'; - -@immutable -abstract class SentScreenState {} - -class SentScreenInitial extends SentScreenState {} - -class SentScreenLoaded extends SentScreenState { - final List sentMessages; - - SentScreenLoaded(this.sentMessages); -} +part of 'sent_screen_cubit.dart'; + +@immutable +abstract class SentScreenState {} + +class SentScreenInitial extends SentScreenState {} + +/// Messages Sent [sentMessages]is Recieved successfully +class SentScreenLoaded extends SentScreenState { + final List sentMessages; + + SentScreenLoaded(this.sentMessages); +} diff --git a/reddit/lib/data/model/message_screen_model.dart b/reddit/lib/data/model/message_screen_model.dart index 779ef3c1..e329ef1a 100644 --- a/reddit/lib/data/model/message_screen_model.dart +++ b/reddit/lib/data/model/message_screen_model.dart @@ -1,145 +1,191 @@ -/// Model for Getting Messages from "/api/message/me/message". -class AllMessageInboxModel { - late String id; - late String authorName; - late String subject; - late String body; - late String createdAt; - - AllMessageInboxModel({ - required this.id, - required this.authorName, - required this.subject, - required this.body, - required this.createdAt, - }); - - @override - // ignore: hash_and_equals - bool operator ==(Object other) => - identical(this, other) || - other is AllMessageInboxModel && - id == other.id && - authorName == other.authorName && - subject == other.subject && - body == other.body && - createdAt == other.createdAt; - - AllMessageInboxModel.fromJson(Map json) { - id = json['_id']; - authorName = json['authorName']; - subject = json['subject']; - body = json['body']; - createdAt = json['createdAt']; - } - printfunc() { - print( - 'MassageModel: id =$id ,authorName=$authorName , subject =$subject ,body=$body ,createdAt=$createdAt'); - } -} - -class InboxModelling { - List? messages; - InboxModelling() { - messages = []; - } - copyMessagesFromJson(List jsons) { - messages = []; - if (messages != null) { - for (var json in jsons) { - messages!.add(AllMessageInboxModel.fromJson((json))); - } - print('Inbox data after Modilling'); - print(messages!.length); - for (var message in messages!) { - print(message.printfunc()); - } - } - } - - fromJson(Map json) { - copyMessagesFromJson(json['messages']); - } - - copydataFromJson(List jsons) { - var json = jsons[0]; - fromJson(json); - } - - datafromJson(Map json) { - copydataFromJson(json['data']); - } -} - -/// Model for Getting Messages from "/api/message/me/sent". -class AllSentMessageModel { - late String id; - late String destName; - late String subject; - late String body; - late String createdAt; - - AllSentMessageModel({ - required this.id, - required this.destName, - required this.subject, - required this.body, - required this.createdAt, - }); - - @override - // ignore: hash_and_equals - bool operator ==(Object other) => - identical(this, other) || - other is AllSentMessageModel && - id == other.id && - destName == other.destName && - subject == other.subject && - body == other.body && - createdAt == other.createdAt; - - AllSentMessageModel.fromJson(Map json) { - id = json['_id']; - destName = json['destName']; - subject = json['subject']; - body = json['body']; - createdAt = json['createdAt']; - } - printfunc() { - print( - 'MassageModel: id =$id ,destName=$destName , subject =$subject ,body=$body ,createdAt=$createdAt'); - } -} - -class SentModelling { - List? messages; - SentModelling() { - messages = []; - } - copyMessagesFromJson(List jsons) { - messages = []; - if (messages != null) { - for (var json in jsons) { - messages!.add(AllSentMessageModel.fromJson((json))); - } - print('Sent data after Modilling'); - print(messages!.length); - for (var message in messages!) { - print(message.printfunc()); - } - } - } - - fromJson(Map json) { - copyMessagesFromJson(json['messages']); - } - - copydataFromJson(List jsons) { - var json = jsons[0]; - fromJson(json); - } - - datafromJson(Map json) { - copydataFromJson(json['data']); - } -} +/// This class represents the data model of Inbox Messages from "/api/message/me/message". +class AllMessageInboxModel { + late String id; + late String authorName; + late String subject; + late String body; + late String createdAt; + + AllMessageInboxModel({ + required this.id, + required this.authorName, + required this.subject, + required this.body, + required this.createdAt, + }); + + @override + // ignore: hash_and_equals + /// [other] : is a [AllMessageInboxModel] object that we want to compare with + /// + /// Returns a [bool] that represent the equivilance of two [AllMessageInboxModel] objects + bool operator ==(Object other) => + identical(this, other) || + other is AllMessageInboxModel && + id == other.id && + authorName == other.authorName && + subject == other.subject && + body == other.body && + createdAt == other.createdAt; + + /// [json] : [Map] of the Inbox Messages that was returned by the API. + /// + /// Returns [AllMessageInboxModel] object that contains the data of [json]. + AllMessageInboxModel.fromJson(Map json) { + id = json['_id']; + authorName = json['authorName']; + subject = json['subject']; + body = json['body']; + createdAt = json['createdAt']; + } + + /// To Check Data of the Object from this Model Class [AllMessageInboxModel]. + printfunc() { + print( + 'MassageModel: id =$id ,authorName=$authorName , subject =$subject ,body=$body ,createdAt=$createdAt'); + } +} + +/// This class helping in return Object contain List of [InboxModelling] Recived from Server. +class InboxModelling { + List? messages; + InboxModelling() { + messages = []; + } + + /// [jsons] : [List] of the Inbox Messages that was returned by the API. + /// + /// intializing [messages] + /// Returns [InboxModelling] object that contains the List data of [jsons]. + copyMessagesFromJson(List jsons) { + messages = []; + if (messages != null) { + for (var json in jsons) { + messages!.add(AllMessageInboxModel.fromJson((json))); + } + print('Inbox data after Modilling'); + print(messages!.length); + for (var message in messages!) { + print(message.printfunc()); + } + } + } + + /// [json] : [Map] of the messages Object that was returned by the API. + /// + /// intializing [messages] of [json] Data. + fromJson(Map json) { + copyMessagesFromJson(json['messages']); + } + + /// [json] : [List] of the data List that was returned by the API. + /// + /// intializing [json] of [jsons] Data. + copydataFromJson(List jsons) { + var json = jsons[0]; + fromJson(json); + } + + /// [json] : [Map] of the data Object that was returned by the API. + /// + /// intializing [data] of [json] Data. + datafromJson(Map json) { + copydataFromJson(json['data']); + } +} + +/// This class represents the data model of Sent Messages from "/api/message/me/sent". +class AllSentMessageModel { + late String id; + late String destName; + late String subject; + late String body; + late String createdAt; + + AllSentMessageModel({ + required this.id, + required this.destName, + required this.subject, + required this.body, + required this.createdAt, + }); + + @override + // ignore: hash_and_equals + /// [other] : is a [AllSentMessageModel] object that we want to compare with + /// + /// Returns a [bool] that represent the equivilance of two [AllSentMessageModel] objects + bool operator ==(Object other) => + identical(this, other) || + other is AllSentMessageModel && + id == other.id && + destName == other.destName && + subject == other.subject && + body == other.body && + createdAt == other.createdAt; + + /// [json] : [Map] of the Sent Messages that was returned by the API. + /// + /// Returns [AllSentMessageModel] object that contains the data of [json]. + AllSentMessageModel.fromJson(Map json) { + id = json['_id']; + destName = json['destName']; + subject = json['subject']; + body = json['body']; + createdAt = json['createdAt']; + } + + /// To Check Data of the Object from this Model Class [AllSentMessageModel]. + printfunc() { + print( + 'MassageModel: id =$id ,destName=$destName , subject =$subject ,body=$body ,createdAt=$createdAt'); + } +} + +/// This class helping in return Object contain List of [AllSentMessageModel] Recived from Server. +class SentModelling { + List? messages; + SentModelling() { + messages = []; + } + + /// [jsons] : [List] of the Sent Messages that was returned by the API. + /// + /// intializing [messages] + /// Returns [SentModelling] object that contains the List data of [jsons]. + copyMessagesFromJson(List jsons) { + messages = []; + if (messages != null) { + for (var json in jsons) { + messages!.add(AllSentMessageModel.fromJson((json))); + } + print('Sent data after Modilling'); + print(messages!.length); + for (var message in messages!) { + print(message.printfunc()); + } + } + } + + /// [json] : [Map] of the messages Object that was returned by the API. + /// + /// intializing [messages] of [json] Data. + fromJson(Map json) { + copyMessagesFromJson(json['messages']); + } + + /// [json] : [List] of the data List that was returned by the API. + /// + /// intializing [json] of [jsons] Data. + copydataFromJson(List jsons) { + var json = jsons[0]; + fromJson(json); + } + + /// [json] : [Map] of the data Object that was returned by the API. + /// + /// intializing [data] of [json] Data. + datafromJson(Map json) { + copydataFromJson(json['data']); + } +} diff --git a/reddit/lib/data/model/saved_posts_model.dart b/reddit/lib/data/model/saved_posts_model.dart index 24ffeac4..66f399ee 100644 --- a/reddit/lib/data/model/saved_posts_model.dart +++ b/reddit/lib/data/model/saved_posts_model.dart @@ -1,98 +1,121 @@ -// ignore_for_file: public_member_api_docs, sort_constructors_first -/// Model for Getting savedPosts from "/api/user/post/save". -class SavedPostsModel { - late String id; - late String text; - late int commentCount; - late String title; - late String publishedDate; - late String subredditName; - late String subredditId; - late int votesCount; - late String userName; - late String userPhoto; - late String userId; - - SavedPostsModel({ - required this.id, - required this.text, - required this.commentCount, - required this.title, - required this.publishedDate, - required this.subredditName, - required this.subredditId, - required this.votesCount, - required this.userName, - required this.userPhoto, - required this.userId, - }); - - @override - // ignore: hash_and_equals - bool operator ==(Object other) => - identical(this, other) || - other is SavedPostsModel && - id == other.id && - text == other.text && - commentCount == other.commentCount && - title == other.title && - publishedDate == other.publishedDate && - subredditName == other.subredditName && - subredditId == other.subredditId && - votesCount == other.votesCount && - userName == other.userName && - userPhoto == other.userPhoto && - userId == other.userId; - - SavedPostsModel.fromJson(Map json) { - id = json['_id']; - text = json['text']; - commentCount = json['commentCount']; - title = json['title']; - publishedDate = json['publishedDate']; - votesCount = json['votesCount']; - subredditFromJson(json['subredditInfo']); - userFromJson(json['user']); - } - - subredditFromJson(Map json) { - subredditName = json['name']; - subredditId = json['id']; - } - - userFromJson(Map json) { - userName = json['username']; - String tempUserPhoto = json['photo']; - userPhoto = tempUserPhoto.substring(1); - userId = json['id']; - } - - printfunc() { - print( - 'Post: id =$id ,text=$text , commentCount =$commentCount ,title=$title ,publishedDate=$publishedDate , subredditId =$subredditId ,subredditName=$subredditName , votesCount =$votesCount ,userName=$userName ,userPhoto=$userPhoto,userId =$userId '); - } -} - -class SavedPostsModelling { - List? savedPosts; - SavedPostsModelling() { - savedPosts = []; - } - copysavedPostsFromJson(List jsons) { - savedPosts = []; - if (savedPosts != null) { - for (var json in jsons) { - savedPosts!.add(SavedPostsModel.fromJson((json))); - } - print('Saved Posts after Modilling'); - print(savedPosts!.length); - for (var post in savedPosts!) { - print(post.printfunc()); - } - } - } - - datafromJson(Map json) { - copysavedPostsFromJson(json['data']); - } -} +// ignore_for_file: public_member_api_docs, sort_constructors_first + +/// This class represents the data model of Saved Posts from "/api/user/post/save". +class SavedPostsModel { + late String id; + late String text; + late int commentCount; + late String title; + late String publishedDate; + late String subredditName; + late String subredditId; + late int votesCount; + late String userName; + late String userPhoto; + late String userId; + + SavedPostsModel({ + required this.id, + required this.text, + required this.commentCount, + required this.title, + required this.publishedDate, + required this.subredditName, + required this.subredditId, + required this.votesCount, + required this.userName, + required this.userPhoto, + required this.userId, + }); + + @override + // ignore: hash_and_equals + /// [other] : is a [SavedPostsModel] object that we want to compare with + /// + /// Returns a [bool] that represent the equivilance of two [SavedPostsModel] objects + bool operator ==(Object other) => + identical(this, other) || + other is SavedPostsModel && + id == other.id && + text == other.text && + commentCount == other.commentCount && + title == other.title && + publishedDate == other.publishedDate && + subredditName == other.subredditName && + subredditId == other.subredditId && + votesCount == other.votesCount && + userName == other.userName && + userPhoto == other.userPhoto && + userId == other.userId; + + /// [json] : [Map] of the Saved Posts that was returned by the API. + /// + /// Returns [SavedPostsModel] object that contains the data of [json]. + SavedPostsModel.fromJson(Map json) { + id = json['_id']; + text = json['text']; + commentCount = json['commentCount']; + title = json['title']; + publishedDate = json['publishedDate']; + votesCount = json['votesCount']; + subredditFromJson(json['subredditInfo']); + userFromJson(json['user']); + } + + /// [json] : [Map] of the Subreddit Info that was returned by the API. + /// + /// intializing [subredditId] & [subredditName] of [json] Data. + subredditFromJson(Map json) { + subredditName = json['name']; + subredditId = json['id']; + } + + /// [json] : [Map] of the User Info that was returned by the API. + /// + /// intializing [userName] & [userId] & []of [userPhoto] Data. + userFromJson(Map json) { + userName = json['username']; + String tempUserPhoto = json['photo']; + userPhoto = tempUserPhoto.substring(1); + userId = json['id']; + } + + /// To Check Data of the Object from this Model Class [SavedPostsModel]. + printfunc() { + print( + 'Post: id =$id ,text=$text , commentCount =$commentCount ,title=$title ,publishedDate=$publishedDate , subredditId =$subredditId ,subredditName=$subredditName , votesCount =$votesCount ,userName=$userName ,userPhoto=$userPhoto,userId =$userId '); + } +} + +/// This class helping in return Object contain List of [SavedPostsModel] Recived from Server. +class SavedPostsModelling { + List? savedPosts; + SavedPostsModelling() { + savedPosts = []; + } + + /// [jsons] : [List] of the Saved Posts that was returned by the API. + /// + /// intializing [savedPosts] + /// Returns [SavedPostsModelling] object that contains the List data of [jsons]. + copysavedPostsFromJson(List jsons) { + savedPosts = []; + if (savedPosts != null) { + for (var json in jsons) { + savedPosts!.add(SavedPostsModel.fromJson((json))); + } + print('Saved Posts after Modilling'); + print(savedPosts!.length); + for (var post in savedPosts!) { + print(post.printfunc()); + } + } + } + + /// [json] : [Map] of the Saved Post Object that was returned by the API. + /// + /// intializing [data] of [json] Data. + datafromJson(Map json) { + copysavedPostsFromJson(json['data']); + } +} diff --git a/reddit/lib/data/repository/message_screen_repository.dart b/reddit/lib/data/repository/message_screen_repository.dart index 5596a8c6..d5456a67 100644 --- a/reddit/lib/data/repository/message_screen_repository.dart +++ b/reddit/lib/data/repository/message_screen_repository.dart @@ -1,45 +1,53 @@ -// ignore_for_file: avoid_print - -import 'dart:convert'; - -import 'package:reddit/data/model/message_screen_model.dart'; - -import 'package:reddit/data/web_services/message_screen_web_services.dart'; - -/// Repo for Reciveng data from Web Server. -/// -/// Then Model it. -/// Then Sending it to Cubit. -class MessageScreenRepository { - final MessageScreenWebServices messageScreenWebServices; - SentModelling sentModelling = SentModelling(); - InboxModelling inboxModelling = InboxModelling(); - - MessageScreenRepository({ - required this.messageScreenWebServices, - }); - - Future getAllMessageInboxModel() async { - final allMessages = await messageScreenWebServices.getAllMessagesInbox(); - print("All InboxMessages from repo:"); - print("$allMessages"); - if (allMessages != []) { - inboxModelling.datafromJson(allMessages); - return inboxModelling; - } else { - return InboxModelling(); - } - } - - Future getAllSentMessageModel() async { - final sentMessages = await messageScreenWebServices.getAllSentMessages(); - print("All sent Messages from repo:"); - print("$sentMessages"); - if (sentMessages != []) { - sentModelling.datafromJson(sentMessages); - return sentModelling; - } else { - return SentModelling(); - } - } -} +// ignore_for_file: avoid_print + +import 'dart:convert'; + +import 'package:reddit/data/model/message_screen_model.dart'; + +import 'package:reddit/data/web_services/message_screen_web_services.dart'; + +/// Repo for Reciveng data from Web Server. +/// +/// Then Model it. +/// Then Sending it to Cubit. +class MessageScreenRepository { + final MessageScreenWebServices messageScreenWebServices; + SentModelling sentModelling = SentModelling(); + InboxModelling inboxModelling = InboxModelling(); + + MessageScreenRepository({ + required this.messageScreenWebServices, + }); + + /// This function makes the request to the server to get All Inbox Messages . + /// + /// This function calls the function [MessageScreenWebServices.getAllMessagesInbox] which makes the request to the server. + /// Returns [InboxModelling] that conatins List? [savedPosts]. + Future getAllMessageInboxModel() async { + final allMessages = await messageScreenWebServices.getAllMessagesInbox(); + print("All InboxMessages from repo:"); + print("$allMessages"); + if (allMessages != []) { + inboxModelling.datafromJson(allMessages); + return inboxModelling; + } else { + return InboxModelling(); + } + } + + /// This function makes the request to the server to get All Sent Messages . + /// + /// This function calls the function [MessageScreenWebServices.getAllSentMessages] which makes the request to the server. + /// Returns [SentModelling] that conatins List? [sentMessages]. + Future getAllSentMessageModel() async { + final sentMessages = await messageScreenWebServices.getAllSentMessages(); + print("All sent Messages from repo:"); + print("$sentMessages"); + if (sentMessages != []) { + sentModelling.datafromJson(sentMessages); + return sentModelling; + } else { + return SentModelling(); + } + } +} diff --git a/reddit/lib/data/repository/saved_posts_repo.dart b/reddit/lib/data/repository/saved_posts_repo.dart index 5bc1a176..e5238238 100644 --- a/reddit/lib/data/repository/saved_posts_repo.dart +++ b/reddit/lib/data/repository/saved_posts_repo.dart @@ -1,32 +1,36 @@ -// ignore_for_file: avoid_print - -import 'dart:convert'; - -import 'package:reddit/data/model/saved_posts_model.dart'; - -import 'package:reddit/data/web_services/saved_posts_web_services.dart'; - -/// Repo for Reciveng data from Web Server. -/// -/// Then Model it. -/// Then Sending it to Cubit. -class SavedPostsRepository { - final SavedPostsWebServices savedPostsWebServices; - SavedPostsModelling savedPostsModelling = SavedPostsModelling(); - - SavedPostsRepository({ - required this.savedPostsWebServices, - }); - - Future getAllSavedPosts() async { - final savedPosts = await savedPostsWebServices.getAllSavedPosts(); - print("All saved Posts from repo:"); - print("$savedPosts"); - if (savedPosts != []) { - savedPostsModelling.datafromJson(savedPosts); - return savedPostsModelling; - } else { - return SavedPostsModelling(); - } - } -} +// ignore_for_file: avoid_print + +import 'dart:convert'; + +import 'package:reddit/data/model/saved_posts_model.dart'; + +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; + +/// Repo for Reciveng data from Web Server. +/// +/// Then Model it. +/// Then Sending it to Cubit. +class SavedPostsRepository { + final SavedPostsWebServices savedPostsWebServices; + SavedPostsModelling savedPostsModelling = SavedPostsModelling(); + + SavedPostsRepository({ + required this.savedPostsWebServices, + }); + + /// This function makes the request to the server to get All Saved Posts . + /// + /// This function calls the function [SearchWebService.getSuggestions] which makes the request to the server. + /// Returns [SavedPostsModelling] that conatins List? [savedPosts]. + Future getAllSavedPosts() async { + final savedPosts = await savedPostsWebServices.getAllSavedPosts(); + print("All saved Posts from repo:"); + print("$savedPosts"); + if (savedPosts != []) { + savedPostsModelling.datafromJson(savedPosts); + return savedPostsModelling; + } else { + return SavedPostsModelling(); + } + } +} diff --git a/reddit/lib/data/web_services/message_screen_web_services.dart b/reddit/lib/data/web_services/message_screen_web_services.dart index f1199071..1ca8800f 100644 --- a/reddit/lib/data/web_services/message_screen_web_services.dart +++ b/reddit/lib/data/web_services/message_screen_web_services.dart @@ -1,59 +1,69 @@ -// ignore_for_file: avoid_print, duplicate_ignore - -import 'package:dio/dio.dart'; -import 'package:reddit/constants/strings.dart'; -import 'package:flutter/foundation.dart'; -import 'dart:io'; -import 'dart:typed_data'; -import 'package:flutter/cupertino.dart'; -import 'package:http_parser/http_parser.dart'; - -import '../model/auth_model.dart'; - -class MessageScreenWebServices { - late Dio dio; - String mockUrl = - "https://43a82e45-5f65-4651-90fe-a2190fb44ded.mock.pstmn.io/"; - - ///Setting Dio Options. - MessageScreenWebServices() { - BaseOptions options = BaseOptions( - baseUrl: baseUrl, //mockUrl, - receiveDataWhenStatusError: true, - connectTimeout: 20 * 1000, //20 secs - receiveTimeout: 20 * 1000, - ); - dio = Dio(options); - } - dynamic getAllSentMessages() async { - try { - // Response response = await dio.get('message/me/sent'); - Response response = await dio.get('message/me/sent', - options: Options( - headers: {"Authorization": "Bearer ${UserData.user!.token}"}, - )); - debugPrint('status code : ${response.statusCode}'); - print(response.data); - return response.data; - } catch (e) { - print(e); - return {}; - } - } - - dynamic getAllMessagesInbox() async { - try { - //Response response = await dio.get('message/me/message'); - Response response = await dio.get('message/me/message', - options: Options( - headers: {"Authorization": "Bearer ${UserData.user!.token}"}, - )); - debugPrint('status code : ${response.statusCode}'); - print(response.data); - return response.data; - } catch (e) { - print(e); - return {}; - } - } -} +// ignore_for_file: avoid_print, duplicate_ignore + +import 'package:dio/dio.dart'; +import 'package:reddit/constants/strings.dart'; +import 'package:flutter/foundation.dart'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/cupertino.dart'; +import 'package:http_parser/http_parser.dart'; + +import '../model/auth_model.dart'; + +/// This class is responsible of performing All Messages requests to the REST API +class MessageScreenWebServices { + late Dio dio; + String mockUrl = + "https://43a82e45-5f65-4651-90fe-a2190fb44ded.mock.pstmn.io/"; + + ///Setting Dio Options. + MessageScreenWebServices() { + BaseOptions options = BaseOptions( + baseUrl: baseUrl, //mockUrl, + receiveDataWhenStatusError: true, + connectTimeout: 20 * 1000, //20 secs + receiveTimeout: 20 * 1000, + ); + dio = Dio(options); + } + + /// This function makes the request to the server to get All Sent Messages . + /// + /// This function calls the function [ dio.get ] which makes the request to the server. + /// Returns the response from the server. + dynamic getAllSentMessages() async { + try { + // Response response = await dio.get('message/me/sent'); + Response response = await dio.get('message/me/sent', + options: Options( + headers: {"Authorization": "Bearer ${UserData.user!.token}"}, + )); + debugPrint('status code : ${response.statusCode}'); + print(response.data); + return response.data; + } catch (e) { + print(e); + return {}; + } + } + + /// This function makes the request to the server to get All Messages Inbox. + /// + /// This function calls the function [ dio.get ] which makes the request to the server. + /// Returns the response from the server. + dynamic getAllMessagesInbox() async { + try { + //Response response = await dio.get('message/me/message'); + Response response = await dio.get('message/me/message', + options: Options( + headers: {"Authorization": "Bearer ${UserData.user!.token}"}, + )); + debugPrint('status code : ${response.statusCode}'); + print(response.data); + return response.data; + } catch (e) { + print(e); + return {}; + } + } +} diff --git a/reddit/lib/data/web_services/saved_posts_web_services.dart b/reddit/lib/data/web_services/saved_posts_web_services.dart index c874721f..ef4408b9 100644 --- a/reddit/lib/data/web_services/saved_posts_web_services.dart +++ b/reddit/lib/data/web_services/saved_posts_web_services.dart @@ -1,43 +1,49 @@ -// ignore_for_file: avoid_print, duplicate_ignore - -import 'package:dio/dio.dart'; -import 'package:reddit/constants/strings.dart'; -import 'package:flutter/foundation.dart'; -import 'dart:io'; -import 'dart:typed_data'; -import 'package:flutter/cupertino.dart'; -import 'package:http_parser/http_parser.dart'; - -import '../model/auth_model.dart'; - -class SavedPostsWebServices { - late Dio dio; - String mockUrl = - "https://595283e6-1374-49a3-abc2-32091303998c.mock.pstmn.io/"; - - ///Setting Dio Options. - SavedPostsWebServices() { - BaseOptions options = BaseOptions( - baseUrl: baseUrl, // mockUrl, - receiveDataWhenStatusError: true, - connectTimeout: 20 * 1000, //20 secs - receiveTimeout: 20 * 1000, - ); - dio = Dio(options); - } - dynamic getAllSavedPosts() async { - try { - // Response response = await dio.get('user/post/save'); - Response response = await dio.get('user/post/save', - options: Options( - headers: {"Authorization": "Bearer ${UserData.user!.token}"}, - )); - debugPrint('status code : ${response.statusCode}'); - print(response.data); - return response.data; - } catch (e) { - print(e); - return {}; - } - } -} +// ignore_for_file: avoid_print, duplicate_ignore + +import 'package:dio/dio.dart'; +import 'package:reddit/constants/strings.dart'; +import 'package:flutter/foundation.dart'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/cupertino.dart'; +import 'package:http_parser/http_parser.dart'; + +import '../model/auth_model.dart'; + +/// This class is responsible of performing Saved Posts requests to the REST API +class SavedPostsWebServices { + late Dio dio; + String mockUrl = + "https://595283e6-1374-49a3-abc2-32091303998c.mock.pstmn.io/"; + + ///Setting Dio Options. + SavedPostsWebServices() { + BaseOptions options = BaseOptions( + baseUrl: baseUrl, // mockUrl, + receiveDataWhenStatusError: true, + connectTimeout: 20 * 1000, //20 secs + receiveTimeout: 20 * 1000, + ); + dio = Dio(options); + } + + /// This function makes the request to the server to get Saved Posts. + /// + /// This function calls the function [dio.get] which makes the request to the server. + /// Returns the response from the server. + dynamic getAllSavedPosts() async { + try { + // Response response = await dio.get('user/post/save'); + Response response = await dio.get('user/post/save', + options: Options( + headers: {"Authorization": "Bearer ${UserData.user!.token}"}, + )); + debugPrint('status code : ${response.statusCode}'); + print(response.data); + return response.data; + } catch (e) { + print(e); + return {}; + } + } +} diff --git a/reddit/test/inbox_test.dart b/reddit/test/inbox_test.dart new file mode 100644 index 00000000..d91ef07f --- /dev/null +++ b/reddit/test/inbox_test.dart @@ -0,0 +1,118 @@ +import 'dart:convert'; + +import 'package:bloc_test/bloc_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:reddit/business_logic/cubit/cubit/saved_posts_cubit.dart'; +import 'package:reddit/data/model/saved_posts_model.dart'; +import 'package:reddit/data/repository/saved_posts_repo.dart'; +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; + +class MockDiscoverPageWebService extends Mock implements SavedPostsWebServices { +} + +class MockFDiscoverPagesCubit extends MockCubit + implements SavedPostsCubit {} + +void main() async { + late MockDiscoverPageWebService mockDiscoverPageWebService; + late SavedPostsRepository savedPostsRepository; + late SavedPostsCubit savedPostsCubit; + final Map>> postsListFromWebServices = { + "data": [ + { + "text": "First Post", + "_id": "1", + "commentCount": 300, + "title": "In The Name Of Allah", + "publishedDate": "2023-1-21", + "votesCount": 777, + "subredditInfo": {"name": "ElRayes_Group", "id": "1"}, + "user": { + "username": "Omar_Khaled_2001", + "photo": "/assets/icon/reddit.png", + "id": "1" + } + }, + { + "text": "string", + "_id": "string", + "commentCount": 0, + "title": "string", + "publishedDate": "2022-12-23T17:34:12.984Z", + "votesCount": 0, + "subredditInfo": {"name": "string", "id": "string"}, + "user": {"username": "string", "photo": "string", "id": "string"} + } + ] + }; + + final List savedPostsListFromRepository = [ + SavedPostsModel( + id: "1", + text: "First Post", + commentCount: 300, + title: "In The Name Of Allah", + publishedDate: "2023-1-21", + subredditId: "1", + subredditName: "ElRayes_Group", + votesCount: 777, + userName: "Omar_Khaled_2001", + userPhoto: "/assets/icon/reddit.png", + userId: "1"), + SavedPostsModel( + id: "string", + text: "string", + commentCount: 0, + title: "string", + publishedDate: "2022-12-23T17:34:12.984Z", + subredditId: "string", + subredditName: "string", + votesCount: 0, + userName: "string", + userPhoto: "string", + userId: "string"), + ]; + + group("State test", () { + setUp(() { + mockDiscoverPageWebService = MockDiscoverPageWebService(); + savedPostsRepository = SavedPostsRepository( + savedPostsWebServices: mockDiscoverPageWebService); + savedPostsCubit = SavedPostsCubit(savedPostsRepository); + }); + // Calling getfDiscoverPages() function returns the correct state + // fDiscoverPagesLoading means that the request is sent and we are waiting for the response + // fDiscoverPagesLoaded means that the response is received and UI is built based on this responce + blocTest( + 'Random Posts loaded state is emitted correctly after getting Random Posts data from server', + setUp: () { + when(() => mockDiscoverPageWebService.getAllSavedPosts()).thenAnswer( + (_) async => postsListFromWebServices, + ); + }, + build: () { + return savedPostsCubit; + }, + act: (SavedPostsCubit cubit) => cubit.getAllSavedPosts(), + expect: () => [isA()], + ); + // Test if mapping from Json to model is correct + group('Model test', () { + test('Discover Page Model is generated correctly', () { + SavedPostsModelling savedPostsModelling = SavedPostsModelling(); + savedPostsModelling.datafromJson(postsListFromWebServices); + List? postsListFromModelling = + savedPostsModelling.savedPosts; + expect( + postsListFromModelling![0], + savedPostsListFromRepository[0], + ); + expect( + postsListFromModelling[1], + savedPostsListFromRepository[1], + ); + }); + }); + }); +} diff --git a/reddit/test/saved_posts_test.dart b/reddit/test/saved_posts_test.dart new file mode 100644 index 00000000..3bea2eff --- /dev/null +++ b/reddit/test/saved_posts_test.dart @@ -0,0 +1,118 @@ +import 'dart:convert'; + +import 'package:bloc_test/bloc_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:reddit/business_logic/cubit/cubit/saved_posts_cubit.dart'; +import 'package:reddit/data/model/saved_posts_model.dart'; +import 'package:reddit/data/repository/saved_posts_repo.dart'; +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; + +class MockDiscoverPageWebService extends Mock implements SavedPostsWebServices { +} + +class MockFDiscoverPagesCubit extends MockCubit + implements SavedPostsCubit {} + +void main() async { + late MockDiscoverPageWebService mockDiscoverPageWebService; + late SavedPostsRepository savedPostsRepository; + late SavedPostsCubit savedPostsCubit; + final Map postsListFromWebServices = { + "data": [ + { + "text": "First Post", + "_id": "1", + "commentCount": 300, + "title": "In The Name Of Allah", + "publishedDate": "2023-1-21", + "votesCount": 777, + "subredditInfo": {"name": "ElRayes_Group", "id": "1"}, + "user": { + "username": "Omar_Khaled_2001", + "photo": "/assets/icon/reddit.png", + "id": "1" + } + }, + { + "text": "string", + "_id": "string", + "commentCount": 0, + "title": "string", + "publishedDate": "2022-12-23T17:34:12.984Z", + "votesCount": 0, + "subredditInfo": {"name": "string", "id": "string"}, + "user": {"username": "string", "photo": "string", "id": "string"} + } + ] + }; + + final List? savedPostsListFromRepository = [ + SavedPostsModel( + id: "1", + text: "First Post", + commentCount: 300, + title: "In The Name Of Allah", + publishedDate: "2023-1-21", + subredditId: "1", + subredditName: "ElRayes_Group", + votesCount: 777, + userName: "Omar_Khaled_2001", + userPhoto: "/assets/icon/reddit.png", + userId: "1"), + SavedPostsModel( + id: "string", + text: "string", + commentCount: 0, + title: "string", + publishedDate: "2022-12-23T17:34:12.984Z", + subredditId: "string", + subredditName: "string", + votesCount: 0, + userName: "string", + userPhoto: "string", + userId: "string"), + ]; + + group("State test", () { + setUp(() { + mockDiscoverPageWebService = MockDiscoverPageWebService(); + savedPostsRepository = SavedPostsRepository( + savedPostsWebServices: mockDiscoverPageWebService); + savedPostsCubit = SavedPostsCubit(savedPostsRepository); + }); + // Calling getfDiscoverPages() function returns the correct state + // fDiscoverPagesLoading means that the request is sent and we are waiting for the response + // fDiscoverPagesLoaded means that the response is received and UI is built based on this responce + blocTest( + 'Random Posts loaded state is emitted correctly after getting Random Posts data from server', + setUp: () { + when(() => mockDiscoverPageWebService.getAllSavedPosts()).thenAnswer( + (_) async => postsListFromWebServices, + ); + }, + build: () { + return savedPostsCubit; + }, + act: (SavedPostsCubit cubit) => cubit.getAllSavedPosts(), + expect: () => [isA()], + ); + // Test if mapping from Json to model is correct + group('Model test', () { + test('Discover Page Model is generated correctly', () { + SavedPostsModelling savedPostsModelling = SavedPostsModelling(); + savedPostsModelling.datafromJson(postsListFromWebServices); + List? postsListFromModelling = + savedPostsModelling.savedPosts; + expect( + postsListFromModelling![0], + savedPostsListFromRepository![0], + ); + expect( + postsListFromModelling[1], + savedPostsListFromRepository[1], + ); + }); + }); + }); +} diff --git a/reddit/test/sent_test.dart b/reddit/test/sent_test.dart new file mode 100644 index 00000000..d91ef07f --- /dev/null +++ b/reddit/test/sent_test.dart @@ -0,0 +1,118 @@ +import 'dart:convert'; + +import 'package:bloc_test/bloc_test.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:reddit/business_logic/cubit/cubit/saved_posts_cubit.dart'; +import 'package:reddit/data/model/saved_posts_model.dart'; +import 'package:reddit/data/repository/saved_posts_repo.dart'; +import 'package:reddit/data/web_services/saved_posts_web_services.dart'; + +class MockDiscoverPageWebService extends Mock implements SavedPostsWebServices { +} + +class MockFDiscoverPagesCubit extends MockCubit + implements SavedPostsCubit {} + +void main() async { + late MockDiscoverPageWebService mockDiscoverPageWebService; + late SavedPostsRepository savedPostsRepository; + late SavedPostsCubit savedPostsCubit; + final Map>> postsListFromWebServices = { + "data": [ + { + "text": "First Post", + "_id": "1", + "commentCount": 300, + "title": "In The Name Of Allah", + "publishedDate": "2023-1-21", + "votesCount": 777, + "subredditInfo": {"name": "ElRayes_Group", "id": "1"}, + "user": { + "username": "Omar_Khaled_2001", + "photo": "/assets/icon/reddit.png", + "id": "1" + } + }, + { + "text": "string", + "_id": "string", + "commentCount": 0, + "title": "string", + "publishedDate": "2022-12-23T17:34:12.984Z", + "votesCount": 0, + "subredditInfo": {"name": "string", "id": "string"}, + "user": {"username": "string", "photo": "string", "id": "string"} + } + ] + }; + + final List savedPostsListFromRepository = [ + SavedPostsModel( + id: "1", + text: "First Post", + commentCount: 300, + title: "In The Name Of Allah", + publishedDate: "2023-1-21", + subredditId: "1", + subredditName: "ElRayes_Group", + votesCount: 777, + userName: "Omar_Khaled_2001", + userPhoto: "/assets/icon/reddit.png", + userId: "1"), + SavedPostsModel( + id: "string", + text: "string", + commentCount: 0, + title: "string", + publishedDate: "2022-12-23T17:34:12.984Z", + subredditId: "string", + subredditName: "string", + votesCount: 0, + userName: "string", + userPhoto: "string", + userId: "string"), + ]; + + group("State test", () { + setUp(() { + mockDiscoverPageWebService = MockDiscoverPageWebService(); + savedPostsRepository = SavedPostsRepository( + savedPostsWebServices: mockDiscoverPageWebService); + savedPostsCubit = SavedPostsCubit(savedPostsRepository); + }); + // Calling getfDiscoverPages() function returns the correct state + // fDiscoverPagesLoading means that the request is sent and we are waiting for the response + // fDiscoverPagesLoaded means that the response is received and UI is built based on this responce + blocTest( + 'Random Posts loaded state is emitted correctly after getting Random Posts data from server', + setUp: () { + when(() => mockDiscoverPageWebService.getAllSavedPosts()).thenAnswer( + (_) async => postsListFromWebServices, + ); + }, + build: () { + return savedPostsCubit; + }, + act: (SavedPostsCubit cubit) => cubit.getAllSavedPosts(), + expect: () => [isA()], + ); + // Test if mapping from Json to model is correct + group('Model test', () { + test('Discover Page Model is generated correctly', () { + SavedPostsModelling savedPostsModelling = SavedPostsModelling(); + savedPostsModelling.datafromJson(postsListFromWebServices); + List? postsListFromModelling = + savedPostsModelling.savedPosts; + expect( + postsListFromModelling![0], + savedPostsListFromRepository[0], + ); + expect( + postsListFromModelling[1], + savedPostsListFromRepository[1], + ); + }); + }); + }); +}