TF-3996 Group context menu actions when opened email

This commit is contained in:
dab246
2025-09-03 12:31:47 +07:00
committed by Dat H. Pham
parent 22379dbbbd
commit b66d84ecb8
10 changed files with 168 additions and 10 deletions
@@ -0,0 +1,44 @@
extension IterableExtension<T> on Iterable<T> {
/// Group elements by [keySelector].
/// If [sortKeys] = true, the keys will be sorted in ascending order,
/// key == -1 will always be at the bottom (applies to int keys).
Map<K, List<T>> groupBy<K>(
K Function(T element) keySelector, {
bool sortKeys = false,
}) {
final map = <K, List<T>>{};
for (final element in this) {
final key = keySelector(element);
map.putIfAbsent(key, () => []).add(element);
}
Iterable<K> sortedKeys;
if (sortKeys && K == int) {
sortedKeys = map.keys.toList()
..sort((a, b) {
final ai = a as int;
final bi = b as int;
if (ai == -1 && bi != -1) return 1;
if (bi == -1 && ai != -1) return -1;
return ai.compareTo(bi);
});
} else if (sortKeys) {
sortedKeys = map.keys.toList()
..sort((a, b) {
if (a is Comparable && b is Comparable) {
return (a as Comparable).compareTo(b);
}
return 0;
});
} else {
sortedKeys = map.keys;
}
final result = <K, List<T>>{};
for (final key in sortedKeys) {
result[key] = map[key]!;
}
return result;
}
}
@@ -0,0 +1,57 @@
import 'package:core/presentation/extensions/iterable_extension.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('IterableExtension', () {
group('groupBy method', () {
test('group by int keys without sort', () {
final data = [1, 2, 3, 4];
final result = data.groupBy((e) => e % 2);
expect(result.keys.toList(), [1, 0]);
expect(result[0], [2, 4]);
expect(result[1], [1, 3]);
});
test('group by int keys with sort, -1 goes last', () {
final data = [10, 20, 30, 40];
final categories = [2, -1, 1, 3];
final result = data.groupBy((e) {
final idx = data.indexOf(e);
return categories[idx];
}, sortKeys: true);
expect(result.keys.toList(), [1, 2, 3, -1]);
expect(result[1], [30]);
expect(result[2], [10]);
expect(result[3], [40]);
expect(result[-1], [20]);
});
test('group by string keys with sort', () {
final words = ['apple', 'banana', 'cherry', 'avocado'];
final result = words.groupBy((w) => w[0], sortKeys: true);
expect(result.keys.toList(), ['a', 'b', 'c']);
expect(result['a'], ['apple', 'avocado']);
expect(result['b'], ['banana']);
expect(result['c'], ['cherry']);
});
test('group with multiple elements in same group', () {
final data = ['cat', 'car', 'dog', 'door'];
final result = data.groupBy((s) => s[0]);
expect(result['c'], ['cat', 'car']);
expect(result['d'], ['dog', 'door']);
});
test('empty list returns empty map', () {
final data = <int>[];
final result = data.groupBy((e) => e);
expect(result, isEmpty);
});
});
});
}