From 76a9455c7c4842bb13393416a05ace6fa5ae344d Mon Sep 17 00:00:00 2001 From: otsmr Date: Mon, 5 Oct 2026 22:54:46 +0200 Subject: [PATCH] fix flutter issues --- .../emoji_picker/category_view/category.dart | 2 + .../category_view/category_view.dart | 4 +- .../category_view/category_view_config.dart | 6 +- .../components/emoji_picker/config.dart | 8 +- .../emoji_picker/default_emoji_set.dart | 2 - .../visual/components/emoji_picker/emoji.dart | 6 +- .../components/emoji_picker/emoji_picker.dart | 2 +- .../emoji_picker/emoji_picker_controller.dart | 4 +- .../emoji_picker_internal_utils.dart | 16 ++-- .../emoji_picker/emoji_picker_utils.dart | 13 ++-- .../emoji_picker/emoji_picker_widget.dart | 23 +++--- .../emoji_text_editing_controller.dart | 9 ++- .../emoji_view/default_emoji_picker_view.dart | 3 +- .../emoji_view/emoji_picker_view.dart | 4 +- .../emoji_view/emoji_view_config.dart | 7 +- .../locales/default_emoji_set_locale.dart | 2 +- .../components/emoji_picker/search_view.dart | 10 ++- .../skin_tones/emoji_skin_tones.dart | 8 +- .../skin_tones/skin_tone_config.dart | 4 +- .../skin_tones/skin_tone_overlay.dart | 10 +-- .../skin_tones/triangle_decoration.dart | 2 +- .../widgets/backspace_button.dart | 8 +- .../emoji_picker/widgets/emoji_cell.dart | 29 ++++---- .../views/chats/start_new_chat.view.dart | 1 - rust/src/services/groups/model.rs | 1 + .../emoji_picker_flutter_test.dart | 6 +- .../emoji_picker/emoji_picker_test.dart | 73 +++++++++---------- .../emoji_text_editing_controller_test.dart | 8 +- .../emoji_picker/emoji_text_style_test.dart | 6 +- .../emoji_picker/recent_emoji_state_test.dart | 10 +-- 30 files changed, 149 insertions(+), 138 deletions(-) diff --git a/lib/src/visual/components/emoji_picker/category_view/category.dart b/lib/src/visual/components/emoji_picker/category_view/category.dart index d505598a..4f207953 100644 --- a/lib/src/visual/components/emoji_picker/category_view/category.dart +++ b/lib/src/visual/components/emoji_picker/category_view/category.dart @@ -1,3 +1,5 @@ +// ignore_for_file: constant_identifier_names + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License diff --git a/lib/src/visual/components/emoji_picker/category_view/category_view.dart b/lib/src/visual/components/emoji_picker/category_view/category_view.dart index 03a7d9b4..7d61286f 100644 --- a/lib/src/visual/components/emoji_picker/category_view/category_view.dart +++ b/lib/src/visual/components/emoji_picker/category_view/category_view.dart @@ -4,8 +4,8 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Template class for custom implementation /// Inhert this class to create your own Category view @@ -89,7 +89,7 @@ class DefaultCategoryView extends CategoryView { class DefaultCategoryViewState extends CategoryViewState { @override Widget build(BuildContext context) { - return Container( + return ColoredBox( color: widget.config.categoryViewConfig.backgroundColor, child: Row( children: [ diff --git a/lib/src/visual/components/emoji_picker/category_view/category_view_config.dart b/lib/src/visual/components/emoji_picker/category_view/category_view_config.dart index 008397f9..817f331f 100644 --- a/lib/src/visual/components/emoji_picker/category_view/category_view_config.dart +++ b/lib/src/visual/components/emoji_picker/category_view/category_view_config.dart @@ -1,11 +1,13 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Callback function for custom category view typedef CategoryViewBuilder = @@ -77,7 +79,7 @@ class CategoryViewConfig { final CategoryViewBuilder? customCategoryView; @override - bool operator ==(other) { + bool operator ==(Object other) { return (other is CategoryViewConfig) && other.tabBarHeight == tabBarHeight && other.tabIndicatorAnimDuration == tabIndicatorAnimDuration && diff --git a/lib/src/visual/components/emoji_picker/config.dart b/lib/src/visual/components/emoji_picker/config.dart index 7c45d2e6..e78e315c 100644 --- a/lib/src/visual/components/emoji_picker/config.dart +++ b/lib/src/visual/components/emoji_picker/config.dart @@ -1,12 +1,14 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes, prefer_asserts_with_message + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License * Copyright (c) 2024 Stefan Humm */ +import 'package:flutter/material.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:twonly/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart'; -import 'package:flutter/material.dart'; /// Number of skin tone icons const kSkinToneCount = 6; @@ -89,7 +91,7 @@ class Config { final ResizeConfig resizeConfig; @override - bool operator ==(other) { + bool operator ==(Object other) { return (other is Config) && other.height == height && other.viewOrderConfig == viewOrderConfig && @@ -143,7 +145,7 @@ class ViewOrderConfig { final EmojiPickerItem bottom; @override - bool operator ==(other) { + bool operator ==(Object other) { return other is ViewOrderConfig && other.top == top && other.middle == middle && diff --git a/lib/src/visual/components/emoji_picker/default_emoji_set.dart b/lib/src/visual/components/emoji_picker/default_emoji_set.dart index ab0678e9..4941938d 100644 --- a/lib/src/visual/components/emoji_picker/default_emoji_set.dart +++ b/lib/src/visual/components/emoji_picker/default_emoji_set.dart @@ -4,8 +4,6 @@ * Copyright (c) 2024 Stefan Humm */ -// ignore_for_file: lines_longer_than_80_chars - import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// List of categories of emojis diff --git a/lib/src/visual/components/emoji_picker/emoji.dart b/lib/src/visual/components/emoji_picker/emoji.dart index 59f9ed6c..e933b912 100644 --- a/lib/src/visual/components/emoji_picker/emoji.dart +++ b/lib/src/visual/components/emoji_picker/emoji.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_dynamic_calls, prefer_constructors_over_static_methods + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License @@ -39,9 +41,7 @@ class Emoji { return Emoji( json['emoji'] as String, json['name'] as String, - hasSkinTone: json['hasSkinTone'] != null - ? json['hasSkinTone'] as bool - : false, + hasSkinTone: json['hasSkinTone'] != null && json['hasSkinTone'] as bool, ); } diff --git a/lib/src/visual/components/emoji_picker/emoji_picker.dart b/lib/src/visual/components/emoji_picker/emoji_picker.dart index 404fbce7..9ae6edec 100644 --- a/lib/src/visual/components/emoji_picker/emoji_picker.dart +++ b/lib/src/visual/components/emoji_picker/emoji_picker.dart @@ -4,7 +4,6 @@ * Copyright (c) 2024 Stefan Humm */ -export 'locales/emoji_set.dart'; export 'bottom_action_bar.dart'; export 'category_view/category.dart'; export 'category_view/category_view.dart'; @@ -19,6 +18,7 @@ export 'emoji_text_editing_controller.dart'; export 'emoji_view/default_emoji_picker_view.dart'; export 'emoji_view/emoji_picker_view.dart'; export 'emoji_view/emoji_view_config.dart'; +export 'locales/emoji_set.dart'; export 'search_view.dart'; export 'skin_tones/emoji_skin_tones.dart'; export 'skin_tones/skin_tone_config.dart'; diff --git a/lib/src/visual/components/emoji_picker/emoji_picker_controller.dart b/lib/src/visual/components/emoji_picker/emoji_picker_controller.dart index 430ec4cd..49fa1627 100644 --- a/lib/src/visual/components/emoji_picker/emoji_picker_controller.dart +++ b/lib/src/visual/components/emoji_picker/emoji_picker_controller.dart @@ -1,12 +1,14 @@ +// ignore_for_file: comment_references + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License * Copyright (c) 2024 Stefan Humm */ +import 'package:flutter/foundation.dart' hide Category; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart' show Category; -import 'package:flutter/foundation.dart' hide Category; /// Controller for EmojiPicker widget that allows reading and changing /// the selected category programmatically. diff --git a/lib/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart b/lib/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart index 784e5db6..a8ca6f3b 100644 --- a/lib/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart +++ b/lib/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart @@ -9,10 +9,10 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Initial value for RecentEmoji const initVal = 1; @@ -107,11 +107,11 @@ class EmojiPickerInternalUtils { return Future(() async { final prefs = await SharedPreferences.getInstance(); - var emojiJson = prefs.getString('recent'); + final emojiJson = prefs.getString('recent'); if (emojiJson == null) { return _recentEmojis = []; } - var json = jsonDecode(emojiJson) as List; + final json = jsonDecode(emojiJson) as List; return _recentEmojis = json .map(RecentEmoji.fromJson) .toList(); @@ -128,7 +128,7 @@ class EmojiPickerInternalUtils { emoji = removeSkinTone(emoji); } var recentEmoji = await getRecentEmojis(); - var recentEmojiIndex = recentEmoji.indexWhere( + final recentEmojiIndex = recentEmoji.indexWhere( (element) => element.emoji.emoji == emoji.emoji, ); if (recentEmojiIndex != -1) { @@ -147,7 +147,7 @@ class EmojiPickerInternalUtils { // save locally final prefs = await SharedPreferences.getInstance(); - prefs.setString('recent', jsonEncode(recentEmoji)); + unawaited(prefs.setString('recent', jsonEncode(recentEmoji))); return _recentEmojis = recentEmoji; } @@ -162,7 +162,7 @@ class EmojiPickerInternalUtils { emoji = removeSkinTone(emoji); } var recentEmoji = await getRecentEmojis(); - var recentEmojiIndex = recentEmoji.indexWhere( + final recentEmojiIndex = recentEmoji.indexWhere( (element) => element.emoji.emoji == emoji.emoji, ); if (recentEmojiIndex != -1) { @@ -188,7 +188,7 @@ class EmojiPickerInternalUtils { // save locally final prefs = await SharedPreferences.getInstance(); - prefs.setString('recent', jsonEncode(recentEmoji)); + unawaited(prefs.setString('recent', jsonEncode(recentEmoji))); return _recentEmojis = recentEmoji; } @@ -196,7 +196,7 @@ class EmojiPickerInternalUtils { /// Clears the list of recent emojis in local storage Future clearRecentEmojisInLocalStorage() async { final prefs = await SharedPreferences.getInstance(); - prefs.setString('recent', jsonEncode([])); + unawaited(prefs.setString('recent', jsonEncode([]))); _recentEmojis = []; } diff --git a/lib/src/visual/components/emoji_picker/emoji_picker_utils.dart b/lib/src/visual/components/emoji_picker/emoji_picker_utils.dart index dd0622ff..56b373fb 100644 --- a/lib/src/visual/components/emoji_picker/emoji_picker_utils.dart +++ b/lib/src/visual/components/emoji_picker/emoji_picker_utils.dart @@ -6,13 +6,14 @@ import 'dart:math'; +import 'package:flutter/material.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; -import 'package:flutter/material.dart'; /// Emoji Regex /// Keycap Sequence '((\u0023|\u002a|[\u0030-\u0039])\ufe0f\u20e3){1}' /// Issue: https://github.com/flutter/flutter/issues/36062 +// ignore: constant_identifier_names const EmojiRegex = r'((\u0023|\u002a|[\u0030-\u0039])\ufe0f\u20e3){1}|\p{Emoji}|\u200D|\uFE0F'; @@ -56,7 +57,7 @@ class EmojiPickerUtils { : data; // Set all the emoji entities - for (var emojis in availableCategoryEmoji) { + for (final emojis in availableCategoryEmoji) { _allAvailableEmojiEntities.addAll(emojis.emoji); } } @@ -186,7 +187,7 @@ class EmojiPickerUtils { /// instead of an invalid double-modifier one (e.g. 👋🏻🏽). Emoji applySkinTone(Emoji emoji, String color) { final codeUnits = removeSkinTone(emoji).emoji.codeUnits; - var result = List.empty(growable: true) + final result = List.empty(growable: true) // Basic emoji without gender (until char 2) ..addAll(codeUnits.sublist(0, min(codeUnits.length, 2))) // Skin tone @@ -246,9 +247,9 @@ class EmojiPickerUtils { Future clearRecentEmojis({ required GlobalKey key, }) async { - return await EmojiPickerInternalUtils() - .clearRecentEmojisInLocalStorage() - .then((_) => key.currentState?.updateRecentEmoji([], refresh: true)); + return EmojiPickerInternalUtils().clearRecentEmojisInLocalStorage().then( + (_) => key.currentState?.updateRecentEmoji([], refresh: true), + ); } /// Returns the emoji regex diff --git a/lib/src/visual/components/emoji_picker/emoji_picker_widget.dart b/lib/src/visual/components/emoji_picker/emoji_picker_widget.dart index 3013eeb6..a9b0ad61 100644 --- a/lib/src/visual/components/emoji_picker/emoji_picker_widget.dart +++ b/lib/src/visual/components/emoji_picker/emoji_picker_widget.dart @@ -1,3 +1,5 @@ +// ignore_for_file: constant_identifier_names + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License @@ -6,17 +8,17 @@ import 'dart:io'; -import 'package:twonly/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart'; +import 'package:flutter/material.dart'; import 'package:twonly/src/visual/components/emoji_picker/category_view/category.dart'; import 'package:twonly/src/visual/components/emoji_picker/config.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_controller.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_view/default_emoji_picker_view.dart'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_view/emoji_picker_view.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart'; +import 'package:twonly/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart'; import 'package:twonly/src/visual/components/emoji_picker/search_view.dart'; -import 'package:flutter/material.dart'; /// All the possible categories that [Emoji] can be put into /// @@ -342,7 +344,7 @@ class EmojiPickerState extends State { if (cursorPosition >= 0) { final selection = controller.value.selection; final newTextBeforeCursor = _deleteWordByWord( - selection.textBefore(text).toString(), + selection.textBefore(text), ); controller.value = controller.value.copyWith( text: newTextBeforeCursor + selection.textAfter(text), @@ -558,8 +560,7 @@ class EmojiPickerState extends State { final maximumHeight = _maximumPickerHeight(initialHeight); final nextHeight = ((_currentPickerHeight ?? initialHeight) - details.delta.dy) - .clamp(initialHeight, maximumHeight) - .toDouble(); + .clamp(initialHeight, maximumHeight); if (nextHeight != _currentPickerHeight) { setState(() => _currentPickerHeight = nextHeight); } @@ -596,12 +597,10 @@ class EmojiPickerState extends State { final resizeConfig = widget.config.resizeConfig; final configuredMaximum = resizeConfig.maxHeight ?? safeHeight * resizeConfig.maxHeightFactor; - return configuredMaximum - .clamp( - initialHeight, - safeHeight < initialHeight ? initialHeight : safeHeight, - ) - .toDouble(); + return configuredMaximum.clamp( + initialHeight, + safeHeight < initialHeight ? initialHeight : safeHeight, + ); } void _showSearchView() { diff --git a/lib/src/visual/components/emoji_picker/emoji_text_editing_controller.dart b/lib/src/visual/components/emoji_picker/emoji_text_editing_controller.dart index c1f39c28..3d295bcf 100644 --- a/lib/src/visual/components/emoji_picker/emoji_text_editing_controller.dart +++ b/lib/src/visual/components/emoji_picker/emoji_text_editing_controller.dart @@ -1,11 +1,13 @@ +// ignore_for_file: constant_identifier_names, prefer_asserts_with_message + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/widgets.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Default delimiter for regex const delimiter = '|'; @@ -14,7 +16,7 @@ const delimiter = '|'; /// a particular style to emoji characters. class EmojiTextEditingController extends TextEditingController { /// Constructor, requres emojiStyle, since otherwise this class has no effect - EmojiTextEditingController({super.text, required this.emojiTextStyle}); + EmojiTextEditingController({required this.emojiTextStyle, super.text}); /// The style used for the emoji characters final TextStyle emojiTextStyle; @@ -25,8 +27,8 @@ class EmojiTextEditingController extends TextEditingController { @override TextSpan buildTextSpan({ required BuildContext context, - TextStyle? style, required bool withComposing, + TextStyle? style, }) { assert( !value.composing.isValid || !withComposing || value.isComposingRangeValid, @@ -83,7 +85,6 @@ class EmojiTextEditingController extends TextEditingController { /// Emoji text style providing commonly available fallback fonts. const DefaultEmojiTextStyle = TextStyle( - inherit: true, fontFamilyFallback: [ 'Apple Color Emoji', 'Noto Color Emoji', diff --git a/lib/src/visual/components/emoji_picker/emoji_view/default_emoji_picker_view.dart b/lib/src/visual/components/emoji_picker/emoji_view/default_emoji_picker_view.dart index 63316bc4..64eb62ce 100644 --- a/lib/src/visual/components/emoji_picker/emoji_view/default_emoji_picker_view.dart +++ b/lib/src/visual/components/emoji_picker/emoji_view/default_emoji_picker_view.dart @@ -4,8 +4,8 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Default EmojiPicker Implementation class DefaultEmojiPickerView extends EmojiPickerView { @@ -254,7 +254,6 @@ class _DefaultEmojiPickerViewState extends State ), sliver: SliverGrid.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - childAspectRatio: 1, crossAxisCount: viewConfig.columns, mainAxisSpacing: viewConfig.verticalSpacing, crossAxisSpacing: viewConfig.horizontalSpacing, diff --git a/lib/src/visual/components/emoji_picker/emoji_view/emoji_picker_view.dart b/lib/src/visual/components/emoji_picker/emoji_view/emoji_picker_view.dart index 4d6b61ee..4c54c5e5 100644 --- a/lib/src/visual/components/emoji_picker/emoji_view/emoji_picker_view.dart +++ b/lib/src/visual/components/emoji_picker/emoji_view/emoji_picker_view.dart @@ -32,11 +32,11 @@ abstract class EmojiPickerView extends StatefulWidget { class EmojiContainer extends StatelessWidget { /// Constructor. const EmojiContainer({ - super.key, required this.color, required this.buttonMode, - this.padding, required this.child, + super.key, + this.padding, }); final Color color; diff --git a/lib/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart b/lib/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart index 99454ad6..7c5e8513 100644 --- a/lib/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart +++ b/lib/src/visual/components/emoji_picker/emoji_view/emoji_view_config.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes, constant_identifier_names + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License @@ -6,8 +8,8 @@ import 'dart:math'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Callback function for custom view typedef EmojiViewBuilder = @@ -40,6 +42,7 @@ class EmojiViewConfig { this.noRecents = DefaultNoRecentsWidget, this.loadingIndicator = const SizedBox.shrink(), this.buttonMode = ButtonMode.MATERIAL, + // ignore: prefer_asserts_with_message }) : assert(categorySpacing >= 0); /// Number of emojis per row @@ -95,7 +98,7 @@ class EmojiViewConfig { } @override - bool operator ==(other) { + bool operator ==(Object other) { return (other is EmojiViewConfig) && other.columns == columns && other.emojiSizeMax == emojiSizeMax && diff --git a/lib/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart b/lib/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart index d0246401..746f68be 100644 --- a/lib/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart +++ b/lib/src/visual/components/emoji_picker/locales/default_emoji_set_locale.dart @@ -4,8 +4,8 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Default method for locale selection List getDefaultEmojiLocale(Locale locale) { diff --git a/lib/src/visual/components/emoji_picker/search_view.dart b/lib/src/visual/components/emoji_picker/search_view.dart index fd568643..f20330d6 100644 --- a/lib/src/visual/components/emoji_picker/search_view.dart +++ b/lib/src/visual/components/emoji_picker/search_view.dart @@ -1,12 +1,14 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License * Copyright (c) 2024 Stefan Humm */ +import 'package:flutter/material.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; -import 'package:flutter/material.dart'; /// Template class for custom implementation /// Inhert this class to create your own search view @@ -138,7 +140,7 @@ class SearchViewState extends State emojiBoxPosition, emoji, emojiSize, - null, // Todo: check if we can provide the category + null, widget.config, _onSkinTonedEmojiSelected, links[emoji.emoji]!, @@ -205,7 +207,7 @@ class SearchViewConfig { final SearchViewBuilder? customSearchView; @override - bool operator ==(other) { + bool operator ==(Object other) { return other is SearchViewConfig && other.backgroundColor == backgroundColor && other.buttonIconColor == buttonIconColor && @@ -251,7 +253,7 @@ class DefaultSearchViewState extends SearchViewState { constraints.maxWidth, ); - return Container( + return ColoredBox( color: widget.config.searchViewConfig.backgroundColor, child: Column( mainAxisSize: MainAxisSize.min, diff --git a/lib/src/visual/components/emoji_picker/skin_tones/emoji_skin_tones.dart b/lib/src/visual/components/emoji_picker/skin_tones/emoji_skin_tones.dart index 3dbe4303..3e0999d1 100644 --- a/lib/src/visual/components/emoji_picker/skin_tones/emoji_skin_tones.dart +++ b/lib/src/visual/components/emoji_picker/skin_tones/emoji_skin_tones.dart @@ -24,5 +24,11 @@ class SkinTone { static const String dark = '🏿'; /// Return all values as Array - static const values = [light, mediumLight, medium, mediumDark, dark]; + static const List values = [ + light, + mediumLight, + medium, + mediumDark, + dark, + ]; } diff --git a/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_config.dart b/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_config.dart index becd7a18..9f0af1cb 100644 --- a/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_config.dart +++ b/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_config.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_equals_and_hash_code_on_mutable_classes + /* * Modified version of https://github.com/Fintasys/emoji_picker_flutter * MIT License @@ -37,7 +39,7 @@ class SkinToneConfig { final bool rememberSkinTone; @override - bool operator ==(other) { + bool operator ==(Object other) { return (other is SkinToneConfig) && other.enabled == enabled && other.dialogBackgroundColor == dialogBackgroundColor && diff --git a/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_overlay.dart b/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_overlay.dart index 48a736ec..b0df9290 100644 --- a/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_overlay.dart +++ b/lib/src/visual/components/emoji_picker/skin_tones/skin_tone_overlay.dart @@ -6,8 +6,8 @@ import 'dart:collection'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Skin tone overlay mixin mixin SkinToneOverlayStateMixin on State { @@ -52,7 +52,7 @@ mixin SkinToneOverlayStateMixin on State { .toList(); final screenWidth = MediaQuery.of(context).size.width; - final emojiPickerRenderbox = context.findRenderObject() as RenderBox; + final emojiPickerRenderbox = context.findRenderObject()! as RenderBox; final emojiBoxSize = config.emojiViewConfig.getEmojiBoxSize( emojiPickerRenderbox.size.width, ); @@ -74,9 +74,9 @@ mixin SkinToneOverlayStateMixin on State { child: TapRegion( onTapOutside: (_) => closeSkinToneOverlay(), child: Material( - elevation: 4.0, + elevation: 4, child: Container( - padding: const EdgeInsets.symmetric(vertical: 4.0), + padding: const EdgeInsets.symmetric(vertical: 4), color: config.skinToneConfig.dialogBackgroundColor, child: Row( children: [ @@ -120,7 +120,7 @@ mixin SkinToneOverlayStateMixin on State { } double _calculateTopOffset(double emojiBoxSize) { - final verticalPaddingOverlay = 8.0; + const verticalPaddingOverlay = 8.0; final top = -emojiBoxSize - verticalPaddingOverlay; return top; } diff --git a/lib/src/visual/components/emoji_picker/skin_tones/triangle_decoration.dart b/lib/src/visual/components/emoji_picker/skin_tones/triangle_decoration.dart index 7ef75870..48281aef 100644 --- a/lib/src/visual/components/emoji_picker/skin_tones/triangle_decoration.dart +++ b/lib/src/visual/components/emoji_picker/skin_tones/triangle_decoration.dart @@ -43,7 +43,7 @@ class _TriangleShapePainter extends BoxPainter { // per documentation, the size should be always not null here, no need // for null checks final s = configuration.size!; - var path = Path() + final path = Path() ..moveTo(s.width + offset.dx, s.height - _size + offset.dy) ..lineTo(s.width - _size + offset.dx, s.height + offset.dy) ..lineTo(s.width + offset.dx, s.height + offset.dy) diff --git a/lib/src/visual/components/emoji_picker/widgets/backspace_button.dart b/lib/src/visual/components/emoji_picker/widgets/backspace_button.dart index 18fbfdd1..8a622802 100644 --- a/lib/src/visual/components/emoji_picker/widgets/backspace_button.dart +++ b/lib/src/visual/components/emoji_picker/widgets/backspace_button.dart @@ -6,8 +6,8 @@ import 'dart:async'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// Backspace Button Widget class BackspaceButton extends StatefulWidget { @@ -72,7 +72,7 @@ class _BackspaceButtonState extends State { var millisecondsSincePressed = 0; // Callback function executed on each timer tick - void _callback(Timer timer) { + void callback(Timer timer) { // Accumulate elapsed time since the last tick millisecondsSincePressed += callbackInterval.inMilliseconds; @@ -87,7 +87,7 @@ class _BackspaceButtonState extends State { _onBackspacePressedCallbackTimer?.cancel(); _onBackspacePressedCallbackTimer = Timer.periodic( callbackInterval, - _callback, + callback, ); // Reset the elapsed time for the new interval @@ -105,7 +105,7 @@ class _BackspaceButtonState extends State { // Start the initial timer with the short-press interval _onBackspacePressedCallbackTimer = Timer.periodic( callbackInterval, - _callback, + callback, ); } diff --git a/lib/src/visual/components/emoji_picker/widgets/emoji_cell.dart b/lib/src/visual/components/emoji_picker/widgets/emoji_cell.dart index 16463e1d..de5e90af 100644 --- a/lib/src/visual/components/emoji_picker/widgets/emoji_cell.dart +++ b/lib/src/visual/components/emoji_picker/widgets/emoji_cell.dart @@ -4,9 +4,9 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; /// A widget that represents an individual clickable emoji cell. /// Can have a long pressed listener [onSkinToneDialogRequested] that @@ -14,30 +14,30 @@ import 'package:flutter/material.dart'; class EmojiCell extends StatelessWidget { /// Constructor for manually setting all properties const EmojiCell({ - super.key, required this.emoji, required this.emojiSize, required this.emojiBoxSize, - this.categoryEmoji, required this.buttonMode, required this.enableSkinTones, required this.textStyle, required this.skinToneIndicatorColor, - this.onSkinToneDialogRequested, required this.onEmojiSelected, + super.key, + this.categoryEmoji, + this.onSkinToneDialogRequested, }); /// Constructor that can retrieve as much information as possible from /// [Config] EmojiCell.fromConfig({ - super.key, required this.emoji, required this.emojiSize, required this.emojiBoxSize, - this.categoryEmoji, required this.onEmojiSelected, - this.onSkinToneDialogRequested, required Config config, + super.key, + this.categoryEmoji, + this.onSkinToneDialogRequested, }) : buttonMode = config.emojiViewConfig.buttonMode, enableSkinTones = config.skinToneConfig.enabled, textStyle = config.emojiTextStyle, @@ -77,12 +77,12 @@ class EmojiCell extends StatelessWidget { @override Widget build(BuildContext context) { - onPressed() { + void onPressed() { onEmojiSelected(categoryEmoji?.category, emoji); } - onLongPressed() { - final renderBox = context.findRenderObject() as RenderBox; + void onLongPressed() { + final renderBox = context.findRenderObject()! as RenderBox; final emojiBoxPosition = renderBox.localToGlobal(Offset.zero); onSkinToneDialogRequested?.call( emojiBoxPosition, @@ -106,8 +106,8 @@ class EmojiCell extends StatelessWidget { /// Build different Button based on ButtonMode Widget _buildButtonWidget({ required VoidCallback onPressed, - VoidCallback? onLongPressed, required Widget child, + VoidCallback? onLongPressed, }) { if (buttonMode == ButtonMode.MATERIAL) { return MaterialButton( @@ -116,7 +116,7 @@ class EmojiCell extends StatelessWidget { elevation: 0, highlightElevation: 0, padding: EdgeInsets.zero, - shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero), + shape: const RoundedRectangleBorder(), child: child, ); } @@ -126,7 +126,6 @@ class EmojiCell extends StatelessWidget { child: CupertinoButton( onPressed: onPressed, padding: EdgeInsets.zero, - alignment: Alignment.center, child: child, ), ); @@ -142,7 +141,7 @@ class EmojiCell extends StatelessWidget { Widget _buildEmoji() { final emojiText = Text( emoji.emoji, - textScaler: const TextScaler.linear(1.0), + textScaler: TextScaler.noScaling, style: _getEmojiTextStyle(), ); @@ -152,7 +151,7 @@ class EmojiCell extends StatelessWidget { ? Container( decoration: TriangleDecoration( color: skinToneIndicatorColor, - size: 8.0, + size: 8, ), child: emojiText, ) diff --git a/lib/src/visual/views/chats/start_new_chat.view.dart b/lib/src/visual/views/chats/start_new_chat.view.dart index fbdf8595..13dad6ae 100644 --- a/lib/src/visual/views/chats/start_new_chat.view.dart +++ b/lib/src/visual/views/chats/start_new_chat.view.dart @@ -143,7 +143,6 @@ class _StartNewChatView extends State { padding: const EdgeInsets.only( bottom: 40, left: 10, - top: 0, right: 10, ), child: Column( diff --git a/rust/src/services/groups/model.rs b/rust/src/services/groups/model.rs index 8947018f..d90d8267 100644 --- a/rust/src/services/groups/model.rs +++ b/rust/src/services/groups/model.rs @@ -11,6 +11,7 @@ use crate::error::{Result, TwonlyError}; pub(crate) struct GroupRecord { pub group_id: String, pub group_name: String, + #[allow(dead_code)] pub state_version_id: i64, pub state_encryption_key: Option>, pub my_group_private_key: Option>, diff --git a/test/visual/components/emoji_picker/emoji_picker_flutter_test.dart b/test/visual/components/emoji_picker/emoji_picker_flutter_test.dart index a1016ff0..74110218 100644 --- a/test/visual/components/emoji_picker/emoji_picker_flutter_test.dart +++ b/test/visual/components/emoji_picker/emoji_picker_flutter_test.dart @@ -4,9 +4,9 @@ * Copyright (c) 2024 Stefan Humm */ +import 'package:flutter_test/flutter_test.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; -import 'package:flutter_test/flutter_test.dart'; void main() { skinToneTests(); @@ -100,7 +100,7 @@ void skinToneTests() { utils .applyDisplaySkinTone( toneable, - const SkinToneConfig(rememberSkinTone: false), + const SkinToneConfig(), SkinTone.medium, ) .emoji, @@ -123,7 +123,7 @@ void skinToneTests() { void emojiModelTests() { test('encode Emoji', () { - final encode = const Emoji('🤣', 'name'); + const encode = Emoji('🤣', 'name'); expect(encode.toJson(), { 'emoji': '🤣', 'name': 'name', diff --git a/test/visual/components/emoji_picker/emoji_picker_test.dart b/test/visual/components/emoji_picker/emoji_picker_test.dart index d3835a5e..c24bff85 100644 --- a/test/visual/components/emoji_picker/emoji_picker_test.dart +++ b/test/visual/components/emoji_picker/emoji_picker_test.dart @@ -4,10 +4,10 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; // Use for golden tests, helpful in debugging // await expectLater( @@ -21,24 +21,23 @@ void main() { setUp(EmojiPickerInternalUtils.resetCaches); testWidgets('Should allow user to select an emoji', ( - WidgetTester tester, + tester, ) async { - final _controller = TextEditingController(); - Emoji? _emojiSelected; - Category? _categorySelected; + final controller0 = TextEditingController(); + Emoji? emojiSelected; + Category? categorySelected; // Build our app and trigger a frame. await tester.pumpWidget( MaterialApp( home: Scaffold( body: EmojiPicker( - textEditingController: _controller, + textEditingController: controller0, onEmojiSelected: (category, emoji) { - _emojiSelected = emoji; - _categorySelected = category; + emojiSelected = emoji; + categorySelected = category; }, config: const Config( - height: 256, categoryViewConfig: CategoryViewConfig( recentTabBehavior: RecentTabBehavior.NONE, ), @@ -64,20 +63,20 @@ void main() { await tester.pumpAndSettle(); // Check if the emoji is added to the text controller - expect(_controller.text, contains('🙂')); + expect(controller0.text, contains('🙂')); // Check if the emoji been passed to the 'onEmojiSelected' callback expect( - _emojiSelected, + emojiSelected, equals(const Emoji('🙂', 'face | happy | slightly | smile | smiling')), ); // Check if the category been passed to the 'onEmojiSelected' callback - expect(_categorySelected, equals(Category.SMILEYS)); + expect(categorySelected, equals(Category.SMILEYS)); }); testWidgets('Shows the redesigned header and one continuous emoji list', ( - WidgetTester tester, + tester, ) async { var stickerPressed = false; final controller = EmojiPickerController( @@ -137,7 +136,7 @@ void main() { }); testWidgets('Drag handle grows picker from its configured height', ( - WidgetTester tester, + tester, ) async { var showing = true; late StateSetter setHarnessState; @@ -158,7 +157,6 @@ void main() { child: EmojiPicker( controller: pickerController, config: const Config( - height: 256, resizeConfig: ResizeConfig(maxHeight: 420), emojiViewConfig: EmojiViewConfig( backgroundColor: pickerColor, @@ -192,7 +190,7 @@ void main() { final dragIndicator = tester.widget( find.byKey(const Key('emojiPickerDragIndicator')), ); - final dragDecoration = dragIndicator.decoration as BoxDecoration; + final dragDecoration = dragIndicator.decoration! as BoxDecoration; expect(dragDecoration.color, ThemeData.dark().colorScheme.outline); expect(dragDecoration.borderRadius, BorderRadius.circular(32)); @@ -212,13 +210,12 @@ void main() { expect(tester.getSize(picker).height, 256); }); - testWidgets('Drag handle can be hidden', (WidgetTester tester) async { + testWidgets('Drag handle can be hidden', (tester) async { await tester.pumpWidget( const MaterialApp( home: Scaffold( body: EmojiPicker( config: Config( - height: 256, resizeConfig: ResizeConfig(showDragHandle: false), categoryViewConfig: CategoryViewConfig( recentTabBehavior: RecentTabBehavior.NONE, @@ -240,25 +237,25 @@ void main() { }); testWidgets('Should allow to select an emoji with skintone on longPress', ( - WidgetTester tester, + tester, ) async { - final _controller = TextEditingController(); - final _utils = EmojiPickerUtils(); - final emoji = const Emoji('👍', 'Thumbs Up', hasSkinTone: true); - Emoji? _emojiSelected; - Category? _categorySelected; + final controller0 = TextEditingController(); + final utils = EmojiPickerUtils(); + const emoji = Emoji('👍', 'Thumbs Up', hasSkinTone: true); + Emoji? emojiSelected; + Category? categorySelected; // Build our app and trigger a frame. await tester.pumpWidget( MaterialApp( home: Scaffold( body: Padding( - padding: const EdgeInsets.only(top: 64.0), + padding: const EdgeInsets.only(top: 64), child: EmojiPicker( - textEditingController: _controller, + textEditingController: controller0, onEmojiSelected: (category, emoji) { - _emojiSelected = emoji; - _categorySelected = category; + emojiSelected = emoji; + categorySelected = category; }, config: const Config( height: 500, @@ -298,7 +295,7 @@ void main() { Finder? skinToneVariantToFind; for (var i = 0; i < SkinTone.values.length; i++) { skinToneVariantToFind = find.text( - _utils.applySkinTone(emoji, SkinTone.values[i]).emoji, + utils.applySkinTone(emoji, SkinTone.values[i]).emoji, ); // Verify if we can find the skintone variant expect(skinToneVariantToFind, findsOneWidget); @@ -308,24 +305,24 @@ void main() { await tester.tap(skinToneVariantToFind!); // Check if the emoji is added to the text controller - expect(_controller.text, contains('👍🏿')); + expect(controller0.text, contains('👍🏿')); // Check if the emoji been passed to the 'onEmojiSelected' callback - expect(_emojiSelected?.emoji, equals('👍🏿')); + expect(emojiSelected?.emoji, equals('👍🏿')); expect( - _emojiSelected?.name, + emojiSelected?.name, equals('+1 | good | hand | like | thumb | up | yes'), ); - expect(_emojiSelected?.hasSkinTone, equals(true)); + expect(emojiSelected?.hasSkinTone, equals(true)); // Check if the category been passed to the 'onEmojiSelected' callback - expect(_categorySelected, equals(Category.SMILEYS)); + expect(categorySelected, equals(Category.SMILEYS)); }); testWidgets('Clips overflow when constrained tighter than natural height', ( - WidgetTester tester, + tester, ) async { - final _controller = TextEditingController(); + final controller0 = TextEditingController(); // Constrain the picker far below the natural sum of the category bar // and bottom action bar to force the inner Column to overflow (#256). @@ -337,7 +334,7 @@ void main() { width: 300, height: 30, child: EmojiPicker( - textEditingController: _controller, + textEditingController: controller0, config: const Config( height: 30, categoryViewConfig: CategoryViewConfig( diff --git a/test/visual/components/emoji_picker/emoji_text_editing_controller_test.dart b/test/visual/components/emoji_picker/emoji_text_editing_controller_test.dart index e9306098..6ffd96f8 100644 --- a/test/visual/components/emoji_picker/emoji_text_editing_controller_test.dart +++ b/test/visual/components/emoji_picker/emoji_text_editing_controller_test.dart @@ -4,18 +4,18 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; void main() { group('EmojiTextEditingController', () { testWidgets('should apply emojiTextStyle to emojis', (tester) async { await tester.pumpWidget( Builder( - builder: (BuildContext context) { - final emojiStyle = const TextStyle(color: Colors.red); - final regularStyle = const TextStyle(color: Colors.black); + builder: (context) { + const emojiStyle = TextStyle(color: Colors.red); + const regularStyle = TextStyle(color: Colors.black); final controller = EmojiTextEditingController( text: 'Hello 👋 World', emojiTextStyle: emojiStyle, diff --git a/test/visual/components/emoji_picker/emoji_text_style_test.dart b/test/visual/components/emoji_picker/emoji_text_style_test.dart index b3bc876a..06033e7d 100644 --- a/test/visual/components/emoji_picker/emoji_text_style_test.dart +++ b/test/visual/components/emoji_picker/emoji_text_style_test.dart @@ -4,17 +4,17 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; void main() { group('EmojiTextStyle', () { testWidgets('should apply EmojiTextStyle to emoji in text', (tester) async { await tester.pumpWidget( Builder( - builder: (BuildContext context) { - final text = 'Hello 👋 World'; + builder: (context) { + const text = 'Hello 👋 World'; final result = EmojiPickerUtils().setEmojiTextStyle( text, emojiStyle: const TextStyle(color: Colors.red), diff --git a/test/visual/components/emoji_picker/recent_emoji_state_test.dart b/test/visual/components/emoji_picker/recent_emoji_state_test.dart index 79942d2d..ca6f3fea 100644 --- a/test/visual/components/emoji_picker/recent_emoji_state_test.dart +++ b/test/visual/components/emoji_picker/recent_emoji_state_test.dart @@ -4,19 +4,19 @@ * Copyright (c) 2024 Stefan Humm */ -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; -import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker.dart'; +import 'package:twonly/src/visual/components/emoji_picker/emoji_picker_internal_utils.dart'; /// Test harness that lets us trigger a rebuild of [EmojiPicker] from its /// parent, mimicking an unrelated `setState()` higher up in the widget tree. class _RebuildHarness extends StatefulWidget { const _RebuildHarness({ - super.key, required this.pickerKey, required this.config, + super.key, }); final GlobalKey pickerKey; @@ -59,10 +59,6 @@ void main() { const config = Config( height: 400, - categoryViewConfig: CategoryViewConfig( - initCategory: Category.RECENT, - recentTabBehavior: RecentTabBehavior.RECENT, - ), ); // Deliberately not part of the built-in set. In the continuous picker a