From 738808d48f231a49a1c09f1fbb617849e8f9ca75 Mon Sep 17 00:00:00 2001 From: Omer <56688420+omerfaunal@users.noreply.github.com> Date: Sat, 23 Dec 2023 19:11:32 +0300 Subject: [PATCH] 646 fe home page advanced nodes (#677) * New provider for getting nodes by type * Create node options menu buttons * Add buttons to home page --- .../lib/providers/node_provider.dart | 36 +++++++++++ .../lib/screens/home_page/home_page.dart | 60 +++++++++++++---- .../screens/home_page/mobile_home_page.dart | 5 ++ .../home_page/widgets/select_button.dart | 64 +++++++++++++++++++ .../home_page/widgets/select_buttons.dart | 47 ++++++++++++++ 5 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart create mode 100644 project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart diff --git a/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart b/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart index 5532ab0e..0bd21156 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart @@ -152,6 +152,42 @@ class NodeProvider with ChangeNotifier { } } + Future<void> getNodeByType(String queryType) async { + Uri url = Uri.parse("${Constants.apiUrl}/search/?type=$queryType"); + final Map<String, String> headers = { + "Accept": "application/json", + "content-type": "application/json" + }; + try { + final response = await http.get(url, headers: headers); + + if (response.statusCode == 200) { + final data = json.decode(response.body); + _searchNodeResult.clear(); + _searchNodeResult.addAll((data['nodes'] as List<dynamic>).map((node) => Node( + contributors: (node['authors'] as List<dynamic>) + .map((author) => User( + id: author['id'], + firstName: author['name'], + lastName: author['surname'], + email: author['username'])) + .toList(), + id: node['id'], + nodeTitle: node['title'], + publishDate: DateTime.parse(node['date']), + ))); + notifyListeners(); + } else if (response.statusCode == 400) { + throw SearchError(); + } else { + print(response); + throw Exception("Error"); + } + } catch (e) { + rethrow; + } + } + Future<void> getNodeSuggestions() async { await search(SearchType.theorem, "", random: true, suggestions: true); } diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart index 00de7d9f..ef533621 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart @@ -29,7 +29,7 @@ class _HomePageState extends State<HomePage> { @override void didChangeDependencies() { if (_firstTime) { - randomNodes(); + onTypeChange(0); _firstTime = false; } super.didChangeDependencies(); @@ -41,23 +41,25 @@ class _HomePageState extends State<HomePage> { super.dispose(); } - void randomNodes() async { + Future<void> onTypeChange(int index) async { + final nodeProvider = Provider.of<NodeProvider>(context, listen: false); + String type = ""; + if (index == 0) { + type = "trending"; + } else if (index == 1) { + type = "latest"; + } else if (index == 2) { + type = "most_read"; + } else if (index == 3) { + type = "random"; + } else if (index == 4) { + type = "for_you"; + } try { - final nodeProvider = Provider.of<NodeProvider>(context, listen: false); setState(() { isLoading = true; }); - await nodeProvider.search(SearchType.both, "", random: true); - } on WrongSearchTypeError { - setState(() { - error = true; - errorMessage = WrongSearchTypeError().message; - }); - } on SearchError { - setState(() { - error = true; - errorMessage = SearchError().message; - }); + await nodeProvider.getNodeByType(type); } catch (e) { setState(() { error = true; @@ -70,6 +72,35 @@ class _HomePageState extends State<HomePage> { } } + // void randomNodes() async { + // try { + // final nodeProvider = Provider.of<NodeProvider>(context, listen: false); + // setState(() { + // isLoading = true; + // }); + // await nodeProvider.search(SearchType.both, "", random: true); + // } on WrongSearchTypeError { + // setState(() { + // error = true; + // errorMessage = WrongSearchTypeError().message; + // }); + // } on SearchError { + // setState(() { + // error = true; + // errorMessage = SearchError().message; + // }); + // } catch (e) { + // setState(() { + // error = true; + // errorMessage = "Something went wrong!"; + // }); + // } finally { + // setState(() { + // isLoading = false; + // }); + // } + // } + void search(String text) async { if (text.isEmpty) return; if (text.length < 4) return; @@ -146,6 +177,7 @@ class _HomePageState extends State<HomePage> { return MobileHomePage( searchBarFocusNode: searchBarFocusNode, onSearch: search, + onTypeChange: onTypeChange, onSemanticSearch: semanticSearch, isLoading: isLoading, error: error, diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart index 9d860e7e..b8c343b3 100644 --- a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart @@ -3,6 +3,7 @@ import 'package:collaborative_science_platform/providers/node_provider.dart'; import 'package:collaborative_science_platform/providers/user_provider.dart'; import 'package:collaborative_science_platform/screens/home_page/widgets/home_page_appbar.dart'; import 'package:collaborative_science_platform/screens/home_page/widgets/node_cards.dart'; +import 'package:collaborative_science_platform/screens/home_page/widgets/select_buttons.dart'; import 'package:collaborative_science_platform/screens/home_page/widgets/user_cards.dart'; import 'package:collaborative_science_platform/screens/page_with_appbar/page_with_appbar.dart'; import 'package:collaborative_science_platform/utils/responsive/responsive.dart'; @@ -14,6 +15,7 @@ import 'package:provider/provider.dart'; class MobileHomePage extends StatelessWidget { final FocusNode searchBarFocusNode; final Function onSearch; + final Function onTypeChange; final Function onSemanticSearch; final bool isLoading; final bool error; @@ -23,6 +25,7 @@ class MobileHomePage extends StatelessWidget { super.key, required this.searchBarFocusNode, required this.onSearch, + required this.onTypeChange, required this.onSemanticSearch, required this.isLoading, required this.error, @@ -52,6 +55,8 @@ class MobileHomePage extends StatelessWidget { desktop: SearchBarExtended(exactSearch: onSearch, semanticSearch: onSemanticSearch)), ), + const SizedBox(height: 10.0), + SelectButtons(onTypeChange), Padding( padding: const EdgeInsets.only(top: 10.0), child: isLoading diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart new file mode 100644 index 00000000..3158ffe4 --- /dev/null +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; + +class SelectButton extends StatefulWidget { + final int index; + final String name; + final bool selected; + final Function onPressed; + const SelectButton( + {required this.index, + required this.name, + required this.selected, + required this.onPressed, + super.key}); + + @override + State<SelectButton> createState() => _SelectButtonState(); +} + +class _SelectButtonState extends State<SelectButton> { + bool isHovering = false; + @override + Widget build(BuildContext context) { + return MouseRegion( + cursor: SystemMouseCursors.click, + onEnter: (event) => setState(() => isHovering = true), + onExit: (event) => setState(() => isHovering = false), + child: GestureDetector( + onTap: () { + widget.onPressed(widget.index); + }, + child: Container( + height: 35, + width: 90, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(6), + color: widget.selected + ? Colors.indigo[600] + : isHovering + ? Colors.indigo[200] + : Colors.grey[200], + ), + padding: const EdgeInsets.all(10), + margin: const EdgeInsets.only(right: 8), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SelectionContainer.disabled( + child: Text( + widget.name, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: widget.selected ? Colors.white : Colors.grey[700]), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart new file mode 100644 index 00000000..4c9ea42f --- /dev/null +++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart @@ -0,0 +1,47 @@ +import 'package:collaborative_science_platform/screens/home_page/widgets/select_button.dart'; +import 'package:flutter/material.dart'; + +class SelectButtons extends StatefulWidget { + final Function onTypeChange; + const SelectButtons(this.onTypeChange, {super.key}); + + @override + State<SelectButtons> createState() => _SelectButtonsState(); +} + +class _SelectButtonsState extends State<SelectButtons> { + int selectedIndex = 0; + + void selectOne(int index) async { + setState(() { + selectedIndex = index; + }); + widget.onTypeChange(index); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SelectButton( + index: 0, name: "Trending", selected: selectedIndex == 0, onPressed: selectOne), + const SizedBox(width: 10.0), + SelectButton(index: 1, name: "Latest", selected: selectedIndex == 1, onPressed: selectOne), + const SizedBox(width: 10.0), + SelectButton( + index: 2, name: "Most Read", selected: selectedIndex == 2, onPressed: selectOne), + const SizedBox(width: 10.0), + SelectButton(index: 3, name: "Random", selected: selectedIndex == 3, onPressed: selectOne), + // if (Provider.of<Auth>(context).isSignedIn) + // Row( + // children: [ + // const SizedBox(width: 10.0), + // SelectButton( + // index: 4, name: "For You", selected: selectedIndex == 4, onPressed: selectOne), + // ], + // ), + ], + ); + } +}