|
1 | | -// ignore_for_file: constant_identifier_names |
2 | | - |
3 | 1 | import 'package:equatable/equatable.dart'; |
4 | 2 | import 'package:json_annotation/json_annotation.dart'; |
5 | | -import 'package:stream_chat/src/core/models/comparable_field.dart'; |
6 | 3 |
|
7 | 4 | part 'requests.g.dart'; |
8 | 5 |
|
9 | | -/// A list of [SortOption]s that define a sorting order for elements of type [T] |
10 | | -/// |
11 | | -/// When multiple sort options are provided, they are applied in sequence |
12 | | -/// until a non-equal comparison is found. |
13 | | -/// |
14 | | -/// Example: `Sort<ChannelState>([pinnedAtSort, lastMessageAtSort])` |
15 | | -typedef SortOrder<T extends ComparableFieldProvider> = List<SortOption<T>>; |
16 | | - |
17 | | -/// Extension that allows a [SortOrder] to be used as a comparator function. |
18 | | -extension CompositeComparator<T extends ComparableFieldProvider> |
19 | | - on SortOrder<T> { |
20 | | - /// Compares two objects using all sort options in sequence. |
21 | | - /// |
22 | | - /// Returns the first non-zero comparison result, or 0 if all comparisons |
23 | | - /// result in equality. |
24 | | - /// |
25 | | - /// ```dart |
26 | | - /// channels.sort(mySort.compare); |
27 | | - /// ``` |
28 | | - int compare(T a, T b) { |
29 | | - for (final sortOption in this) { |
30 | | - final comparison = sortOption.compare(a, b); |
31 | | - if (comparison != 0) return comparison; |
32 | | - } |
33 | | - |
34 | | - return 0; // All comparisons were equal |
35 | | - } |
36 | | -} |
37 | | - |
38 | | -/// A sort specification for objects that implement [ComparableFieldProvider]. |
39 | | -/// |
40 | | -/// Defines a field to sort by and a direction (ascending or descending). |
41 | | -/// Can use a custom comparator or create a default one based on the field name. |
42 | | -/// |
43 | | -/// Example: |
44 | | -/// ```dart |
45 | | -/// // Sort channels by last message date in descending order |
46 | | -/// final sort = SortOption<ChannelState>("last_message_at"); |
47 | | -/// ``` |
48 | | -@JsonSerializable(includeIfNull: false) |
49 | | -class SortOption<T extends ComparableFieldProvider> { |
50 | | - /// Creates a new SortOption instance with the specified field and direction. |
51 | | - /// |
52 | | - /// ```dart |
53 | | - /// final sorting = SortOption("last_message_at") // Default: descending order |
54 | | - /// ``` |
55 | | - const SortOption( |
56 | | - this.field, { |
57 | | - this.direction = SortOption.DESC, |
58 | | - Comparator<T>? comparator, |
59 | | - }) : _comparator = comparator; |
60 | | - |
61 | | - /// Creates a SortOption for descending order sorting by the specified field. |
62 | | - /// |
63 | | - /// Example: |
64 | | - /// ```dart |
65 | | - /// // Sort channels by last message date in descending order |
66 | | - /// final sort = SortOption.desc("last_message_at"); |
67 | | - /// ``` |
68 | | - const SortOption.desc( |
69 | | - this.field, { |
70 | | - Comparator<T>? comparator, |
71 | | - }) : direction = SortOption.DESC, |
72 | | - _comparator = comparator; |
73 | | - |
74 | | - /// Creates a SortOption for ascending order sorting by the specified field. |
75 | | - /// |
76 | | - /// Example: |
77 | | - /// ```dart |
78 | | - /// // Sort channels by name in ascending order |
79 | | - /// final sort = SortOption.asc("name"); |
80 | | - /// ``` |
81 | | - const SortOption.asc( |
82 | | - this.field, { |
83 | | - Comparator<T>? comparator, |
84 | | - }) : direction = SortOption.ASC, |
85 | | - _comparator = comparator; |
86 | | - |
87 | | - /// Create a new instance from JSON. |
88 | | - factory SortOption.fromJson(Map<String, dynamic> json) => |
89 | | - _$SortOptionFromJson(json); |
90 | | - |
91 | | - /// Ascending order (1) |
92 | | - static const ASC = 1; |
93 | | - |
94 | | - /// Descending order (-1) |
95 | | - static const DESC = -1; |
96 | | - |
97 | | - /// The field name to sort by |
98 | | - final String field; |
99 | | - |
100 | | - /// The sort direction (ASC or DESC) |
101 | | - final int direction; |
102 | | - |
103 | | - /// Compares two objects of type T using the specified field and direction. |
104 | | - /// |
105 | | - /// Returns: |
106 | | - /// - 0 if both objects are equal |
107 | | - /// - 1 if the first object is greater than the second |
108 | | - /// - -1 if the first object is less than the second |
109 | | - /// |
110 | | - /// Handles null values by treating null as less than any non-null value. |
111 | | - /// |
112 | | - /// ```dart |
113 | | - /// final sortOption = SortOption<ChannelState>("last_message_at"); |
114 | | - /// final sortedChannels = channels.sort(sortOption.compare); |
115 | | - /// ``` |
116 | | - int compare(T a, T b) => direction * comparator(a, b); |
117 | | - |
118 | | - /// Returns a comparator function for sorting objects of type T. |
119 | | - @JsonKey(includeToJson: false, includeFromJson: false) |
120 | | - Comparator<T> get comparator { |
121 | | - if (_comparator case final comparator?) return comparator; |
122 | | - |
123 | | - return (T a, T b) { |
124 | | - final aValue = a.getComparableField(field); |
125 | | - final bValue = b.getComparableField(field); |
126 | | - |
127 | | - // Handle null values |
128 | | - if (aValue == null && bValue == null) return 0; |
129 | | - if (aValue == null) return -1; |
130 | | - if (bValue == null) return 1; |
131 | | - |
132 | | - return aValue.compareTo(bValue); |
133 | | - }; |
134 | | - } |
135 | | - |
136 | | - final Comparator<T>? _comparator; |
137 | | - |
138 | | - /// Converts this option to JSON. |
139 | | - Map<String, dynamic> toJson() => _$SortOptionToJson(this); |
140 | | -} |
141 | | - |
142 | 6 | /// Pagination options. |
143 | 7 | @JsonSerializable(includeIfNull: false) |
144 | 8 | class PaginationParams extends Equatable { |
|
0 commit comments