diff --git a/lib/src/components/best_friends_selector.dart b/lib/src/components/best_friends_selector.dart index 6deb9b9..0ff7c40 100644 --- a/lib/src/components/best_friends_selector.dart +++ b/lib/src/components/best_friends_selector.dart @@ -2,6 +2,7 @@ import 'dart:collection'; import 'package:fixnum/fixnum.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:twonly/src/components/flame.dart'; import 'package:twonly/src/components/headline.dart'; import 'package:twonly/src/components/initialsavatar.dart'; import 'package:twonly/src/model/contacts_model.dart'; @@ -10,10 +11,12 @@ class BestFriendsSelector extends StatelessWidget { final List users; final Function(Int64, bool) updateStatus; final HashSet selectedUserIds; + final int maxTotalMediaCounter; const BestFriendsSelector({ super.key, required this.users, + required this.maxTotalMediaCounter, required this.updateStatus, required this.selectedUserIds, }); @@ -24,14 +27,13 @@ class BestFriendsSelector extends StatelessWidget { return Container(); } - final limitedUsers = users.length > 8 ? users.sublist(0, 8) : users; return Column( children: [ HeadLineComponent(AppLocalizations.of(context)!.shareImageBestFriends), Column( spacing: 8, children: List.generate( - (limitedUsers.length + 1) ~/ 2, + (users.length + 1) ~/ 2, (rowIndex) { final firstUserIndex = rowIndex * 2; final secondUserIndex = firstUserIndex + 1; @@ -41,19 +43,20 @@ class BestFriendsSelector extends StatelessWidget { Expanded( child: UserCheckbox( isChecked: selectedUserIds - .contains(limitedUsers[firstUserIndex].userId), - user: limitedUsers[firstUserIndex], + .contains(users[firstUserIndex].userId), + user: users[firstUserIndex], onChanged: updateStatus, + maxTotalMediaCounter: maxTotalMediaCounter, ), ), - (secondUserIndex < limitedUsers.length) + (secondUserIndex < users.length) ? Expanded( child: UserCheckbox( - isChecked: selectedUserIds - .contains(limitedUsers[secondUserIndex].userId), - user: limitedUsers[secondUserIndex], - onChanged: updateStatus, - ), + isChecked: selectedUserIds + .contains(users[secondUserIndex].userId), + user: users[secondUserIndex], + onChanged: updateStatus, + maxTotalMediaCounter: maxTotalMediaCounter), ) : Expanded( child: Container(), @@ -72,10 +75,12 @@ class UserCheckbox extends StatelessWidget { final Contact user; final Function(Int64, bool) onChanged; final bool isChecked; + final int maxTotalMediaCounter; const UserCheckbox({ super.key, required this.user, + required this.maxTotalMediaCounter, required this.onChanged, required this.isChecked, }); @@ -105,14 +110,15 @@ class UserCheckbox extends StatelessWidget { displayName: user.displayName, ), SizedBox(width: 8), - Expanded( - child: Text( - user.displayName.length > 10 - ? '${user.displayName.substring(0, 10)}...' - : user.displayName, - overflow: TextOverflow.ellipsis, - ), + Text( + user.displayName.length > 10 + ? '${user.displayName.substring(0, 10)}...' + : user.displayName, + overflow: TextOverflow.ellipsis, ), + if (user.flameCounter > 0) + FlameCounterWidget(user, maxTotalMediaCounter), + Expanded(child: Container()), Checkbox( value: isChecked, onChanged: (bool? value) { diff --git a/lib/src/components/flame.dart b/lib/src/components/flame.dart new file mode 100644 index 0000000..62a166b --- /dev/null +++ b/lib/src/components/flame.dart @@ -0,0 +1,32 @@ +import 'package:flutter/material.dart'; +import 'package:twonly/src/model/contacts_model.dart'; + +class FlameCounterWidget extends StatelessWidget { + final Contact user; + final int maxTotalMediaCounter; + + const FlameCounterWidget( + this.user, + this.maxTotalMediaCounter, { + super.key, + }); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + const SizedBox(width: 5), + Text("•"), + const SizedBox(width: 5), + Text( + user.flameCounter.toString(), + style: const TextStyle(fontSize: 12), + ), + Text( + (maxTotalMediaCounter == user.totalMediaCounter) ? "❤️‍🔥" : "🔥", + style: const TextStyle(fontSize: 10), + ), + ], + ); + } +} diff --git a/lib/src/views/chat_list_view.dart b/lib/src/views/chat_list_view.dart index 54199a6..e76a5d3 100644 --- a/lib/src/views/chat_list_view.dart +++ b/lib/src/views/chat_list_view.dart @@ -2,6 +2,7 @@ import 'dart:math'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; +import 'package:twonly/src/components/flame.dart'; import 'package:twonly/src/components/initialsavatar.dart'; import 'package:twonly/src/components/message_send_state_icon.dart'; import 'package:twonly/src/components/notification_badge.dart'; @@ -187,25 +188,7 @@ class _UserListItem extends State { style: TextStyle(fontSize: 12), ), if (widget.user.flameCounter > 0) - Row( - children: [ - const SizedBox(width: 5), - Text("•"), - const SizedBox(width: 5), - Text( - widget.user.flameCounter.toString(), - style: TextStyle(fontSize: 12), - ), - const SizedBox(width: 3), - Text( - (widget.maxTotalMediaCounter == - widget.user.totalMediaCounter) - ? "❤️‍🔥" - : "🔥", - style: TextStyle(fontSize: 10), - ) - ], - ), + FlameCounterWidget(widget.user, widget.maxTotalMediaCounter), ], ), leading: InitialsAvatar(displayName: widget.user.displayName), diff --git a/lib/src/views/share_image_view.dart b/lib/src/views/share_image_view.dart index 35874ef..ee16c74 100644 --- a/lib/src/views/share_image_view.dart +++ b/lib/src/views/share_image_view.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/components/best_friends_selector.dart'; +import 'package:twonly/src/components/flame.dart'; import 'package:twonly/src/components/headline.dart'; import 'package:twonly/src/components/initialsavatar.dart'; import 'package:twonly/src/model/contacts_model.dart'; @@ -21,7 +22,9 @@ class ShareImageView extends StatefulWidget { class _ShareImageView extends State { List _users = []; - List _usersFiltered = []; + List _otherUsers = []; + List _bestFriends = []; + int maxTotalMediaCounter = 0; final HashSet _selectedUserIds = HashSet(); String _lastSearchQuery = ''; final TextEditingController searchUserName = TextEditingController(); @@ -36,26 +39,57 @@ class _ShareImageView extends State { final users = await DbContacts.getActiveUsers(); setState(() { _users = users; - _usersFiltered = _users; + _updateUsers(_users); + }); + } + + Future _updateUsers(List users) async { + // Sort contacts by flameCounter and then by totalMediaCounter + users.sort((a, b) { + // First, compare by flameCounter + int flameComparison = b.flameCounter.compareTo(a.flameCounter); + if (flameComparison != 0) { + return flameComparison; // Sort by flameCounter in descending order + } + // If flameCounter is the same, compare by totalMediaCounter + return b.totalMediaCounter.compareTo( + a.totalMediaCounter); // Sort by totalMediaCounter in descending order + }); + + maxTotalMediaCounter = 0; + if (users.isNotEmpty) { + maxTotalMediaCounter = + users.map((x) => x.totalMediaCounter).reduce((a, b) => a > b ? a : b); + } + + // Separate best friends and other users + List bestFriends = []; + List otherUsers = []; + + for (var contact in users) { + if (contact.flameCounter > 0 && bestFriends.length < 6) { + bestFriends.add(contact); + } else { + otherUsers.add(contact); + } + } + + setState(() { + _bestFriends = bestFriends; + _otherUsers = otherUsers; }); } Future _filterUsers(String query) async { if (query.isEmpty) { - _usersFiltered = _users; + _updateUsers(_users); return; } - if (_lastSearchQuery.length < query.length) { - _usersFiltered = _users - .where((user) => - user.displayName.toLowerCase().contains(query.toLowerCase())) - .toList(); - } else { - _usersFiltered = _usersFiltered - .where((user) => - user.displayName.toLowerCase().contains(query.toLowerCase())) - .toList(); - } + List usersFiltered = _users + .where((user) => + user.displayName.toLowerCase().contains(query.toLowerCase())) + .toList(); + _updateUsers(usersFiltered); _lastSearchQuery = query; } @@ -77,8 +111,9 @@ class _ShareImageView extends State { AppLocalizations.of(context)!.searchUsernameInput))), const SizedBox(height: 10), BestFriendsSelector( - users: _usersFiltered, + users: _bestFriends, selectedUserIds: _selectedUserIds, + maxTotalMediaCounter: maxTotalMediaCounter, updateStatus: (userId, checked) { if (checked) { _selectedUserIds.add(userId); @@ -88,12 +123,13 @@ class _ShareImageView extends State { }, ), const SizedBox(height: 10), - if (_usersFiltered.isNotEmpty) + if (_otherUsers.isNotEmpty) HeadLineComponent( AppLocalizations.of(context)!.shareImageAllUsers), Expanded( child: UserList( - List.from(_usersFiltered), + List.from(_otherUsers), + maxTotalMediaCounter, selectedUserIds: _selectedUserIds, ), ) @@ -136,8 +172,10 @@ class _ShareImageView extends State { } class UserList extends StatelessWidget { - const UserList(this.users, {super.key, required this.selectedUserIds}); + const UserList(this.users, this.maxTotalMediaCounter, + {super.key, required this.selectedUserIds}); final List users; + final int maxTotalMediaCounter; final HashSet selectedUserIds; @override @@ -151,7 +189,11 @@ class UserList extends StatelessWidget { itemBuilder: (BuildContext context, int i) { Contact user = users[i]; return ListTile( - title: Text(user.displayName), + title: Row(children: [ + Text(user.displayName), + if (user.flameCounter > 0) + FlameCounterWidget(user, maxTotalMediaCounter), + ]), leading: InitialsAvatar( displayName: user.displayName, fontSize: 15,