Skip to content

Commit d3e7a63

Browse files
committed
add default avatar
1 parent cdb89a1 commit d3e7a63

File tree

8 files changed

+80
-155
lines changed

8 files changed

+80
-155
lines changed

assets/images/default_avatar.svg

Lines changed: 27 additions & 0 deletions
Loading

lib/src/database/daos/contacts_dao.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,6 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
115115
}
116116
}
117117

118-
Future<void> newMessageExchange(int userId) {
119-
return updateContact(
120-
userId,
121-
ContactsCompanion(
122-
lastMessageExchange: Value(DateTime.now()),
123-
),
124-
);
125-
}
126-
127118
Stream<List<Contact>> watchNotAcceptedContacts() {
128119
return (select(contacts)
129120
..where((t) =>

lib/src/database/daos/messages_dao.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
193193
Future<int?> insertMessage(MessagesCompanion message) async {
194194
try {
195195
await (update(contacts)
196-
..where((c) => c.userId.equals(message.contactId.value)))
196+
..where(
197+
(c) => c.userId.equals(message.contactId.value),
198+
))
197199
.write(ContactsCompanion(lastMessageExchange: Value(DateTime.now())));
198200

199201
return await into(messages).insert(message);

lib/src/model/json/message.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Color getMessageColorFromType(MessageContent content, BuildContext context) {
1515
color = context.color.primary;
1616
} else {
1717
if (content.isVideo) {
18-
color = const Color.fromARGB(255, 240, 243, 33);
18+
color = const Color.fromARGB(255, 243, 33, 208);
1919
} else {
2020
color = Colors.redAccent;
2121
}

lib/src/views/chats/chat_list.view.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:twonly/globals.dart';
1010
import 'package:twonly/src/database/daos/contacts_dao.dart';
1111
import 'package:twonly/src/database/tables/messages_table.dart';
1212
import 'package:twonly/src/database/twonly_database.dart';
13+
import 'package:twonly/src/model/json/userdata.dart';
1314
import 'package:twonly/src/providers/connection.provider.dart';
1415
import 'package:twonly/src/services/api/media_download.dart';
1516
import 'package:twonly/src/utils/misc.dart';
@@ -21,14 +22,15 @@ import 'package:twonly/src/views/chats/chat_list_components/connection_info.comp
2122
import 'package:twonly/src/views/chats/chat_list_components/feedback_btn.dart';
2223
import 'package:twonly/src/views/chats/chat_list_components/last_message_time.dart';
2324
import 'package:twonly/src/views/chats/chat_messages.view.dart';
25+
import 'package:twonly/src/views/chats/chat_messages_components/message_send_state_icon.dart';
2426
import 'package:twonly/src/views/chats/media_viewer.view.dart';
2527
import 'package:twonly/src/views/chats/start_new_chat.view.dart';
2628
import 'package:twonly/src/views/components/flame.dart';
2729
import 'package:twonly/src/views/components/initialsavatar.dart';
28-
import 'package:twonly/src/views/components/message_send_state_icon.dart';
2930
import 'package:twonly/src/views/components/notification_badge.dart';
3031
import 'package:twonly/src/views/components/user_context_menu.dart';
3132
import 'package:twonly/src/views/settings/help/changelog.view.dart';
33+
import 'package:twonly/src/views/settings/profile/profile.view.dart';
3234
import 'package:twonly/src/views/settings/settings_main.view.dart';
3335
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
3436
import 'package:twonly/src/views/tutorial/tutorials.dart';
@@ -43,6 +45,7 @@ class _ChatListViewState extends State<ChatListView> {
4345
late StreamSubscription<List<Contact>> _contactsSub;
4446
List<Contact> _contacts = [];
4547
List<Contact> _pinnedContacts = [];
48+
UserData? _user;
4649

4750
GlobalKey firstUserListItemKey = GlobalKey();
4851
GlobalKey searchForOtherUsers = GlobalKey();
@@ -76,6 +79,7 @@ class _ChatListViewState extends State<ChatListView> {
7679

7780
final user = await getUser();
7881
if (user == null) return;
82+
_user = user;
7983
final changeLog = await rootBundle.loadString('CHANGELOG.md');
8084
final changeLogHash =
8185
(await compute(Sha256().hash, changeLog.codeUnits)).bytes;
@@ -112,6 +116,23 @@ class _ChatListViewState extends State<ChatListView> {
112116
return Scaffold(
113117
appBar: AppBar(
114118
title: Row(children: [
119+
GestureDetector(
120+
onTap: () async {
121+
await Navigator.push(context,
122+
MaterialPageRoute(builder: (context) {
123+
return const ProfileView();
124+
}));
125+
_user = await getUser();
126+
if (!mounted) return;
127+
setState(() {});
128+
},
129+
child: ContactAvatar(
130+
userData: _user,
131+
fontSize: 14,
132+
color: context.color.onSurface.withAlpha(20),
133+
),
134+
),
135+
const SizedBox(width: 10),
115136
const Text('twonly '),
116137
if (planId != 'Free')
117138
GestureDetector(

lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
44
import 'package:twonly/globals.dart';
55
import 'package:twonly/src/database/twonly_database.dart';
66
import 'package:twonly/src/model/memory_item.model.dart';
7-
import 'package:twonly/src/views/components/message_send_state_icon.dart';
7+
import 'package:twonly/src/views/chats/chat_messages_components/message_send_state_icon.dart';
88
import 'package:twonly/src/views/memories/memories_item_thumbnail.dart';
99
import 'package:twonly/src/views/memories/memories_photo_slider.view.dart';
1010

lib/src/views/components/message_send_state_icon.dart renamed to lib/src/views/chats/chat_messages_components/message_send_state_icon.dart

File renamed without changes.
Lines changed: 26 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_svg/svg.dart';
3-
import 'package:twonly/src/database/daos/contacts_dao.dart';
43
import 'package:twonly/src/database/twonly_database.dart';
54
import 'package:twonly/src/model/json/userdata.dart';
65
import 'package:twonly/src/utils/log.dart';
@@ -11,170 +10,55 @@ class ContactAvatar extends StatelessWidget {
1110
this.contact,
1211
this.userData,
1312
this.fontSize = 20,
13+
this.color,
1414
});
1515
final Contact? contact;
1616
final UserData? userData;
1717
final double? fontSize;
18+
final Color? color;
1819

1920
@override
2021
Widget build(BuildContext context) {
21-
var displayName = '';
2222
String? avatarSvg;
2323

2424
if (contact != null) {
25-
displayName = getContactDisplayName(contact!).replaceAll('\u0336', '');
2625
avatarSvg = contact!.avatarSvg;
2726
} else if (userData != null) {
28-
displayName = userData!.displayName;
2927
avatarSvg = userData!.avatarSvg;
3028
} else {
3129
return Container();
3230
}
3331

3432
final proSize = (fontSize == null) ? 40 : (fontSize! * 2);
3533

36-
if (avatarSvg != null) {
37-
return Container(
38-
constraints: BoxConstraints(
39-
minHeight: 2 * (fontSize ?? 20),
40-
minWidth: 2 * (fontSize ?? 20),
41-
maxWidth: 2 * (fontSize ?? 20),
42-
maxHeight: 2 * (fontSize ?? 20),
43-
),
44-
child: Center(
45-
child: ClipRRect(
46-
borderRadius: BorderRadius.circular(12),
47-
child: SizedBox(
48-
height: proSize as double,
49-
width: proSize,
50-
child: Center(
51-
child: SvgPicture.string(
52-
avatarSvg,
53-
errorBuilder: (context, error, stackTrace) {
54-
Log.error('$error');
55-
return Container();
56-
},
57-
),
58-
),
34+
return Container(
35+
constraints: BoxConstraints(
36+
minHeight: 2 * (fontSize ?? 20),
37+
minWidth: 2 * (fontSize ?? 20),
38+
maxWidth: 2 * (fontSize ?? 20),
39+
maxHeight: 2 * (fontSize ?? 20),
40+
),
41+
child: Center(
42+
child: ClipRRect(
43+
borderRadius: BorderRadius.circular(12),
44+
child: Container(
45+
height: proSize as double,
46+
width: proSize,
47+
color: color,
48+
child: Center(
49+
child: avatarSvg == null
50+
? SvgPicture.asset('assets/images/default_avatar.svg')
51+
: SvgPicture.string(
52+
avatarSvg,
53+
errorBuilder: (context, error, stackTrace) {
54+
Log.error('$error');
55+
return Container();
56+
},
57+
),
5958
),
6059
),
6160
),
62-
);
63-
}
64-
65-
// Extract initials from the displayName
66-
final nameParts = displayName.split(' ');
67-
var initials = nameParts.map((part) => part[0]).join().toUpperCase();
68-
69-
if (initials.length > 2) {
70-
initials = initials[0] + initials[1];
71-
} else if (initials.length == 1) {
72-
initials = displayName[0] + displayName[1];
73-
}
74-
75-
initials = initials.toUpperCase();
76-
77-
// Generate a color based on the initials (you can customize this logic)
78-
final avatarColor = _getColorFromUsername(
79-
displayName, Theme.of(context).brightness == Brightness.dark);
80-
81-
final Widget child = Text(
82-
initials,
83-
style: TextStyle(
84-
color: _getTextColor(avatarColor),
85-
fontWeight: FontWeight.normal,
86-
fontSize: fontSize,
8761
),
8862
);
89-
90-
final isPro = initials[0] == 'T';
91-
92-
if (isPro) {
93-
return Container(
94-
constraints: BoxConstraints(
95-
minHeight: 2 * (fontSize ?? 20),
96-
minWidth: 2 * (fontSize ?? 20),
97-
maxWidth: 2 * (fontSize ?? 20),
98-
maxHeight: 2 * (fontSize ?? 20),
99-
),
100-
child: Center(
101-
child: ClipRRect(
102-
borderRadius: BorderRadius.circular(12),
103-
child: Container(
104-
height: proSize as double,
105-
width: proSize,
106-
//padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
107-
color: avatarColor,
108-
child: Center(child: child),
109-
),
110-
),
111-
),
112-
);
113-
} else {
114-
return CircleAvatar(
115-
backgroundColor: avatarColor,
116-
radius: fontSize,
117-
child: child,
118-
);
119-
}
120-
}
121-
122-
Color _getTextColor(Color color) {
123-
const value = 100.0;
124-
// Ensure the value does not exceed the RGB limits
125-
final newRed = ((color.r * 255) - value).clamp(0, 255).round();
126-
final newGreen = (color.g * 255 - value).clamp(0, 255).round();
127-
final newBlue = (color.b * 255 - value).clamp(0, 255).round();
128-
129-
return Color.fromARGB((color.a * 255).round(), newRed, newGreen, newBlue);
130-
}
131-
132-
Color _getColorFromUsername(String displayName, bool isDarkMode) {
133-
// Define color lists for light and dark themes
134-
final lightColors = <Color>[
135-
Colors.red,
136-
Colors.green,
137-
Colors.blue,
138-
Colors.orange,
139-
Colors.purple,
140-
Colors.teal,
141-
Colors.amber,
142-
Colors.indigo,
143-
Colors.cyan,
144-
Colors.lime,
145-
Colors.pink,
146-
Colors.brown,
147-
Colors.grey,
148-
];
149-
150-
final darkColors = <Color>[
151-
const Color.fromARGB(255, 246, 227, 254), // Light Lavender
152-
const Color.fromARGB(255, 246, 216, 215), // Light Pink
153-
const Color.fromARGB(255, 226, 236, 235), // Light Teal
154-
const Color.fromARGB(255, 255, 224, 178), // Light Yellow
155-
const Color.fromARGB(255, 255, 182, 193), // Light Pink (Hot Pink)
156-
const Color.fromARGB(255, 173, 216, 230), // Light Blue
157-
const Color.fromARGB(255, 221, 160, 221), // Plum
158-
const Color.fromARGB(255, 255, 228, 196), // Bisque
159-
const Color.fromARGB(255, 240, 230, 140), // Khaki
160-
const Color.fromARGB(255, 255, 192, 203), // Pink
161-
const Color.fromARGB(255, 255, 218, 185), // Peach Puff
162-
const Color.fromARGB(255, 255, 160, 122), // Light Salmon
163-
const Color.fromARGB(255, 135, 206, 250), // Light Sky Blue
164-
const Color.fromARGB(255, 255, 228, 225), // Misty Rose
165-
const Color.fromARGB(255, 240, 248, 255), // Alice Blue
166-
const Color.fromARGB(255, 255, 250, 205), // Lemon Chiffon
167-
const Color.fromARGB(255, 255, 218, 185), // Peach Puff
168-
];
169-
170-
// Simple logic to generate a hash from initials
171-
final hash =
172-
displayName.codeUnits.fold(0, (prev, element) => prev + element);
173-
174-
// Select the appropriate color list based on the current theme brightness
175-
final colors = isDarkMode ? darkColors : lightColors;
176-
177-
// Use the hash to select a color from the list
178-
return colors[hash % colors.length];
17963
}
18064
}

0 commit comments

Comments
 (0)