Skip to content

Commit 34640e8

Browse files
feat: ✨ Add Pin/Mute Icon in ChatViewList
- Provided timestamp in last message time builder - Provided chat data in profile avatar, chat & trailing builders
1 parent ac9b456 commit 34640e8

File tree

15 files changed

+271
-121
lines changed

15 files changed

+271
-121
lines changed

example/lib/chat_view_list_screen.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class _ChatViewListScreenState extends State<ChatViewListScreen> {
5757
enablePagination: true,
5858
loadMoreConfig: const LoadMoreConfig(),
5959
tileConfig: ListTileConfig(
60+
pinIconConfig: const PinIconConfig(),
61+
muteIconConfig: const MuteIconConfig(),
6062
typingStatusConfig: const TypingStatusConfig(
6163
showUserNames: true,
6264
),

lib/src/extensions/extensions.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ extension ChatViewStateTitleExtension on String? {
153153
}
154154

155155
extension type const TypingStatusConfigExtension(TypingStatusConfig config) {
156-
String toTypingStatus(List<String> users) {
156+
String toTypingStatus(List<ChatUser> users) {
157157
final prefix = config.prefix ?? '';
158158
final suffix = config.suffix ?? '';
159159
final showUserNames = config.showUserNames;
@@ -163,20 +163,20 @@ extension type const TypingStatusConfigExtension(TypingStatusConfig config) {
163163

164164
final count = users.length;
165165

166-
final firstName = users[0];
166+
final firstName = users[0].name;
167167

168168
if (count == 1) {
169169
return '$firstName ${locale.isVerb} $text';
170170
} else if (count == 2) {
171171
final newText = showUserNames
172-
? '$firstName & ${users[1]} ${locale.areVerb}'
172+
? '$firstName & ${users[1].name} ${locale.areVerb}'
173173
: '$firstName & 1 ${locale.other} ${locale.isVerb}';
174174
return '$newText $text';
175175
} else if (showUserNames && count == 3) {
176-
return '${users[0]}, ${users[1]} & ${users[2]} ${locale.areVerb} $text';
176+
return '$firstName, ${users[1].name} & ${users[2].name} ${locale.areVerb} $text';
177177
} else {
178178
final newText = showUserNames
179-
? '$firstName, ${users[1]} & ${count - 2}'
179+
? '$firstName, ${users[1].name} & ${count - 2}'
180180
: '$firstName & ${count - 1}';
181181
return '$newText ${locale.others} ${locale.areVerb} $text';
182182
}

lib/src/models/chat_view_list_item.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import 'package:chatview_utils/chatview_utils.dart';
2323

2424
import '../values/enumeration.dart';
2525
import '../values/typedefs.dart';
26+
import 'config_models/chat_view_list/chat_settings.dart';
2627
import 'omit.dart';
2728

2829
/// Model class representing a user or group in the chat list.
@@ -32,8 +33,9 @@ class ChatViewListItem {
3233
required this.id,
3334
required this.name,
3435
this.chatType = ChatType.user,
35-
this.typingUsers = const <String>{},
36+
this.typingUsers = const <ChatUser>{},
3637
this.userActiveStatus = UserActiveStatus.offline,
38+
this.settings = const ChatSettings(),
3739
this.lastMessage,
3840
this.imageUrl,
3941
this.unreadCount,
@@ -64,16 +66,19 @@ class ChatViewListItem {
6466
/// Defaults to [UserActiveStatus.offline].
6567
final UserActiveStatus userActiveStatus;
6668

67-
// TODO(YASH): Switch to User Object instead of string.
6869
/// Set of users currently typing in the chat.
69-
final Set<String> typingUsers;
70+
final Set<ChatUser> typingUsers;
71+
72+
/// Settings for the chat list view.
73+
final ChatSettings settings;
7074

7175
ChatViewListItem copyWith({
7276
Defaulted<String> id = const Omit(),
7377
Defaulted<String> name = const Omit(),
7478
Defaulted<ChatType> chatType = const Omit(),
75-
Defaulted<Set<String>> typingUsers = const Omit(),
79+
Defaulted<Set<ChatUser>> typingUsers = const Omit(),
7680
Defaulted<UserActiveStatus> userActiveStatus = const Omit(),
81+
Defaulted<ChatSettings> settings = const Omit(),
7782
Defaulted<Message>? lastMessage = const Omit(),
7883
Defaulted<String>? imageUrl = const Omit(),
7984
Defaulted<int>? unreadCount = const Omit(),
@@ -83,10 +88,11 @@ class ChatViewListItem {
8388
name: name is Omit ? this.name : name as String,
8489
chatType: chatType is Omit ? this.chatType : chatType as ChatType,
8590
typingUsers:
86-
typingUsers is Omit ? this.typingUsers : typingUsers as Set<String>,
91+
typingUsers is Omit ? this.typingUsers : typingUsers as Set<ChatUser>,
8792
userActiveStatus: userActiveStatus is Omit
8893
? this.userActiveStatus
8994
: userActiveStatus as UserActiveStatus,
95+
settings: settings is Omit ? this.settings : settings as ChatSettings,
9096
lastMessage:
9197
lastMessage is Omit ? this.lastMessage : lastMessage as Message?,
9298
imageUrl: imageUrl is Omit ? this.imageUrl : imageUrl as String?,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import '../../../values/enumeration.dart';
2+
import '../../../values/typedefs.dart';
3+
import '../../omit.dart';
4+
5+
class ChatSettings {
6+
const ChatSettings({
7+
this.muteStatus = MuteStatus.unmute,
8+
this.pinStatus = PinStatus.unpinned,
9+
this.pinTime,
10+
});
11+
12+
final MuteStatus muteStatus;
13+
final PinStatus pinStatus;
14+
final DateTime? pinTime;
15+
16+
ChatSettings copyWith({
17+
Defaulted<MuteStatus> muteStatus = const Omit(),
18+
Defaulted<PinStatus> pinStatus = const Omit(),
19+
Defaulted<DateTime>? pinTime = const Omit(),
20+
}) {
21+
return ChatSettings(
22+
muteStatus:
23+
muteStatus is Omit ? this.muteStatus : muteStatus as MuteStatus,
24+
pinStatus: pinStatus is Omit ? this.pinStatus : pinStatus as PinStatus,
25+
pinTime: pinTime is Omit ? this.pinTime : pinTime as DateTime?,
26+
);
27+
}
28+
}

lib/src/models/config_models/chat_view_list/last_message_time_config.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import 'package:flutter/material.dart';
2323

2424
import '../../../utils/constants/constants.dart';
25+
import '../../../values/typedefs.dart';
2526

2627
class LastMessageTimeConfig {
2728
const LastMessageTimeConfig({
@@ -30,6 +31,7 @@ class LastMessageTimeConfig {
3031
this.dateFormatPattern = defaultDateFormat,
3132
this.spaceBetweenTimeAndUnreadCount = 5,
3233
this.textStyle,
34+
this.timeBuilder,
3335
});
3436

3537
/// Maximum number of lines for the last message time in the chat list.
@@ -54,4 +56,6 @@ class LastMessageTimeConfig {
5456
///
5557
/// Defaults to `5.0`.
5658
final double spaceBetweenTimeAndUnreadCount;
59+
60+
final LastMessageTimeBuilder? timeBuilder;
5761
}

lib/src/models/config_models/chat_view_list/list_tile_config.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import '../../../values/typedefs.dart';
2525
import '../../chat_view_list_item.dart';
2626
import 'last_message_time_config.dart';
2727
import 'list_type_indicator_config.dart';
28+
import 'mute_icon_config.dart';
29+
import 'pin_icon_config.dart';
2830
import 'unread_count_config.dart';
2931
import 'user_active_status_config.dart';
3032
import 'user_avatar_config.dart';
@@ -34,6 +36,8 @@ class ListTileConfig {
3436
/// Creates a configuration object for the user widget in the chat list UI.
3537
const ListTileConfig({
3638
this.showOnlineStatus = true,
39+
this.muteIconConfig = const MuteIconConfig(),
40+
this.pinIconConfig = const PinIconConfig(),
3741
this.timeConfig = const LastMessageTimeConfig(),
3842
this.userAvatarConfig = const UserAvatarConfig(),
3943
this.unreadCountConfig = const UnreadCountConfig(),
@@ -50,13 +54,21 @@ class ListTileConfig {
5054
this.onTap,
5155
this.onLongPress,
5256
this.lastMessageTileBuilder,
57+
this.userNameBuilder,
58+
this.trailingBuilder,
5359
});
5460

5561
/// Padding around the widget in the chat list.
5662
///
5763
/// Defaults to `EdgeInsets.symmetric(vertical: 6, horizontal: 8)`.
5864
final EdgeInsets padding;
5965

66+
/// Custom widget builder for the user name in the chat list.
67+
final UserNameBuilder? userNameBuilder;
68+
69+
/// Custom widget builder for the trailing widget in the chat list.
70+
final TrailingBuilder? trailingBuilder;
71+
6072
/// Text styles for various text elements in the user widget.
6173
final TextStyle? userNameTextStyle;
6274

@@ -119,4 +131,10 @@ class ListTileConfig {
119131

120132
/// Configuration for the typing status indicator in the chat list.
121133
final TypingStatusConfig typingStatusConfig;
134+
135+
/// Configuration for the mute icon in the chat list.
136+
final MuteIconConfig muteIconConfig;
137+
138+
/// Configuration for the pin icon in the chat list.
139+
final PinIconConfig pinIconConfig;
122140
}

lib/src/models/config_models/chat_view_list/models.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020
* SOFTWARE.
2121
*/
22+
export 'chat_settings.dart';
2223
export 'chat_view_list_config.dart';
2324
export 'list_tile_config.dart';
2425
export 'last_message_time_config.dart';
2526
export 'list_type_indicator_config.dart';
2627
export 'load_more_config.dart';
28+
export 'mute_icon_config.dart';
29+
export 'pin_icon_config.dart';
2730
export 'search_config.dart';
2831
export 'unread_count_config.dart';
2932
export 'user_active_status_config.dart';
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import 'package:flutter/widgets.dart';
2+
3+
class MuteIconConfig {
4+
const MuteIconConfig({
5+
this.size = 18,
6+
this.widget,
7+
this.color,
8+
});
9+
10+
final Widget? widget;
11+
final double? size;
12+
final Color? color;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import 'package:flutter/widgets.dart';
2+
3+
class PinIconConfig {
4+
const PinIconConfig({
5+
this.size = 18,
6+
this.widget,
7+
this.color,
8+
});
9+
10+
final Widget? widget;
11+
final double? size;
12+
final Color? color;
13+
}

lib/src/models/config_models/chat_view_list/user_avatar_config.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class UserAvatarConfig {
1212
this.backgroundColor,
1313
this.onBackgroundImageError,
1414
this.onProfileTap,
15+
this.avatarBuilder,
1516
});
1617

1718
/// Radius for the circle avatar in the profile widget.
@@ -27,4 +28,7 @@ class UserAvatarConfig {
2728

2829
/// Callback function that is called when the profile widget is tapped.
2930
final ValueSetter<ChatViewListItem>? onProfileTap;
31+
32+
/// Builder function to create a custom avatar widget.
33+
final UserAvatarBuilder? avatarBuilder;
3034
}

0 commit comments

Comments
 (0)