diff --git a/lib/data/models/contact_cubit.dart b/lib/data/models/contact_cubit.dart index c3c9e88c4b2f74f77f02c5b60bca759d68ca2d1c..d00de6e81e08a4db9d173970881f44e5d5d339b2 100644 --- a/lib/data/models/contact_cubit.dart +++ b/lib/data/models/contact_cubit.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; +import '../../ui/ui_helpers.dart'; import 'contact.dart'; import 'contact_state.dart'; @@ -41,6 +42,29 @@ class ContactsCubit extends HydratedCubit<ContactsState> { filteredContacts: filteredContactsTruncated)); } + Future<List<Contact>> _resizeAvatars(List<Contact> list) async { + final List<Contact> newList = <Contact>[]; + for (final Contact c in list) { + if (c.avatar != null) { + final Contact newC = c.copyWith(avatar: await resizeAvatar(c.avatar!)); + newList.add(newC); + } else { + newList.add(c); + } + } + return newList; + } + + Future<void> resizeAvatars() async { + final List<Contact> contactsCompressed = + await _resizeAvatars(state.contacts); + final List<Contact> filteredContactsCompressed = + await _resizeAvatars(state.filteredContacts); + emit(state.copyWith( + contacts: contactsCompressed, + filteredContacts: filteredContactsCompressed)); + } + void updateContact(Contact contact) { final List<Contact> contacts = state.contacts.map((Contact c) { if (c.pubKey == contact.pubKey) { diff --git a/lib/ui/ui_helpers.dart b/lib/ui/ui_helpers.dart index f280ea4eee7fcff6039445f47f7a12d3b58b19d0..ccf8fb9ca46803d370e367bbeac309239c52ae1b 100644 --- a/lib/ui/ui_helpers.dart +++ b/lib/ui/ui_helpers.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:clipboard/clipboard.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:fast_image_resizer/fast_image_resizer.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -50,11 +51,12 @@ void copyPublicKeyToClipboard(BuildContext context) { const Color defAvatarBgColor = Colors.grey; const Color defAvatarColor = Colors.white; +const double defAvatarSize = 24; Widget avatar(Uint8List? rawAvatar, {Color color = defAvatarColor, Color bgColor = defAvatarBgColor, - double avatarSize = 24}) { + double avatarSize = defAvatarSize}) { return rawAvatar != null && rawAvatar.isNotEmpty ? CircleAvatar( radius: avatarSize, @@ -153,25 +155,16 @@ double parseToDoubleLocalized( String localizeNumber(BuildContext context, double amount) => NumberFormat.decimalPattern(context.locale.toString()).format(amount); -Contact contactFromResultSearch(Map<String, dynamic> record) { +Future<Contact> contactFromResultSearch(Map<String, dynamic> record) async { final Map<String, dynamic> source = record['_source'] as Map<String, dynamic>; - final Uint8List? avatarBase64 = _getAvatarFromResults(source); + final Uint8List? avatarBase64 = await _getAvatarFromResults(source); return Contact( pubKey: record['_id'] as String, name: source['title'] as String, avatar: avatarBase64); } -/* -Contact contactFromUserProfile(Map<String, dynamic> source) { - final Uint8List? avatarBase64 = _getAvatarFromResults(source); - return Contact( - pubKey: source['issuer'] as String, - name: source['title'] as String, - avatar: avatarBase64); -} */ - -Uint8List? _getAvatarFromResults(Map<String, dynamic> source) { +Future<Uint8List?> _getAvatarFromResults(Map<String, dynamic> source) async { Uint8List? avatarBase64; if (source['avatar'] != null) { final Map<String, dynamic> avatar = @@ -179,7 +172,18 @@ Uint8List? _getAvatarFromResults(Map<String, dynamic> source) { avatarBase64 = imageFromBase64String( 'data:${avatar['_content_type']};base64,${avatar['_content']}'); } - return avatarBase64; + if (avatarBase64 != null && avatarBase64.isNotEmpty) { + final Uint8List? avatarBase64resized = await resizeAvatar(avatarBase64); + return avatarBase64resized; + } else { + return null; + } +} + +Future<Uint8List?> resizeAvatar(Uint8List avatarBase64) async { + final ByteData? bytes = + await resizeImage(avatarBase64, height: defAvatarSize.toInt() * 2); + return bytes != null ? Uint8List.view(bytes.buffer) : null; } final RegExp basicEnglishCharsRegExp = diff --git a/pubspec.lock b/pubspec.lock index c5f143a4ba5180ff4124e29f966523170ba4cee3..ecce57fc745d89d7905e2c205d006c2895f64ccb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -410,6 +410,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1" + fast_image_resizer: + dependency: "direct main" + description: + name: fast_image_resizer + sha256: fc63778efab052f3e5f242c80eab1b72ee4753001678e27420050d4d1941564d + url: "https://pub.dev" + source: hosted + version: "0.0.2" feedback: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 2680b08d530b416f4d406ffb6fb34380768a2623..524496e8a08dc3f1151ff69ba33061d7bf0baf8f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -86,6 +86,7 @@ dependencies: feedback_gitlab: ^2.2.0 connectivity_wrapper: ^1.1.3 rxdart: ^0.27.7 + fast_image_resizer: ^0.0.2 dev_dependencies: flutter_test: