Browse Source

Begin adding pagination to messages, conversations, and friends

Friends needs some attention, due to accepted / non accepted requests
develop
Tovi Jaeschke-Rogers 2 years ago
parent
commit
71b242eaa0
12 changed files with 140 additions and 13 deletions
  1. +4
    -0
      Backend/Database/FriendRequests.go
  2. +2
    -2
      Backend/Database/Seeder/FriendSeeder.go
  3. +23
    -1
      Backend/Database/Seeder/UserSeeder.go
  4. +1
    -1
      Backend/Database/UserConversations.go
  5. +1
    -0
      README.md
  6. +19
    -4
      mobile/lib/services/conversations_service.dart
  7. +8
    -1
      mobile/lib/services/friends_service.dart
  8. +18
    -2
      mobile/lib/services/messages_service.dart
  9. +19
    -0
      mobile/lib/views/main/conversation/detail.dart
  10. +19
    -0
      mobile/lib/views/main/conversation/list.dart
  11. +6
    -2
      mobile/lib/views/main/conversation/list_item.dart
  12. +20
    -0
      mobile/lib/views/main/friend/list.dart

+ 4
- 0
Backend/Database/FriendRequests.go View File

@ -63,6 +63,10 @@ func GetFriendRequestsByUserID(userID string, page int, acceptedAt time.Time) ([
query = query. query = query.
Offset(offset). Offset(offset).
Limit(PageSize) Limit(PageSize)
if page > 0 {
query = query.Where("accepted_at IS NULL")
}
} }
err = query. err = query.


+ 2
- 2
Backend/Database/Seeder/FriendSeeder.go View File

