added pagination to find a convo partner page

pull/1011/head
ggurdin 2 years ago
parent c27c7396b6
commit 1bddef6874

@ -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<FindPartner> {
PangeaController pangeaController = MatrixState.pangeaController;
bool initialLoad = true;
bool loading = false;
String currentSearchTerm = "";
late LanguageModel targetLanguageSearch;
@ -28,12 +30,15 @@ class FindPartnerController extends State<FindPartner> {
String? flagEmoji;
//PTODO - implement pagination
String? previousPage;
String? nextUrl = "";
int nextPage = 1;
Timer? coolDown;
final List<Profile> _userProfilesCache = [];
final scrollController = ScrollController();
@override
void initState() {
targetLanguageSearch = pangeaController.languageController.userL1 ??
@ -41,31 +46,29 @@ class FindPartnerController extends State<FindPartner> {
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<Profile> 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<Profile> get userProfiles => _userProfilesCache.where((p) {
return (p.targetLanguage != null &&
targetLanguageSearch.langCode == p.targetLanguage) &&
@ -83,9 +86,9 @@ class FindPartnerController extends State<FindPartner> {
);
}
void searchUserProfiles() async {
Future<void> 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<FindPartner> {
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<void> 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(() {});
}
}

@ -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

@ -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,
);

@ -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:

@ -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

Loading…
Cancel
Save