Skip to content

Commit 0251846

Browse files
CubeRomanMagellanMagellan
andauthored
SK-644: Update the main screen with chats (#114)
* update date widget * update avatar color * update profile bloc --------- Co-authored-by: Magellan <magellan@connectycube.com>
1 parent 2ed0a0c commit 0251846

8 files changed

Lines changed: 95 additions & 76 deletions

File tree

sama_chat_client/lib/src/features/conversations_list/bloc/conversations_list_bloc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class ConversationsBloc extends Bloc<ConversationsEvent, ConversationsState> {
5252
add(ConversationsRefreshed());
5353

5454
if (state.typingStatuses.containsKey(chat.id)) {
55-
add(TypingStatusStopReceived(chat.id, chat.lastMessage!.from!));
55+
add(TypingStatusStopReceived(chat.id, chat.lastMessage!.from));
5656
}
5757
}
5858
});

sama_chat_client/lib/src/features/conversations_list/view/conversations_list.dart

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ class _ConversationsListState extends State<ConversationsList> with RouteAware {
2727
routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
2828
}
2929

30-
@override
31-
void didPopNext() {
32-
// TODO RP for now not using
33-
// context.read<ConversationsBloc>().add(ConversationsRefreshed());
34-
}
35-
3630
@override
3731
Widget build(BuildContext context) {
3832
return BlocBuilder<ConversationsBloc, ConversationsState>(

sama_chat_client/lib/src/features/conversations_list/widgets/avatar_group_icon.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ import '../../../db/models/avatar_model.dart';
44
import '../../../shared/ui/colors.dart';
55

66
class AvatarGroupIcon extends StatelessWidget {
7-
const AvatarGroupIcon(this.avatar, {super.key});
7+
const AvatarGroupIcon(this.avatar, this.name, {super.key});
88

99
final AvatarModel? avatar;
10+
final String name;
1011
final Size size = const Size(55, 60);
1112

1213
@override
1314
Widget build(BuildContext context) {
1415
return Container(
15-
decoration: const BoxDecoration(
16-
color: black,
16+
decoration: BoxDecoration(
17+
color: getAvatarColor(name),
1718
shape: BoxShape.circle,
1819
),
1920
height: size.height,

sama_chat_client/lib/src/features/conversations_list/widgets/avatar_letter_icon.dart

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

33
import '../../../db/models/avatar_model.dart';
44
import '../../../shared/ui/colors.dart';
5+
import '../../../shared/utils/string_utils.dart';
56

67
class AvatarLetterIcon extends StatelessWidget {
78
const AvatarLetterIcon({
@@ -10,8 +11,8 @@ class AvatarLetterIcon extends StatelessWidget {
1011
super.key,
1112
this.size = const Size(55, 55),
1213
this.padding = EdgeInsets.zero,
13-
this.backgroundColor = black,
14-
this.textColor = dullGray,
14+
this.backgroundColor,
15+
this.textColor = signalBlack,
1516
this.avatar,
1617
this.isDeleted,
1718
});
@@ -21,7 +22,7 @@ class AvatarLetterIcon extends StatelessWidget {
2122
final String? lastName;
2223
final Size size;
2324
final EdgeInsetsGeometry padding;
24-
final Color backgroundColor;
25+
final Color? backgroundColor;
2526
final Color textColor;
2627
final AvatarModel? avatar;
2728
final bool? isDeleted;
@@ -38,7 +39,9 @@ class AvatarLetterIcon extends StatelessWidget {
3839
Widget build(BuildContext context) {
3940
return Container(
4041
decoration: BoxDecoration(
41-
color: backgroundColor,
42+
color: isDeleted ?? false
43+
? black
44+
: backgroundColor ?? getAvatarColor(name + (lastName ?? '')),
4245
shape: BoxShape.circle,
4346
// border: Border.all(color: whiteAluminum, width: 2),
4447
),

sama_chat_client/lib/src/features/conversations_list/widgets/conversation_list_item.dart

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ConversationListItem extends StatelessWidget {
3232
avatar: conversation.avatar,
3333
isDeleted: isDeletedUser(conversation.opponent),
3434
)
35-
: AvatarGroupIcon(conversation.avatar),
35+
: AvatarGroupIcon(conversation.avatar, conversation.name),
3636
title: Text(
3737
conversation.name,
3838
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
@@ -128,62 +128,67 @@ class DateUnreadWidget extends StatelessWidget {
128128

129129
@override
130130
Widget build(BuildContext context) {
131-
return Column(
132-
crossAxisAlignment: CrossAxisAlignment.end,
133-
children: [
134-
Padding(
135-
padding: const EdgeInsets.only(right: 2),
136-
child: Text(
137-
DateFormatter().getVerboseDateTimeRepresentation(
138-
(conversation.lastMessage?.t != null
139-
? DateTime.fromMillisecondsSinceEpoch(
140-
conversation.lastMessage!.t! * 1000)
141-
: conversation.updatedAt!)),
142-
style: const TextStyle(color: whiteAluminum, fontSize: 15),
143-
),
144-
),
145-
if (conversation.unreadMessagesCount != null &&
146-
conversation.unreadMessagesCount != 0)
147-
Padding(
148-
padding: const EdgeInsets.only(top: 4),
149-
child: Container(
150-
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 6),
151-
decoration: BoxDecoration(
152-
color: slateBlue, borderRadius: BorderRadius.circular(10.0)),
131+
return Padding(
132+
padding: const EdgeInsets.only(top: 5),
133+
child: Column(
134+
crossAxisAlignment: CrossAxisAlignment.end,
135+
children: [
136+
Padding(
137+
padding: const EdgeInsets.only(right: 2),
153138
child: Text(
154-
conversation.unreadMessagesCount.toString(),
155-
style: const TextStyle(color: white),
139+
DateFormatter().getVerboseDateTimeRepresentation(
140+
(conversation.lastMessage?.t != null
141+
? DateTime.fromMillisecondsSinceEpoch(
142+
conversation.lastMessage!.t! * 1000)
143+
: conversation.updatedAt)),
144+
style: const TextStyle(color: whiteAluminum, fontSize: 13),
156145
),
157146
),
158-
),
159-
],
160-
);
147+
if (conversation.unreadMessagesCount != null &&
148+
conversation.unreadMessagesCount != 0)
149+
Padding(
150+
padding: const EdgeInsets.only(top: 4),
151+
child: Container(
152+
padding:
153+
const EdgeInsets.symmetric(vertical: 2, horizontal: 6),
154+
decoration: BoxDecoration(
155+
color: slateBlue,
156+
borderRadius: BorderRadius.circular(10.0)),
157+
child: Text(
158+
conversation.unreadMessagesCount.toString(),
159+
style: const TextStyle(color: white),
160+
),
161+
),
162+
),
163+
],
164+
));
161165
}
162166
}
163167

164168
class DateFormatter {
165-
String getVerboseDateTimeRepresentation(DateTime dateTime) {
166-
DateTime now = DateTime.now();
167-
DateTime justNow = DateTime.now().subtract(const Duration(minutes: 1));
169+
String getVerboseDateTimeRepresentation(DateTime date) {
170+
final now = DateTime.now();
171+
final difference = now.difference(date);
168172

169-
DateTime localDateTime = dateTime.toLocal();
173+
if (difference.inMinutes < 1) {
174+
return 'Just now';
175+
}
170176

171-
if (!localDateTime.difference(justNow).isNegative) {
172-
return DateFormat('jm').format(dateTime);
177+
if (now.year == date.year &&
178+
now.month == date.month &&
179+
now.day == date.day) {
180+
return DateFormat('HH:mm').format(date);
173181
}
174182

175-
String roughTimeString = DateFormat('jm').format(dateTime);
176-
if (localDateTime.day == now.day &&
177-
localDateTime.month == now.month &&
178-
localDateTime.year == now.year) {
179-
return roughTimeString;
183+
final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
184+
if (date.isAfter(startOfWeek)) {
185+
return DateFormat('EEE').format(date).toLowerCase();
180186
}
181187

182-
if (now.difference(localDateTime).inDays < 4) {
183-
String weekday = DateFormat('EEEE').format(localDateTime);
184-
return weekday.substring(0, 2);
188+
if (now.year == date.year) {
189+
return DateFormat('dd.MM').format(date);
185190
}
186191

187-
return DateFormat.yMd().format(dateTime);
192+
return DateFormat('dd.MM.yy').format(date);
188193
}
189194
}

sama_chat_client/lib/src/features/profile/bloc/profile_bloc.dart

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,25 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
2929
on<ProfileResetChanges>(_onResetChanges);
3030
on<ProfileSubmitted>(_onSubmitted);
3131

32-
_userRepository.getCurrentUser().then((user) {
33-
add(ProfileUserReceived(user));
34-
});
32+
add(ProfileUserReceived());
3533
}
3634

3735
final UserRepository _userRepository;
3836

39-
void _onUserReceived(
37+
Future<void> _onUserReceived(
4038
ProfileUserReceived event,
4139
Emitter<ProfileState> emit,
42-
) {
40+
) async {
41+
var user = await _userRepository.getCurrentUser();
4342
emit(
4443
state.copyWith(
4544
status: FormzSubmissionStatus.initial,
46-
userLogin: event.user?.login,
47-
userAvatar: UserAvatar.pure(event.user?.avatar?.imageUrl ?? ''),
48-
userFirstname: UserFirstname.pure(event.user?.firstName ?? ''),
49-
userLastname: UserLastname.pure(event.user?.lastName ?? ''),
50-
userPhone: UserPhone.pure(event.user?.phone ?? ''),
51-
userEmail: UserEmail.pure(event.user?.email ?? '')),
45+
userLogin: user?.login,
46+
userAvatar: UserAvatar.pure(user?.avatar?.imageUrl ?? ''),
47+
userFirstname: UserFirstname.pure(user?.firstName ?? ''),
48+
userLastname: UserLastname.pure(user?.lastName ?? ''),
49+
userPhone: UserPhone.pure(user?.phone ?? ''),
50+
userEmail: UserEmail.pure(user?.email ?? '')),
5251
);
5352
}
5453

sama_chat_client/lib/src/features/profile/bloc/profile_event.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,7 @@ sealed class ProfileEvent extends Equatable {
77
List<Object?> get props => [];
88
}
99

10-
final class ProfileUserReceived extends ProfileEvent {
11-
const ProfileUserReceived(this.user);
12-
13-
final UserModel? user;
14-
15-
@override
16-
List<Object?> get props => [user];
17-
}
10+
final class ProfileUserReceived extends ProfileEvent {}
1811

1912
final class ProfileAvatarPicked extends ProfileEvent {}
2013

sama_chat_client/lib/src/shared/ui/colors.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import 'dart:ui';
22

3+
import 'package:flutter/material.dart';
4+
35
const Color white = Color(0xFFFFFFFF);
46
const Color lightWhite = Color(0xFFF9F9F9);
57
const Color smokyWhite = Color(0xFFF6F6F6);
@@ -23,3 +25,25 @@ const Color lightPink = Color(0xFFFFB6C1);
2325
const Color orange = Color(0xFFFFA500);
2426
const Color redPurple = Color(0xFF68174D);
2527
const Color red = Color(0xFFDF2E38);
28+
29+
const colors = [
30+
Color(0xFFe17076), // red
31+
Color(0xFFf4a261), // orange
32+
Color(0xFFe9c46a), // yellow
33+
Color(0xFF2a9d8f), // teal
34+
Color(0xFF4d96ff), // blue
35+
Color(0xFF9b5de5), // purple
36+
Color(0xFFf15bb5), // pink
37+
Color(0xFF00bcd4), // cyan
38+
];
39+
40+
Color getAvatarColor(String input) {
41+
final hash = input.runes.fold(0, (prev, el) => prev * 31 + el);
42+
final index = hash.abs() % colors.length;
43+
44+
final saturation = 0.35 + ((hash >> 8) % 40) / 100; // 0.35–0.75
45+
final lightness = 0.55 + ((hash >> 16) % 20) / 100; // 0.55–0.75
46+
47+
final hsl = HSLColor.fromColor(colors[index]);
48+
return hsl.withSaturation(saturation).withLightness(lightness).toColor();
49+
}

0 commit comments

Comments
 (0)