@ -116,13 +116,13 @@ func SeedFriends() {
accepted = false accepted = false
for i = 0; i <= 5; i++ {
for i = 0; i < 25; i++ {
secondaryUser, err = Database.GetUserByUsername(userNames[i]) secondaryUser, err = Database.GetUserByUsername(userNames[i])
if err != nil { if err != nil {
panic(err) panic(err)
} }
if i > 3 {
if i > 7 {
accepted = true accepted = true
} }


+ 23
- 1
Backend/Database/Seeder/UserSeeder.go View File

@ -19,6 +19,28 @@ var userNames = []string{
"nodesanymore", "nodesanymore",
"sacredpolitical", "sacredpolitical",
"pajamasenergy", "pajamasenergy",
"Multiscience",
"Exequies",
"Nebulae",
"Synartesis",
"LinklingKaput",
"Gumption",
"Festooned",
"Ratatouille",
"VersusBoing",
"Jiggermast",
"Ambsase",
"Ard3pic",
"Smegma",
"Vaporiform",
"Agromania",
"GleetrAlgor",
"Zymurgy",
"Nipperkin",
"Thespian",
"Mewling",
"Scram",
"Fizgig",
} }
func createUser(username string) (Database.User, error) { func createUser(username string) (Database.User, error) {
@ -70,7 +92,7 @@ func SeedUsers() {
panic(err) panic(err)
} }
for i = 0; i <= 10; i++ {
for i = 0; i < len(userNames); i++ {
_, err = createUser(userNames[i]) _, err = createUser(userNames[i])
if err != nil { if err != nil {
panic(err) panic(err)


+ 1
- 1
Backend/Database/UserConversations.go View File

@ -45,8 +45,8 @@ func GetUserConversationsByUserId(id string, page int) ([]UserConversation, erro
err = DB.Offset(offset). err = DB.Offset(offset).
Limit(PageSize). Limit(PageSize).
Order("created_at DESC").
Find(&conversations, "user_id = ?", id). Find(&conversations, "user_id = ?", id).
Order("created_at DESC").
Error Error
return conversations, err return conversations, err


+ 1
- 0
README.md View File

@ -13,3 +13,4 @@ Encrypted messaging app
- Sort conversation based on latest message - Sort conversation based on latest message
- Fix admin bool on conversation object frontend - Fix admin bool on conversation object frontend
- Fix image picker being patchy on iOS - Fix image picker being patchy on iOS
- Fix being able to add friends > 1 times

+ 19
- 4
mobile/lib/services/conversations_service.dart View File

@ -111,11 +111,23 @@ class ConversationsService {
} }
} }
static Future<_BaseConversationsResult> _getBaseConversations() async {
static Future<_BaseConversationsResult> _getBaseConversations({
int page = 0
}) async {
RSAPrivateKey privKey = await MyProfile.getPrivateKey(); RSAPrivateKey privKey = await MyProfile.getPrivateKey();
Map<String, String> params = {};
if (page != 0) {
params['page'] = page.toString();
}
var uri = await MyProfile.getServerUrl('api/v1/auth/conversations');
uri = uri.replace(queryParameters: params);
http.Response resp = await http.get( http.Response resp = await http.get(
await MyProfile.getServerUrl('api/v1/auth/conversations'),
uri,
headers: { headers: {
'cookie': await getSessionCookie(), 'cookie': await getSessionCookie(),
} }
@ -225,8 +237,11 @@ class ConversationsService {
} }
} }
static Future<void> updateConversations({DateTime? updatedAt}) async {
_BaseConversationsResult baseConvs = await _getBaseConversations();
static Future<void> updateConversations({
int page = 0,
DateTime? updatedAt
}) async {
_BaseConversationsResult baseConvs = await _getBaseConversations(page: page);
if (baseConvs.detailIds.isEmpty) { if (baseConvs.detailIds.isEmpty) {
return; return;


+ 8
- 1
mobile/lib/services/friends_service.dart View File

@ -11,11 +11,18 @@ import '/utils/storage/database.dart';
import '/utils/storage/session_cookie.dart'; import '/utils/storage/session_cookie.dart';
class FriendsService { class FriendsService {
static Future<void> updateFriends({DateTime? acceptedAt}) async {
static Future<void> updateFriends({
int page = 0,
DateTime? acceptedAt
}) async {
RSAPrivateKey privKey = await MyProfile.getPrivateKey(); RSAPrivateKey privKey = await MyProfile.getPrivateKey();
Map<String, String> params = {}; Map<String, String> params = {};
if (page != 0) {
params['page'] = page.toString();
}
if (acceptedAt != null) { if (acceptedAt != null) {
params['updated_at'] = acceptedAt.toIso8601String(); params['updated_at'] = acceptedAt.toIso8601String();
} }


+ 18
- 2
mobile/lib/services/messages_service.dart View File

@ -127,12 +127,28 @@ class MessagesService {
}); });
} }
static Future<void> updateMessageThread(Conversation conversation, {MyProfile? profile}) async {
static Future<void> updateMessageThread(
Conversation conversation, {
int page = 0,
MyProfile? profile,
}) async {
profile ??= await MyProfile.getProfile(); profile ??= await MyProfile.getProfile();
ConversationUser currentUser = await ConversationUsersRepository.getConversationUser(conversation, profile.id); ConversationUser currentUser = await ConversationUsersRepository.getConversationUser(conversation, profile.id);
Map<String, String> params = {};
if (page != 0) {
params['page'] = page.toString();
}
print(page);
var uri = await MyProfile.getServerUrl('api/v1/auth/messages/${currentUser.associationKey}');
uri = uri.replace(queryParameters: params);
var resp = await http.get( var resp = await http.get(
await MyProfile.getServerUrl('api/v1/auth/messages/${currentUser.associationKey}'),
uri,
headers: { headers: {
'cookie': await getSessionCookie(), 'cookie': await getSessionCookie(),
} }


+ 19
- 0
mobile/lib/views/main/conversation/detail.dart View File

@ -25,6 +25,8 @@ class ConversationDetail extends StatefulWidget{
} }
class _ConversationDetailState extends State<ConversationDetail> { class _ConversationDetailState extends State<ConversationDetail> {
late ScrollController _scrollController;
List<Message> messages = []; List<Message> messages = [];
MyProfile profile = MyProfile( MyProfile profile = MyProfile(
@ -86,10 +88,26 @@ class _ConversationDetailState extends State<ConversationDetail> {
@override @override
void initState() { void initState() {
sendDisabled = widget.conversation.adminSendMessages && !widget.conversation.admin; sendDisabled = widget.conversation.adminSendMessages && !widget.conversation.admin;
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
super.initState(); super.initState();
fetchMessages(); fetchMessages();
} }
Future<void> _scrollListener() async {
if (!(_scrollController.offset >= _scrollController.position.maxScrollExtent)) {
return;
}
int page = 0;
if (messages.length > 19) {
page = messages.length ~/ 20;
}
await MessagesService.updateMessageThread(widget.conversation, page: page);
await fetchMessages();
}
Widget messagesView() { Widget messagesView() {
if (messages.isEmpty) { if (messages.isEmpty) {
return const Center( return const Center(
@ -98,6 +116,7 @@ class _ConversationDetailState extends State<ConversationDetail> {
} }
return ListView.builder( return ListView.builder(
controller: _scrollController,
itemCount: messages.length, itemCount: messages.length,
shrinkWrap: true, shrinkWrap: true,
padding: EdgeInsets.only( padding: EdgeInsets.only(


+ 19
- 0
mobile/lib/views/main/conversation/list.dart View File

@ -29,6 +29,7 @@ class ConversationList extends StatefulWidget {
class _ConversationListState extends State<ConversationList> { class _ConversationListState extends State<ConversationList> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>(); final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
late ScrollController _scrollController;
List<Conversation> conversations = []; List<Conversation> conversations = [];
List<Friend> friends = []; List<Friend> friends = [];
@ -148,6 +149,8 @@ class _ConversationListState extends State<ConversationList> {
@override @override
void initState() { void initState() {
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
super.initState(); super.initState();
conversations.addAll(widget.conversations); conversations.addAll(widget.conversations);
friends.addAll(widget.friends); friends.addAll(widget.friends);
@ -162,6 +165,7 @@ class _ConversationListState extends State<ConversationList> {
} }
return ListView.builder( return ListView.builder(
controller: _scrollController,
itemCount: conversations.length, itemCount: conversations.length,
shrinkWrap: false, shrinkWrap: false,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
@ -184,6 +188,21 @@ class _ConversationListState extends State<ConversationList> {
setState(() {}); setState(() {});
} }
Future<void> _scrollListener() async {
if (!(_scrollController.offset >= _scrollController.position.maxScrollExtent)) {
return;
}
int page = 0;
if (conversations.length > 19) {
page = conversations.length ~/ 20;
}
await ConversationsService.updateConversations(page: page);
onGoBack(null);
}
onGoBack(dynamic value) async { onGoBack(dynamic value) async {
conversations = await ConversationsRepository.getConversations(); conversations = await ConversationsRepository.getConversations();
friends = await FriendsRepository.getFriends(); friends = await FriendsRepository.getFriends();


+ 6
- 2
mobile/lib/views/main/conversation/list_item.dart View File

@ -110,11 +110,15 @@ class _ConversationListItemState extends State<ConversationListItem> {
conversation = widget.conversation; conversation = widget.conversation;
recentMessage = await conversation.getRecentMessage(); recentMessage = await conversation.getRecentMessage();
loaded = true; loaded = true;
setState(() {});
if (mounted) {
setState(() {});
}
} }
onGoBack(dynamic value) async { onGoBack(dynamic value) async {
conversation = await ConversationsRepository.getConversationById(widget.conversation.id); conversation = await ConversationsRepository.getConversationById(widget.conversation.id);
setState(() {});
if (mounted) {
setState(() {});
}
} }
} }

+ 20
- 0
mobile/lib/views/main/friend/list.dart View File

@ -26,6 +26,7 @@ class FriendList extends StatefulWidget {
class _FriendListState extends State<FriendList> { class _FriendListState extends State<FriendList> {
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>(); final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
late ScrollController _scrollController;
List<Friend> friends = []; List<Friend> friends = [];
List<Friend> friendsDuplicate = []; List<Friend> friendsDuplicate = [];
@ -130,6 +131,8 @@ class _FriendListState extends State<FriendList> {
@override @override
void initState() { void initState() {
_scrollController = ScrollController();
_scrollController.addListener(_scrollListener);
super.initState(); super.initState();
friends.addAll(widget.friends); friends.addAll(widget.friends);
} }
@ -164,6 +167,7 @@ class _FriendListState extends State<FriendList> {
} }
return ListView.separated( return ListView.separated(
controller: _scrollController,
itemCount: friends.length, itemCount: friends.length,
shrinkWrap: false, shrinkWrap: false,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
@ -204,4 +208,20 @@ class _FriendListState extends State<FriendList> {
friends = await FriendsRepository.getFriends(); friends = await FriendsRepository.getFriends();
setState(() {}); setState(() {});
} }
Future<void> _scrollListener() async {
if (!(_scrollController.offset >= _scrollController.position.maxScrollExtent)) {
return;
}
int page = 0;
if (friends.length > 19) {
page = friends.length ~/ 20;
}
await FriendsService.updateFriends(page: page);
friends = await FriendsRepository.getFriends();
setState(() {});
}
} }

Loading…
Cancel
Save