Merge pull request #688 from GetStream/ref/deprecate-pagination-params
feat(ui, core): deprecate `.pagination` in favor of `.limit`
This commit is contained in:
@@ -1,14 +1,30 @@
|
||||
## 2.2.1
|
||||
|
||||
🛑️ Breaking Changes from `2.2.1`
|
||||
⚠️ Deprecated
|
||||
|
||||
- `MessageSearchListView` paginationParams property is now non-nullable with a default value.
|
||||
- `MessageSearchListView` `paginationParams` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
paginationParams = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
- `UserListView` pagination property is now non-nullable with a default value.
|
||||
- `UserListView` `pagination` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
pagination = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
- `ChannelListView` `pagination` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
pagination = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
|
||||
🔄 Changed
|
||||
|
||||
@@ -59,7 +59,7 @@ typedef ViewInfoCallback = void Function(Channel);
|
||||
/// Modify it to change the widget appearance.
|
||||
class ChannelListView extends StatefulWidget {
|
||||
/// Instantiate a new ChannelListView
|
||||
const ChannelListView({
|
||||
ChannelListView({
|
||||
Key? key,
|
||||
this.filter,
|
||||
this.sort,
|
||||
@@ -68,9 +68,12 @@ class ChannelListView extends StatefulWidget {
|
||||
this.presence = false,
|
||||
this.memberLimit,
|
||||
this.messageLimit,
|
||||
this.pagination = const PaginationParams(
|
||||
limit: 25,
|
||||
),
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.pagination,
|
||||
int? limit,
|
||||
this.onChannelTap,
|
||||
this.onChannelLongPress,
|
||||
this.channelWidget,
|
||||
@@ -92,7 +95,8 @@ class ChannelListView extends StatefulWidget {
|
||||
this.onDeletePressed,
|
||||
this.swipeActions,
|
||||
this.channelListController,
|
||||
}) : super(key: key);
|
||||
}) : limit = limit ?? pagination?.limit ?? 25,
|
||||
super(key: key);
|
||||
|
||||
/// If true a default swipe to action behaviour will be added to this widget
|
||||
final bool swipeToAction;
|
||||
@@ -129,7 +133,14 @@ class ChannelListView extends StatefulWidget {
|
||||
/// limit: the number of channels to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams pagination;
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? pagination;
|
||||
|
||||
/// The amount of channels requested per API call.
|
||||
final int limit;
|
||||
|
||||
/// Function called when tapping on a channel
|
||||
/// By default it calls [Navigator.push] building a [MaterialPageRoute]
|
||||
@@ -218,7 +229,7 @@ class _ChannelListViewState extends State<ChannelListView> {
|
||||
presence: widget.presence,
|
||||
memberLimit: widget.memberLimit,
|
||||
messageLimit: widget.messageLimit,
|
||||
pagination: widget.pagination,
|
||||
limit: widget.limit,
|
||||
channelListController: _channelListController,
|
||||
listBuilder: widget.listBuilder ?? _buildListView,
|
||||
emptyBuilder: widget.emptyBuilder ?? _buildEmptyWidget,
|
||||
|
||||
@@ -53,12 +53,17 @@ typedef EmptyMessageSearchBuilder = Widget Function(
|
||||
/// Modify it to change the widget appearance.
|
||||
class MessageSearchListView extends StatefulWidget {
|
||||
/// Instantiate a new MessageSearchListView
|
||||
const MessageSearchListView({
|
||||
MessageSearchListView({
|
||||
Key? key,
|
||||
required this.filters,
|
||||
this.messageQuery,
|
||||
this.sortOptions,
|
||||
this.paginationParams = const PaginationParams(limit: 30),
|
||||
@Deprecated(
|
||||
"'paginationParams' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.paginationParams,
|
||||
int? limit,
|
||||
this.messageFilters,
|
||||
this.separatorBuilder,
|
||||
this.itemBuilder,
|
||||
@@ -71,7 +76,8 @@ class MessageSearchListView extends StatefulWidget {
|
||||
this.loadingBuilder,
|
||||
this.childBuilder,
|
||||
this.messageSearchListController,
|
||||
}) : super(key: key);
|
||||
}) : limit = limit ?? paginationParams?.limit ?? 30,
|
||||
super(key: key);
|
||||
|
||||
/// Message String to search on
|
||||
final String? messageQuery;
|
||||
@@ -93,7 +99,14 @@ class MessageSearchListView extends StatefulWidget {
|
||||
/// limit: the number of users to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams paginationParams;
|
||||
@Deprecated(
|
||||
"'paginationParams' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? paginationParams;
|
||||
|
||||
/// The amount of messages requested per API call.
|
||||
final int limit;
|
||||
|
||||
/// The message query filters to use.
|
||||
/// You can query on any of the custom fields you've defined on the [Channel].
|
||||
@@ -152,7 +165,7 @@ class _MessageSearchListViewState extends State<MessageSearchListView> {
|
||||
filters: widget.filters,
|
||||
sortOptions: widget.sortOptions,
|
||||
messageQuery: widget.messageQuery,
|
||||
paginationParams: widget.paginationParams,
|
||||
limit: widget.limit,
|
||||
messageFilters: widget.messageFilters,
|
||||
messageSearchListController: _messageSearchListController,
|
||||
emptyBuilder: widget.emptyBuilder ??
|
||||
|
||||
@@ -46,12 +46,17 @@ typedef UserItemBuilder = Widget Function(BuildContext, User, bool);
|
||||
/// Modify it to change the widget appearance.
|
||||
class UserListView extends StatefulWidget {
|
||||
/// Instantiate a new UserListView
|
||||
const UserListView({
|
||||
UserListView({
|
||||
Key? key,
|
||||
this.filter = const Filter.empty(),
|
||||
this.sort,
|
||||
this.presence,
|
||||
this.pagination = const PaginationParams(limit: 30),
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.pagination,
|
||||
int? limit,
|
||||
this.onUserTap,
|
||||
this.onUserLongPress,
|
||||
this.userWidget,
|
||||
@@ -71,6 +76,7 @@ class UserListView extends StatefulWidget {
|
||||
crossAxisCount == 1 || groupAlphabetically == false,
|
||||
'Cannot group alphabetically when crossAxisCount > 1',
|
||||
),
|
||||
limit = limit ?? pagination?.limit ?? 30,
|
||||
super(key: key);
|
||||
|
||||
/// The query filters to use.
|
||||
@@ -94,7 +100,14 @@ class UserListView extends StatefulWidget {
|
||||
/// limit: the number of users to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams pagination;
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? pagination;
|
||||
|
||||
/// The amount of users requested per API call.
|
||||
final int limit;
|
||||
|
||||
/// Function called when tapping on a channel
|
||||
/// By default it calls [Navigator.push] building a [MaterialPageRoute]
|
||||
@@ -185,7 +198,7 @@ class _UserListViewState extends State<UserListView>
|
||||
),
|
||||
listBuilder:
|
||||
widget.listBuilder ?? (context, list) => _buildListView(list),
|
||||
pagination: widget.pagination,
|
||||
limit: widget.limit,
|
||||
sort: widget.sort,
|
||||
filter: widget.filter,
|
||||
presence: widget.presence,
|
||||
|
||||
@@ -62,7 +62,7 @@ void main() {
|
||||
return Scaffold(
|
||||
body: StreamChannel(
|
||||
channel: MockChannel(),
|
||||
child: const ChannelListView(),
|
||||
child: ChannelListView(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -56,7 +56,7 @@ void main() {
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
_context = context;
|
||||
return const Scaffold(
|
||||
return Scaffold(
|
||||
body: UsersBloc(
|
||||
child: UserListView(),
|
||||
),
|
||||
@@ -85,7 +85,7 @@ void main() {
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
_context = context;
|
||||
return const Scaffold(
|
||||
return Scaffold(
|
||||
body: UsersBloc(
|
||||
child: UserListView(),
|
||||
),
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
## Upcoming
|
||||
|
||||
🛑️ Breaking Changes from `2.2.1`
|
||||
⚠️ Deprecated
|
||||
|
||||
- `MessageSearchListViewCore` paginationParams property is now non-nullable with a default value.
|
||||
- `MessageSearchListViewCore` `paginationParams` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
paginationParams = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
- `UserListViewCore` pagination property is now non-nullable with a default value.
|
||||
- `UserListViewCore` `pagination` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
pagination = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
- `ChannelListViewCore` `pagination` property is now deprecated in favor of `limit`.
|
||||
```dart
|
||||
// previous
|
||||
pagination = const PaginationParams(limit: 30)
|
||||
|
||||
// new
|
||||
limit = 30
|
||||
```
|
||||
|
||||
🔄 Changed
|
||||
|
||||
@@ -56,7 +56,7 @@ import 'package:stream_chat_flutter_core/src/typedef.dart';
|
||||
/// information about the channels.
|
||||
class ChannelListCore extends StatefulWidget {
|
||||
/// Instantiate a new ChannelListView
|
||||
const ChannelListCore({
|
||||
ChannelListCore({
|
||||
Key? key,
|
||||
required this.errorBuilder,
|
||||
required this.emptyBuilder,
|
||||
@@ -69,11 +69,15 @@ class ChannelListCore extends StatefulWidget {
|
||||
this.memberLimit,
|
||||
this.messageLimit,
|
||||
this.sort,
|
||||
this.pagination = const PaginationParams(
|
||||
limit: 25,
|
||||
),
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.pagination,
|
||||
this.channelListController,
|
||||
}) : super(key: key);
|
||||
int? limit,
|
||||
}) : limit = limit ?? pagination?.limit ?? 25,
|
||||
super(key: key);
|
||||
|
||||
/// A [ChannelListController] allows reloading and pagination.
|
||||
/// Use [ChannelListController.loadData] and
|
||||
@@ -124,7 +128,14 @@ class ChannelListCore extends StatefulWidget {
|
||||
/// limit: the number of channels to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams pagination;
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? pagination;
|
||||
|
||||
/// The amount of channels requested per API call.
|
||||
final int limit;
|
||||
|
||||
@override
|
||||
ChannelListCoreState createState() => ChannelListCoreState();
|
||||
@@ -162,7 +173,7 @@ class ChannelListCoreState extends State<ChannelListCore> {
|
||||
presence: widget.presence,
|
||||
memberLimit: widget.memberLimit,
|
||||
messageLimit: widget.messageLimit,
|
||||
paginationParams: widget.pagination,
|
||||
paginationParams: PaginationParams(limit: widget.limit),
|
||||
);
|
||||
|
||||
/// Fetches more channels with updated pagination and updates the widget
|
||||
@@ -174,7 +185,8 @@ class ChannelListCoreState extends State<ChannelListCore> {
|
||||
presence: widget.presence,
|
||||
memberLimit: widget.memberLimit,
|
||||
messageLimit: widget.messageLimit,
|
||||
paginationParams: widget.pagination.copyWith(
|
||||
paginationParams: PaginationParams(
|
||||
limit: widget.limit,
|
||||
offset: _channelsBloc.channels?.length ?? 0,
|
||||
),
|
||||
);
|
||||
@@ -221,7 +233,7 @@ class ChannelListCoreState extends State<ChannelListCore> {
|
||||
widget.presence != oldWidget.presence ||
|
||||
widget.messageLimit != oldWidget.messageLimit ||
|
||||
widget.memberLimit != oldWidget.memberLimit ||
|
||||
jsonEncode(widget.pagination) != jsonEncode(oldWidget.pagination)) {
|
||||
widget.limit != oldWidget.limit) {
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class MessageSearchListCore extends StatefulWidget {
|
||||
/// * [errorBuilder]
|
||||
/// * [loadingBuilder]
|
||||
/// * [childBuilder]
|
||||
const MessageSearchListCore({
|
||||
MessageSearchListCore({
|
||||
Key? key,
|
||||
required this.emptyBuilder,
|
||||
required this.errorBuilder,
|
||||
@@ -47,9 +47,14 @@ class MessageSearchListCore extends StatefulWidget {
|
||||
required this.filters,
|
||||
this.messageQuery,
|
||||
this.sortOptions,
|
||||
this.paginationParams = const PaginationParams(limit: 30),
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.paginationParams,
|
||||
this.messageFilters,
|
||||
this.messageSearchListController,
|
||||
int? limit,
|
||||
}) : assert(
|
||||
messageQuery != null || messageFilters != null,
|
||||
'Provide at least `query` or `messageFilters`',
|
||||
@@ -58,6 +63,13 @@ class MessageSearchListCore extends StatefulWidget {
|
||||
messageQuery == null || messageFilters == null,
|
||||
"Can't provide both `query` and `messageFilters` at the same time",
|
||||
),
|
||||
assert(
|
||||
paginationParams?.offset == null ||
|
||||
paginationParams?.offset == 0 ||
|
||||
sortOptions == null,
|
||||
'Cannot specify `offset` with `sortOptions` parameter',
|
||||
),
|
||||
limit = limit ?? paginationParams?.limit ?? 30,
|
||||
super(key: key);
|
||||
|
||||
/// A [MessageSearchListController] allows reloading and pagination.
|
||||
@@ -84,7 +96,14 @@ class MessageSearchListCore extends StatefulWidget {
|
||||
/// Pagination parameters
|
||||
/// limit: the number of messages to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
final PaginationParams paginationParams;
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? paginationParams;
|
||||
|
||||
/// The amount of messages requested per API call.
|
||||
final int limit;
|
||||
|
||||
/// The message query filters to use.
|
||||
/// You can query on any of the custom fields you've defined on the [Channel].
|
||||
@@ -157,19 +176,19 @@ class MessageSearchListCoreState extends State<MessageSearchListCore> {
|
||||
filter: widget.filters,
|
||||
sort: widget.sortOptions,
|
||||
query: widget.messageQuery,
|
||||
pagination: widget.paginationParams,
|
||||
messageFilter: widget.messageFilters,
|
||||
pagination: PaginationParams(limit: widget.limit),
|
||||
);
|
||||
|
||||
/// Fetches more messages with updated pagination and updates the widget
|
||||
Future<void> paginateData() {
|
||||
PaginationParams pagination;
|
||||
var pagination = PaginationParams(limit: widget.limit);
|
||||
if (widget.sortOptions != null) {
|
||||
pagination = widget.paginationParams.copyWith(
|
||||
pagination = pagination.copyWith(
|
||||
next: _messageSearchBloc?.nextId,
|
||||
);
|
||||
} else {
|
||||
pagination = widget.paginationParams.copyWith(
|
||||
pagination = pagination.copyWith(
|
||||
offset: _messageSearchBloc?.messageResponses?.length,
|
||||
);
|
||||
}
|
||||
@@ -190,8 +209,7 @@ class MessageSearchListCoreState extends State<MessageSearchListCore> {
|
||||
widget.messageQuery != oldWidget.messageQuery ||
|
||||
jsonEncode(widget.messageFilters) !=
|
||||
jsonEncode(oldWidget.messageFilters) ||
|
||||
jsonEncode(widget.paginationParams) !=
|
||||
jsonEncode(oldWidget.paginationParams)) {
|
||||
widget.limit != oldWidget.limit) {
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
/// [errorBuilder] must all be supplied and not null.
|
||||
class UserListCore extends StatefulWidget {
|
||||
/// Instantiate a new [UserListCore]
|
||||
const UserListCore({
|
||||
UserListCore({
|
||||
required this.errorBuilder,
|
||||
required this.emptyBuilder,
|
||||
required this.loadingBuilder,
|
||||
@@ -66,10 +66,16 @@ class UserListCore extends StatefulWidget {
|
||||
this.filter = const Filter.empty(),
|
||||
this.sort,
|
||||
this.presence,
|
||||
this.pagination = const PaginationParams(limit: 30),
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
this.pagination,
|
||||
this.groupAlphabetically = false,
|
||||
this.userListController,
|
||||
}) : super(key: key);
|
||||
int? limit,
|
||||
}) : limit = limit ?? pagination?.limit ?? 30,
|
||||
super(key: key);
|
||||
|
||||
/// A [UserListController] allows reloading and pagination.
|
||||
/// Use [UserListController.loadData] and [UserListController.paginateData]
|
||||
@@ -107,7 +113,14 @@ class UserListCore extends StatefulWidget {
|
||||
/// limit: the number of users to return (max is 30)
|
||||
/// offset: the offset (max is 1000)
|
||||
/// message_limit: how many messages should be included to each channel
|
||||
final PaginationParams pagination;
|
||||
@Deprecated(
|
||||
"'pagination' is deprecated and shouldn't be used. "
|
||||
"This property is no longer used, Please use 'limit' instead",
|
||||
)
|
||||
final PaginationParams? pagination;
|
||||
|
||||
/// The amount of users requested per API call.
|
||||
final int limit;
|
||||
|
||||
/// Set it to true to group users by their first character
|
||||
///
|
||||
@@ -194,7 +207,7 @@ class UserListCoreState extends State<UserListCore>
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
presence: widget.presence,
|
||||
pagination: widget.pagination,
|
||||
pagination: PaginationParams(limit: widget.limit),
|
||||
);
|
||||
|
||||
/// Fetches more users with updated pagination and updates the widget
|
||||
@@ -202,7 +215,8 @@ class UserListCoreState extends State<UserListCore>
|
||||
filter: widget.filter,
|
||||
sort: widget.sort,
|
||||
presence: widget.presence,
|
||||
pagination: widget.pagination.copyWith(
|
||||
pagination: PaginationParams(
|
||||
limit: widget.limit,
|
||||
offset: _usersBloc!.users?.length ?? 0,
|
||||
),
|
||||
);
|
||||
@@ -213,7 +227,7 @@ class UserListCoreState extends State<UserListCore>
|
||||
if (jsonEncode(widget.filter) != jsonEncode(oldWidget.filter) ||
|
||||
jsonEncode(widget.sort) != jsonEncode(oldWidget.sort) ||
|
||||
widget.presence != oldWidget.presence ||
|
||||
jsonEncode(widget.pagination) != jsonEncode(oldWidget.pagination)) {
|
||||
widget.limit != oldWidget.limit) {
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
||||
@@ -508,4 +508,17 @@ void main() {
|
||||
)).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('`widget.limit` should match `widget.pagination.limit`', () {
|
||||
const pagination = PaginationParams(limit: 30);
|
||||
final channelListCore = ChannelListCore(
|
||||
listBuilder: (_, __) => const Offstage(),
|
||||
loadingBuilder: (BuildContext context) => const Offstage(),
|
||||
emptyBuilder: (BuildContext context) => const Offstage(),
|
||||
errorBuilder: (BuildContext context, Object error) => const Offstage(),
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
expect(channelListCore.limit, pagination.limit);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -551,4 +551,19 @@ void main() {
|
||||
)).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('`widget.limit` should match `widget.pagination.limit`', () {
|
||||
const pagination = PaginationParams(limit: 30);
|
||||
final messageSearchListCore = MessageSearchListCore(
|
||||
childBuilder: (List<GetMessageResponse> messages) => const Offstage(),
|
||||
loadingBuilder: (BuildContext context) => const Offstage(),
|
||||
emptyBuilder: (BuildContext context) => const Offstage(),
|
||||
errorBuilder: (BuildContext context, Object? error) => const Offstage(),
|
||||
filters: testFilter,
|
||||
messageFilters: testMessageFilter,
|
||||
paginationParams: pagination,
|
||||
);
|
||||
|
||||
expect(messageSearchListCore.limit, pagination.limit);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -520,4 +520,17 @@ void main() {
|
||||
)).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
test('`widget.limit` should match `widget.pagination.limit`', () {
|
||||
const pagination = PaginationParams(limit: 30);
|
||||
final userListCore = UserListCore(
|
||||
listBuilder: (_, __) => const Offstage(),
|
||||
loadingBuilder: (BuildContext context) => const Offstage(),
|
||||
emptyBuilder: (BuildContext context) => const Offstage(),
|
||||
errorBuilder: (BuildContext context, Object error) => const Offstage(),
|
||||
pagination: pagination,
|
||||
);
|
||||
|
||||
expect(userListCore.limit, pagination.limit);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user