11import 'package:flutter/material.dart' ;
22import 'package:flutter_svg/svg.dart' ;
3- import 'package:twonly/src/database/daos/contacts_dao.dart' ;
43import 'package:twonly/src/database/twonly_database.dart' ;
54import 'package:twonly/src/model/json/userdata.dart' ;
65import '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 ('\u 0336' , '' );
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