added pagination to find a convo partner page
This commit is contained in:
parent
c27c7396b6
commit
1bddef6874
5 changed files with 101 additions and 65 deletions
|
|
@ -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…
Add table
Reference in a new issue