claude refactorings, flutter best practices, platform dependent changes, general cleanup
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../apiResponse.dart';
|
||||
import '../talkApi.dart';
|
||||
import '../../../api_params.dart';
|
||||
import '../../../api_response.dart';
|
||||
import '../talk_api.dart';
|
||||
|
||||
/// Small POST/DELETE-only Talk endpoints that have no response payload.
|
||||
/// Each class extends [TalkApi] with `assemble` returning `null`. They share
|
||||
|
||||
+7
-4
@@ -3,9 +3,9 @@ import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'getChatParams.dart';
|
||||
import 'getChatResponse.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'get_chat_params.dart';
|
||||
import 'get_chat_response.dart';
|
||||
|
||||
class GetChat extends TalkApi<GetChatResponse> {
|
||||
String chatToken;
|
||||
@@ -14,7 +14,10 @@ class GetChat extends TalkApi<GetChatResponse> {
|
||||
GetChat(this.chatToken, this.params) : super('v1/chat/$chatToken', null, getParameters: params.toJson());
|
||||
|
||||
@override
|
||||
assemble(String raw) => GetChatResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
GetChatResponse assemble(String raw) {
|
||||
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||
return GetChatResponse.fromJson(decoded['ocs'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response> request(Uri uri, Object? body, Map<String, String>? headers) => http.get(uri, headers: headers);
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import '../../../requestCache.dart';
|
||||
import 'getChat.dart';
|
||||
import 'getChatParams.dart';
|
||||
import 'getChatResponse.dart';
|
||||
import '../../../request_cache.dart';
|
||||
import 'get_chat.dart';
|
||||
import 'get_chat_params.dart';
|
||||
import 'get_chat_response.dart';
|
||||
|
||||
class GetChatCache extends SimpleCache<GetChatResponse> {
|
||||
GetChatCache({
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'getChatParams.g.dart';
|
||||
part 'get_chat_params.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true, includeIfNull: false)
|
||||
class GetChatParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getChatParams.dart';
|
||||
part of 'get_chat_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+7
-7
@@ -1,10 +1,10 @@
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiResponse.dart';
|
||||
import '../room/getRoomResponse.dart';
|
||||
import '../../../api_response.dart';
|
||||
import '../room/get_room_response.dart';
|
||||
|
||||
part 'getChatResponse.g.dart';
|
||||
part 'get_chat_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetChatResponse extends ApiResponse {
|
||||
@@ -87,10 +87,10 @@ class GetChatResponseObject {
|
||||
}
|
||||
|
||||
Map<String, RichObjectString>? _fromJson(dynamic json) {
|
||||
if(json is Map<String, dynamic>) {
|
||||
var data = <String, RichObjectString>{};
|
||||
for (var element in json.keys) {
|
||||
data.putIfAbsent(element, () => RichObjectString.fromJson(json[element]));
|
||||
if (json is Map<String, dynamic>) {
|
||||
final data = <String, RichObjectString>{};
|
||||
for (final element in json.keys) {
|
||||
data.putIfAbsent(element, () => RichObjectString.fromJson(json[element] as Map<String, dynamic>));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getChatResponse.dart';
|
||||
part of 'get_chat_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
|
||||
import 'getChatResponse.dart';
|
||||
import 'get_chat_response.dart';
|
||||
|
||||
class RichObjectStringProcessor {
|
||||
static String parseToString(String message, Map<String, RichObjectString>? data) {
|
||||
+3
-3
@@ -2,15 +2,15 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'createRoomParams.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'create_room_params.dart';
|
||||
class CreateRoom extends TalkApi {
|
||||
CreateRoomParams params;
|
||||
|
||||
CreateRoom(this.params) : super('v4/room', params);
|
||||
|
||||
@override
|
||||
assemble(String raw) => null;
|
||||
Null assemble(String raw) => null;
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, Object? body, Map<String, String>? headers) {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'createRoomParams.g.dart';
|
||||
part 'create_room_params.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class CreateRoomParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'createRoomParams.dart';
|
||||
part of 'create_room_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../talkApi.dart';
|
||||
import 'deleteReactMessageParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'delete_react_message_params.dart';
|
||||
|
||||
class DeleteReactMessage extends TalkApi {
|
||||
String chatToken;
|
||||
@@ -11,7 +11,7 @@ class DeleteReactMessage extends TalkApi {
|
||||
DeleteReactMessage({required this.chatToken, required this.messageId, required DeleteReactMessageParams params}) : super('v1/reaction/$chatToken/$messageId', params);
|
||||
|
||||
@override
|
||||
assemble(String raw) => null;
|
||||
Null assemble(String raw) => null;
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'deleteReactMessageParams.g.dart';
|
||||
part 'delete_react_message_params.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class DeleteReactMessageParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'deleteReactMessageParams.dart';
|
||||
part of 'delete_react_message_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+6
-3
@@ -2,15 +2,18 @@ import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'getParticipantsResponse.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'get_participants_response.dart';
|
||||
|
||||
class GetParticipants extends TalkApi<GetParticipantsResponse> {
|
||||
String token;
|
||||
GetParticipants(this.token) : super('v4/room/$token/participants', null);
|
||||
|
||||
@override
|
||||
GetParticipantsResponse assemble(String raw) => GetParticipantsResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
GetParticipantsResponse assemble(String raw) {
|
||||
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||
return GetParticipantsResponse.fromJson(decoded['ocs'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<http.Response> request(Uri uri, Object? body, Map<String, String>? headers) => http.get(uri, headers: headers);
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import '../../../requestCache.dart';
|
||||
import 'getParticipants.dart';
|
||||
import 'getParticipantsResponse.dart';
|
||||
import '../../../request_cache.dart';
|
||||
import 'get_participants.dart';
|
||||
import 'get_participants_response.dart';
|
||||
|
||||
class GetParticipantsCache extends SimpleCache<GetParticipantsResponse> {
|
||||
GetParticipantsCache({
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiResponse.dart';
|
||||
import '../../../api_response.dart';
|
||||
|
||||
part 'getParticipantsResponse.g.dart';
|
||||
part 'get_participants_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetParticipantsResponse extends ApiResponse {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getParticipantsResponse.dart';
|
||||
part of 'get_participants_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+6
-3
@@ -2,8 +2,8 @@ import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'getPollStateResponse.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'get_poll_state_response.dart';
|
||||
|
||||
class GetPollState extends TalkApi<GetPollStateResponse> {
|
||||
String token;
|
||||
@@ -11,7 +11,10 @@ class GetPollState extends TalkApi<GetPollStateResponse> {
|
||||
GetPollState({required this.token, required this.pollId}) : super('v1/poll/$token/$pollId', null);
|
||||
|
||||
@override
|
||||
GetPollStateResponse assemble(String raw) => GetPollStateResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
GetPollStateResponse assemble(String raw) {
|
||||
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||
return GetPollStateResponse.fromJson(decoded['ocs'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<http.Response> request(Uri uri, Object? body, Map<String, String>? headers) => http.get(uri, headers: headers);
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiResponse.dart';
|
||||
import '../../../api_response.dart';
|
||||
|
||||
part 'getPollStateResponse.g.dart';
|
||||
part 'get_poll_state_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetPollStateResponse extends ApiResponse {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getPollStateResponse.dart';
|
||||
part of 'get_poll_state_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+7
-4
@@ -3,9 +3,9 @@ import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../talkApi.dart';
|
||||
import 'getReactionsResponse.dart';
|
||||
import '../../../api_params.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'get_reactions_response.dart';
|
||||
|
||||
class GetReactions extends TalkApi<GetReactionsResponse> {
|
||||
String chatToken;
|
||||
@@ -13,7 +13,10 @@ class GetReactions extends TalkApi<GetReactionsResponse> {
|
||||
GetReactions({required this.chatToken, required this.messageId}) : super('v1/reaction/$chatToken/$messageId', null);
|
||||
|
||||
@override
|
||||
assemble(String raw) => GetReactionsResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
GetReactionsResponse assemble(String raw) {
|
||||
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||
return GetReactionsResponse.fromJson(decoded['ocs'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) => http.get(uri, headers: headers);
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiResponse.dart';
|
||||
import '../../../api_response.dart';
|
||||
|
||||
part 'getReactionsResponse.g.dart';
|
||||
part 'get_reactions_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetReactionsResponse extends ApiResponse {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getReactionsResponse.dart';
|
||||
part of 'get_reactions_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../talkApi.dart';
|
||||
import 'reactMessageParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'react_message_params.dart';
|
||||
|
||||
class ReactMessage extends TalkApi {
|
||||
String chatToken;
|
||||
@@ -11,7 +11,7 @@ class ReactMessage extends TalkApi {
|
||||
ReactMessage({required this.chatToken, required this.messageId, required ReactMessageParams params}) : super('v1/reaction/$chatToken/$messageId', params);
|
||||
|
||||
@override
|
||||
assemble(String raw) => null;
|
||||
Null assemble(String raw) => null;
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'reactMessageParams.g.dart';
|
||||
part 'react_message_params.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class ReactMessageParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'reactMessageParams.dart';
|
||||
part of 'react_message_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+7
-4
@@ -2,9 +2,9 @@ import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'getRoomParams.dart';
|
||||
import 'getRoomResponse.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'get_room_params.dart';
|
||||
import 'get_room_response.dart';
|
||||
|
||||
|
||||
class GetRoom extends TalkApi<GetRoomResponse> {
|
||||
@@ -14,7 +14,10 @@ class GetRoom extends TalkApi<GetRoomResponse> {
|
||||
|
||||
|
||||
@override
|
||||
GetRoomResponse assemble(String raw) => GetRoomResponse.fromJson(jsonDecode(raw)['ocs']);
|
||||
GetRoomResponse assemble(String raw) {
|
||||
final decoded = jsonDecode(raw) as Map<String, dynamic>;
|
||||
return GetRoomResponse.fromJson(decoded['ocs'] as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<http.Response> request(Uri uri, Object? body, Map<String, String>? headers) => http.get(uri, headers: headers);
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import '../../../requestCache.dart';
|
||||
import 'getRoom.dart';
|
||||
import 'getRoomParams.dart';
|
||||
import 'getRoomResponse.dart';
|
||||
import '../../../request_cache.dart';
|
||||
import 'get_room.dart';
|
||||
import 'get_room_params.dart';
|
||||
import 'get_room_response.dart';
|
||||
|
||||
class GetRoomCache extends SimpleCache<GetRoomResponse> {
|
||||
GetRoomCache({super.onUpdate, super.onError, super.renew})
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'getRoomParams.g.dart';
|
||||
part 'get_room_params.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getRoomParams.dart';
|
||||
part of 'get_room_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiResponse.dart';
|
||||
import '../chat/getChatResponse.dart';
|
||||
import '../../../api_response.dart';
|
||||
import '../chat/get_chat_response.dart';
|
||||
|
||||
part 'getRoomResponse.g.dart';
|
||||
part 'get_room_response.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class GetRoomResponse extends ApiResponse {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'getRoomResponse.dart';
|
||||
part of 'get_room_response.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../talkApi.dart';
|
||||
import 'sendMessageParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'send_message_params.dart';
|
||||
|
||||
class SendMessage extends TalkApi {
|
||||
String chatToken;
|
||||
SendMessage(this.chatToken, SendMessageParams params) : super('v1/chat/$chatToken', params);
|
||||
|
||||
@override
|
||||
assemble(String raw) => null;
|
||||
Null assemble(String raw) => null;
|
||||
|
||||
@override
|
||||
Future<Response>? request(Uri uri, ApiParams? body, Map<String, String>? headers) {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'sendMessageParams.g.dart';
|
||||
part 'send_message_params.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true, includeIfNull: false)
|
||||
class SendMessageParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'sendMessageParams.dart';
|
||||
part of 'send_message_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/http.dart';
|
||||
|
||||
import '../talkApi.dart';
|
||||
import 'setReadMarkerParams.dart';
|
||||
import '../talk_api.dart';
|
||||
import 'set_read_marker_params.dart';
|
||||
|
||||
class SetReadMarker extends TalkApi {
|
||||
String chatToken;
|
||||
@@ -15,7 +15,7 @@ class SetReadMarker extends TalkApi {
|
||||
}
|
||||
|
||||
@override
|
||||
assemble(String raw) => null;
|
||||
Null assemble(String raw) => null;
|
||||
|
||||
@override
|
||||
Future<Response> request(Uri uri, Object? body, Map<String, String>? headers) {
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../../apiParams.dart';
|
||||
import '../../../api_params.dart';
|
||||
|
||||
part 'setReadMarkerParams.g.dart';
|
||||
part 'set_read_marker_params.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class SetReadMarkerParams extends ApiParams {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'setReadMarkerParams.dart';
|
||||
part of 'set_read_marker_params.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
@@ -4,9 +4,9 @@ import 'dart:io';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../apiParams.dart';
|
||||
import '../../apiRequest.dart';
|
||||
import '../../apiResponse.dart';
|
||||
import '../../api_params.dart';
|
||||
import '../../api_request.dart';
|
||||
import '../../api_response.dart';
|
||||
import '../../errors/auth_exception.dart';
|
||||
import '../../errors/network_exception.dart';
|
||||
import '../../errors/not_found_exception.dart';
|
||||
Reference in New Issue
Block a user