Skip to content

Commit

Permalink
refactor: use named records for the sortbox
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolas Rimikis <[email protected]>
  • Loading branch information
Leptopoda committed Oct 28, 2023
1 parent aa54c23 commit 559e122
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 38 deletions.
4 changes: 2 additions & 2 deletions packages/neon/neon/lib/src/sort_box/sort_box_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SortBoxBuilder<T extends Enum, R> extends StatelessWidget {
final SortBoxWidgetBuilder<R> builder;

/// Pre sorts input.
final Set<(T property, SortBoxOrder order)>? presort;
final Set<Box<T>>? presort;

@override
Widget build(final BuildContext context) {
Expand All @@ -52,7 +52,7 @@ class SortBoxBuilder<T extends Enum, R> extends StatelessWidget {
builder: (final context, final property, final _) => ValueListenableBuilder<SortBoxOrder>(
valueListenable: sortBoxOrder,
builder: (final context, final order, final _) {
final box = (property, order);
final box = (property: property, order: order);

return builder(context, sortBox.sort(input, box, presort));
},
Expand Down
4 changes: 2 additions & 2 deletions packages/neon/neon_files/lib/sort/files.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ final filesSortBox = SortBox<FilesSortProperty, WebDavFile>(
},
{
FilesSortProperty.modifiedDate: {
(FilesSortProperty.name, SortBoxOrder.ascending),
(property: FilesSortProperty.name, order: SortBoxOrder.ascending),
},
FilesSortProperty.size: {
(FilesSortProperty.name, SortBoxOrder.ascending),
(property: FilesSortProperty.name, order: SortBoxOrder.ascending),
},
},
);
2 changes: 1 addition & 1 deletion packages/neon/neon_files/lib/widgets/browser_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
sortProperty: widget.bloc.options.filesSortPropertyOption,
sortBoxOrder: widget.bloc.options.filesSortBoxOrderOption,
presort: const {
(FilesSortProperty.isFolder, SortBoxOrder.ascending),
(property: FilesSortProperty.isFolder, order: SortBoxOrder.ascending),
},
input: files,
builder: (final context, final sorted) {
Expand Down
4 changes: 2 additions & 2 deletions packages/neon/neon_news/lib/sort/articles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ final articlesSortBox = SortBox<ArticlesSortProperty, news.Article>(
},
{
ArticlesSortProperty.alphabetical: {
(ArticlesSortProperty.publishDate, SortBoxOrder.descending),
(property: ArticlesSortProperty.publishDate, order: SortBoxOrder.descending),
},
ArticlesSortProperty.byFeed: {
(ArticlesSortProperty.alphabetical, SortBoxOrder.ascending),
(property: ArticlesSortProperty.alphabetical, order: SortBoxOrder.ascending),
},
},
);
4 changes: 2 additions & 2 deletions packages/neon/neon_news/lib/sort/feeds.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ final feedsSortBox = SortBox<FeedsSortProperty, news.Feed>(
},
{
FeedsSortProperty.alphabetical: {
(FeedsSortProperty.unreadCount, SortBoxOrder.descending),
(property: FeedsSortProperty.unreadCount, order: SortBoxOrder.descending),
},
FeedsSortProperty.unreadCount: {
(FeedsSortProperty.alphabetical, SortBoxOrder.ascending),
(property: FeedsSortProperty.alphabetical, order: SortBoxOrder.ascending),
},
},
);
10 changes: 5 additions & 5 deletions packages/neon/neon_news/lib/sort/folders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ part of '../neon_news.dart';

final foldersSortBox = SortBox<FoldersSortProperty, FolderFeedsWrapper>(
{
FoldersSortProperty.alphabetical: (final folderFeedsWrapper) => folderFeedsWrapper.$1.name.toLowerCase(),
FoldersSortProperty.unreadCount: (final folderFeedsWrapper) => folderFeedsWrapper.$3,
FoldersSortProperty.alphabetical: (final folderFeedsWrapper) => folderFeedsWrapper.folder.name.toLowerCase(),
FoldersSortProperty.unreadCount: (final folderFeedsWrapper) => folderFeedsWrapper.unreadCount,
},
{
FoldersSortProperty.alphabetical: {
(FoldersSortProperty.unreadCount, SortBoxOrder.descending),
(property: FoldersSortProperty.unreadCount, order: SortBoxOrder.descending),
},
FoldersSortProperty.unreadCount: {
(FoldersSortProperty.alphabetical, SortBoxOrder.ascending),
(property: FoldersSortProperty.alphabetical, order: SortBoxOrder.ascending),
},
},
);

typedef FolderFeedsWrapper = (news.Folder folder, int feedCount, int unreadCount);
typedef FolderFeedsWrapper = ({news.Folder folder, int feedCount, int unreadCount});
4 changes: 2 additions & 2 deletions packages/neon/neon_news/lib/widgets/folders_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class NewsFoldersView extends StatelessWidget {
final feedCount = feedsInFolder.length;
final unreadCount = feedsInFolder.fold(0, (final a, final b) => a + b.unreadCount!);

return (folder, feedCount, unreadCount);
return (folder: folder, feedCount: feedCount, unreadCount: unreadCount);
}).toList()
: null,
builder: (final context, final sorted) => NeonListView(
Expand All @@ -45,7 +45,7 @@ class NewsFoldersView extends StatelessWidget {
final BuildContext context,
final FolderFeedsWrapper folderFeedsWrapper,
) {
final (folder, feedCount, unreadCount) = folderFeedsWrapper;
final (folder: folder, feedCount: feedCount, unreadCount: unreadCount) = folderFeedsWrapper;
return ListTile(
title: Text(
folder.name,
Expand Down
2 changes: 1 addition & 1 deletion packages/neon/neon_notes/lib/sort/categories.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ final categoriesSortBox = SortBox<CategoriesSortProperty, NoteCategory>(
},
{
CategoriesSortProperty.notesCount: {
(CategoriesSortProperty.alphabetical, SortBoxOrder.ascending),
(property: CategoriesSortProperty.alphabetical, order: SortBoxOrder.ascending),
},
},
);
Expand Down
4 changes: 2 additions & 2 deletions packages/neon/neon_notes/lib/sort/notes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ final notesSortBox = SortBox<NotesSortProperty, notes.Note>(
},
{
NotesSortProperty.alphabetical: {
(NotesSortProperty.lastModified, SortBoxOrder.descending),
(property: NotesSortProperty.lastModified, order: SortBoxOrder.descending),
},
NotesSortProperty.lastModified: {
(NotesSortProperty.alphabetical, SortBoxOrder.ascending),
(property: NotesSortProperty.alphabetical, order: SortBoxOrder.ascending),
},
},
);
2 changes: 1 addition & 1 deletion packages/neon/neon_notes/lib/widgets/notes_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class NotesView extends StatelessWidget {
builder: (final context, final notesList) => SortBoxBuilder<NotesSortProperty, notes.Note>(
sortBox: notesSortBox,
presort: const {
(NotesSortProperty.favorite, SortBoxOrder.ascending),
(property: NotesSortProperty.favorite, order: SortBoxOrder.ascending),
},
sortProperty: bloc.options.notesSortPropertyOption,
sortBoxOrder: bloc.options.notesSortBoxOrderOption,
Expand Down
20 changes: 12 additions & 8 deletions packages/sort_box/lib/sort_box.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/// Signature of a function returning a [Comparable].
typedef ComparableGetter<T> = Comparable<Object> Function(T);

/// The box to sort by.
///
/// A box contains a property and a corresponding order.
typedef Box<T> = ({T property, SortBoxOrder order});

/// Sorting Box to sort [List]s on multiple properties.
class SortBox<T extends Enum, R> {
/// Constructs a new SortBox.
Expand All @@ -17,7 +22,7 @@ class SortBox<T extends Enum, R> {
/// A mapping of values [T] to their *Boxes*.
///
/// The Boxes are applied if two elements are considered equal regarding their property [T].
final Map<T, Set<(T property, SortBoxOrder order)>> _boxes;
final Map<T, Set<Box<T>>> _boxes;

/// Sorts the [input] list according to their [box].
///
Expand All @@ -28,8 +33,8 @@ class SortBox<T extends Enum, R> {
/// This function sorts the input in place and a reference to it mutating the provided list.
List<R> sort(
final List<R> input,
final (T property, SortBoxOrder order) box, [
final Set<(T property, SortBoxOrder order)>? presort,
final Box<T> box, [
final Set<Box<T>>? presort,
]) {
if (input.length <= 1) {
return input;
Expand All @@ -38,7 +43,7 @@ class SortBox<T extends Enum, R> {
final boxes = {
...?presort,
box,
...?_boxes[box.$1],
...?_boxes[box.property],
};

final sorted = input..sort((final item1, final item2) => _compare(item1, item2, boxes.iterator..moveNext()));
Expand All @@ -49,16 +54,15 @@ class SortBox<T extends Enum, R> {
int _compare(
final R item1,
final R item2,
final Iterator<(T property, SortBoxOrder order)> iterator,
final Iterator<Box<T>> iterator,
) {
final box = iterator.current;
final (property, sortBoxOrder) = box;
final comparableGetter = _properties[property]!;
final comparableGetter = _properties[box.property]!;

final comparable1 = comparableGetter(item1);
final comparable2 = comparableGetter(item2);

final order = switch (sortBoxOrder) {
final order = switch (box.order) {
SortBoxOrder.ascending => comparable1.compareTo(comparable2),
SortBoxOrder.descending => comparable2.compareTo(comparable1),
};
Expand Down
20 changes: 10 additions & 10 deletions packages/sort_box/test/sort_box_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ void main() {
},
{
FruitSort.alphabetical: {
(FruitSort.count, SortBoxOrder.ascending),
(property: FruitSort.count, order: SortBoxOrder.ascending),
},
FruitSort.count: {
(FruitSort.alphabetical, SortBoxOrder.ascending),
(property: FruitSort.alphabetical, order: SortBoxOrder.ascending),
},
FruitSort.price: {
(FruitSort.alphabetical, SortBoxOrder.descending),
(FruitSort.count, SortBoxOrder.ascending),
(property: FruitSort.alphabetical, order: SortBoxOrder.descending),
(property: FruitSort.count, order: SortBoxOrder.ascending),
},
},
);
Expand All @@ -52,7 +52,7 @@ void main() {
const Fruit('Banana', 4),
const Fruit('Apple', 5),
];
final sorted = sortBox.sort(fruits, (FruitSort.alphabetical, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.alphabetical, order: SortBoxOrder.ascending));

for (var i = 0; i < 3; i++) {
expect(sorted[i].name, 'Apple');
Expand All @@ -70,7 +70,7 @@ void main() {
const Fruit('Banana', 2),
const Fruit('Apple', 3),
];
final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending));

final names = ['Apple', 'Banana', 'Apple', 'Apple', 'Banana'];
for (var i = 0; i < 5; i++) {
Expand All @@ -91,7 +91,7 @@ void main() {
const Fruit('Banana', 1),
const Fruit('Apple', 2),
];
final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending));

final names = ['Apple', 'Banana', 'Apple', 'Apple', 'Banana'];
for (var i = 0; i < 5; i++) {
Expand All @@ -112,7 +112,7 @@ void main() {
const Fruit('Banana', 2),
const Fruit('Apple', 5),
];
final sorted = sortBox.sort(fruits, (FruitSort.alphabetical, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.alphabetical, order: SortBoxOrder.ascending));

for (var i = 0; i < 3; i++) {
expect(sorted[i].name, 'Apple');
Expand All @@ -134,7 +134,7 @@ void main() {
const Fruit('Elderberry', 1),
const Fruit('Damson', 1),
];
final sorted = sortBox.sort(fruits, (FruitSort.count, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.count, order: SortBoxOrder.ascending));

final names = ['Apple', 'Banana', 'Coconut', 'Damson', 'Elderberry'];
for (var i = 0; i < 5; i++) {
Expand All @@ -152,7 +152,7 @@ void main() {
const Fruit('Banana', 1, 3),
const Fruit('Apple', 2, 3),
];
final sorted = sortBox.sort(fruits, (FruitSort.price, SortBoxOrder.ascending));
final sorted = sortBox.sort(fruits, (property: FruitSort.price, order: SortBoxOrder.ascending));

final price = [0, 2, 3, 3, 3];
for (var i = 0; i < 5; i++) {
Expand Down

0 comments on commit 559e122

Please sign in to comment.