diff --git a/lib/pangea/pages/find_partner/find_partner.dart b/lib/pangea/pages/find_partner/find_partner.dart index 18fc71307..f2bd7e8c1 100644 --- a/lib/pangea/pages/find_partner/find_partner.dart +++ b/lib/pangea/pages/find_partner/find_partner.dart @@ -1,9 +1,10 @@ import 'dart:async'; -import 'package:flutter/material.dart'; - +import 'package:country_picker/country_picker.dart'; import 'package:fluffychat/pangea/models/language_model.dart'; import 'package:fluffychat/pangea/models/user_model.dart'; +import 'package:flutter/material.dart'; + import '../../../widgets/matrix.dart'; import '../../controllers/pangea_controller.dart'; import '../../models/user_profile_search_model.dart'; @@ -20,6 +21,7 @@ class FindPartner extends StatefulWidget { class FindPartnerController extends State { PangeaController pangeaController = MatrixState.pangeaController; + bool initialLoad = true; bool loading = false; String currentSearchTerm = ""; late LanguageModel targetLanguageSearch; @@ -28,12 +30,15 @@ class FindPartnerController extends State { String? flagEmoji; //PTODO - implement pagination - String? previousPage; + String? nextUrl = ""; + int nextPage = 1; Timer? coolDown; final List _userProfilesCache = []; + final scrollController = ScrollController(); + @override void initState() { targetLanguageSearch = pangeaController.languageController.userL1 ?? @@ -41,31 +46,29 @@ class FindPartnerController extends State { sourceLanguageSearch = pangeaController.languageController.userL2 ?? pangeaController.pLanguageStore.targetOptions[0]; - searchUserProfiles(); + scrollController.addListener(() { + if (scrollController.position.pixels == + scrollController.position.maxScrollExtent) { + searchUserProfiles(); + } + }); + + searchUserProfiles().then((_) => setState(() => initialLoad = false)); + super.initState(); } + @override + void dispose() { + scrollController.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return FindPartnerView(this); } - // List get userProfiles => currentSearchTerm.isNotEmpty - // ? _userProfilesCache - // .where((p) => - // (p.fullName != null && p.fullName!.contains(currentSearchTerm)) || - // (p.pangeaUserId != null && - // p.pangeaUserId!.contains(currentSearchTerm)) || - // (p.sourceLanguage != null && - // p.sourceLanguage!.contains(currentSearchTerm)) || - // // (p.speaks != null && - // // p.speaks!.any((e) => e.contains(currentSearchTerm))) || - // (p.country != null && p.country!.contains(currentSearchTerm)) || - // // (p.interests != null && - // // p.interests!.any((e) => e.contains(currentSearchTerm)))) - // .toList() - // : _userProfilesCache; - List get userProfiles => _userProfilesCache.where((p) { return (p.targetLanguage != null && targetLanguageSearch.langCode == p.targetLanguage) && @@ -83,9 +86,9 @@ class FindPartnerController extends State { ); } - void searchUserProfiles() async { + Future searchUserProfiles() async { coolDown?.cancel(); - if (loading) return; + if (loading || nextUrl == null) return; setState(() => loading = true); final UserProfileSearchResponse response = @@ -94,15 +97,51 @@ class FindPartnerController extends State { targetLanguage: targetLanguageSearch.langCode, sourceLanguage: sourceLanguageSearch.langCode, country: countrySearch, - limit: 30, + limit: 15, + pageNumber: nextPage.toString(), + ); + + nextUrl = response.next; + nextPage++; + + final String? currentUserId = + pangeaController.userController.userModel?.profile?.pangeaUserId; + _userProfilesCache.addAll( + response.results.where( + (p) => + !_userProfilesCache.any( + (element) => p.pangeaUserId == element.pangeaUserId, + ) && + p.pangeaUserId != currentUserId, + ), ); - for (final p in response.results) { - if (!_userProfilesCache - .any((element) => p.pangeaUserId == element.pangeaUserId)) { - _userProfilesCache.add(p); - } - } setState(() => loading = false); } + + Future filterUserProfiles({ + LanguageModel? targetLanguage, + LanguageModel? sourceLanguage, + Country? country, + }) async { + if (country != null) { + if (country.name != "World Wide") { + countrySearch = country.displayNameNoCountryCode; + flagEmoji = country.flagEmoji; + } else { + countrySearch = null; + flagEmoji = null; + } + } + if (targetLanguage != null) { + targetLanguageSearch = targetLanguage; + } + if (sourceLanguage != null) { + sourceLanguageSearch = sourceLanguage; + } + nextPage = 1; + nextUrl = ""; + await searchUserProfiles(); + setState(() {}); + } } diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart index bbb163a69..e404559ed 100644 --- a/lib/pangea/pages/find_partner/find_partner_view.dart +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -1,10 +1,4 @@ -import 'package:flutter/material.dart'; - import 'package:country_picker/country_picker.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart' as matrix; - import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pangea/models/user_model.dart'; import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; @@ -12,6 +6,11 @@ import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; import 'package:fluffychat/pangea/widgets/user_settings/p_language_dropdown.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart' as matrix; + import '../../../widgets/profile_bottom_sheet.dart'; import 'find_partner.dart'; @@ -80,15 +79,9 @@ class FindPartnerView extends StatelessWidget { context: context, showPhoneCode: false, onSelect: (Country country) { - if (country.name != "World Wide") { - controller.countrySearch = - country.displayNameNoCountryCode; - controller.flagEmoji = country.flagEmoji; - } else { - controller.countrySearch = null; - controller.flagEmoji = null; - } - controller.searchUserProfiles(); + controller.filterUserProfiles( + country: country, + ); }, ), ), @@ -97,16 +90,22 @@ class FindPartnerView extends StatelessWidget { ], ), ), - controller.loading + controller.initialLoad ? const ExpandedContainer(body: ListPlaceholder()) : controller.userProfiles.isNotEmpty ? ExpandedContainer( body: ListView.builder( - itemCount: controller.userProfiles.length, - itemBuilder: (context, i) => UserProfileEntry( - pangeaProfile: controller.userProfiles[i], - controller: controller, - ), + controller: controller.scrollController, + itemCount: controller.userProfiles.length + 1, + itemBuilder: (context, i) => i != + controller.userProfiles.length + ? UserProfileEntry( + pangeaProfile: controller.userProfiles[i], + controller: controller, + ) + : controller.loading + ? const CircularProgressIndicator.adaptive() + : const SizedBox.shrink(), ), ) : ExpandedContainer( @@ -160,7 +159,7 @@ class ProfileSearchTextField extends StatelessWidget { maxHeight: 48, minWidth: 48, ), - suffixIcon: controller.loading + suffixIcon: controller.initialLoad ? const CircularProgressIndicator.adaptive() : const Icon(Icons.search_outlined), contentPadding: const EdgeInsets.symmetric(horizontal: 16), @@ -225,10 +224,10 @@ class LanguageSelectionRow extends StatelessWidget { ? controller.pangeaController.pLanguageStore.baseOptions : controller.pangeaController.pLanguageStore.targetOptions, onChange: (language) { - isSource - ? controller.sourceLanguageSearch = language - : controller.targetLanguageSearch = language; - controller.searchUserProfiles(); + controller.filterUserProfiles( + sourceLanguage: isSource ? language : null, + targetLanguage: isSource ? null : language, + ); }, initialLanguage: isSource ? controller.sourceLanguageSearch diff --git a/lib/pangea/repo/user_repo.dart b/lib/pangea/repo/user_repo.dart index 452120962..76b4104fc 100644 --- a/lib/pangea/repo/user_repo.dart +++ b/lib/pangea/repo/user_repo.dart @@ -1,9 +1,9 @@ import 'dart:convert'; import 'dart:developer'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; import 'package:http/http.dart'; -import 'package:fluffychat/pangea/constants/model_keys.dart'; import '../../widgets/matrix.dart'; import '../models/user_model.dart'; import '../models/user_profile_search_model.dart'; @@ -106,14 +106,12 @@ class PUserRepo { body[ModelKey.userSourceLanguage] = sourceLanguage; } if (country != null) body[ModelKey.userCountry] = country; - // if (speaks != null) body[ModelKey.userSpeaks] = speaks; - if (pageNumber != null) { - body["page_number"] = pageNumber; - } - body["limit"] = limit; + + final String searchUrl = + "${PApiUrls.searchUserProfiles}?limit=$limit${pageNumber != null ? '&page=$pageNumber' : ''}"; final Response res = await req.post( - url: PApiUrls.searchUserProfiles, + url: searchUrl, body: body, ); diff --git a/pubspec.lock b/pubspec.lock index c5c084469..c60c51ceb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: "direct main" description: name: country_picker - sha256: "931454ceb75c7e1230ac5620bfe601a5a293b4436d8de8bf7fea776a05a9568c" + sha256: c578292d7d3ec3132c6634f9c7aab96528f74d61fd363073d5f5a8562bede732 url: "https://pub.dev" source: hosted - version: "2.0.22" + version: "2.0.23" cross_file: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8a788363b..b100ba398 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ dependencies: chewie: ^1.7.1 collection: ^1.17.2 connectivity_plus: ^3.0.2 - country_picker: ^2.0.20 + country_picker: ^2.0.23 csv: ^5.0.2 cupertino_icons: any desktop_drop: ^0.4.4