Merge pull request #770 from GetStream/feat/hard-delete
feat(llc): added hard delete
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Extra properties added to `PaginationParams` to aid in fetching messages.
|
- Extra properties added to `PaginationParams` to aid in fetching messages.
|
||||||
|
- Added hard delete functionality.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -648,7 +648,7 @@ class Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes the [message] from the channel.
|
/// Deletes the [message] from the channel.
|
||||||
Future<EmptyResponse> deleteMessage(Message message) async {
|
Future<EmptyResponse> deleteMessage(Message message, {bool? hard}) async {
|
||||||
// Directly deleting the local messages which are not yet sent to server
|
// Directly deleting the local messages which are not yet sent to server
|
||||||
if (message.status == MessageSendingStatus.sending ||
|
if (message.status == MessageSendingStatus.sending ||
|
||||||
message.status == MessageSendingStatus.failed) {
|
message.status == MessageSendingStatus.failed) {
|
||||||
@@ -675,7 +675,7 @@ class Channel {
|
|||||||
|
|
||||||
state?.addMessage(message);
|
state?.addMessage(message);
|
||||||
|
|
||||||
final response = await _client.deleteMessage(message.id);
|
final response = await _client.deleteMessage(message.id, hard: hard);
|
||||||
|
|
||||||
state?.addMessage(message.copyWith(status: MessageSendingStatus.sent));
|
state?.addMessage(message.copyWith(status: MessageSendingStatus.sent));
|
||||||
|
|
||||||
@@ -1663,7 +1663,11 @@ class ChannelClientState {
|
|||||||
void _listenMessageDeleted() {
|
void _listenMessageDeleted() {
|
||||||
_subscriptions.add(_channel.on(EventType.messageDeleted).listen((event) {
|
_subscriptions.add(_channel.on(EventType.messageDeleted).listen((event) {
|
||||||
final message = event.message!;
|
final message = event.message!;
|
||||||
addMessage(message);
|
if (event.hardDelete == true) {
|
||||||
|
removeMessage(message, hardDelete: true);
|
||||||
|
} else {
|
||||||
|
addMessage(message);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1718,7 +1722,7 @@ class ChannelClientState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a [message] from this [channelState].
|
/// Remove a [message] from this [channelState].
|
||||||
void removeMessage(Message message) {
|
void removeMessage(Message message, {bool hardDelete = false}) {
|
||||||
final parentId = message.parentId;
|
final parentId = message.parentId;
|
||||||
// i.e. it's a thread message
|
// i.e. it's a thread message
|
||||||
// 1. Remove the thread message
|
// 1. Remove the thread message
|
||||||
@@ -1740,7 +1744,10 @@ class ChannelClientState {
|
|||||||
} else {
|
} else {
|
||||||
// Remove regular message
|
// Remove regular message
|
||||||
final allMessages = [...messages];
|
final allMessages = [...messages];
|
||||||
if (allMessages.remove(message)) {
|
if (hardDelete) {
|
||||||
|
allMessages.removeWhere((e) => e.id == message.id);
|
||||||
|
_channelState = _channelState.copyWith(messages: allMessages);
|
||||||
|
} else if (allMessages.remove(message)) {
|
||||||
_channelState = _channelState.copyWith(messages: allMessages);
|
_channelState = _channelState.copyWith(messages: allMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1213,8 +1213,14 @@ class StreamChatClient {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Deletes the given message
|
/// Deletes the given message
|
||||||
Future<EmptyResponse> deleteMessage(String messageId) =>
|
Future<EmptyResponse> deleteMessage(String messageId, {bool? hard}) async {
|
||||||
_chatApi.message.deleteMessage(messageId);
|
final response =
|
||||||
|
await _chatApi.message.deleteMessage(messageId, hard: hard);
|
||||||
|
if (hard == true) {
|
||||||
|
await _chatPersistenceClient?.deleteMessageById(messageId);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a message by [messageId]
|
/// Get a message by [messageId]
|
||||||
Future<GetMessageResponse> getMessage(String messageId) =>
|
Future<GetMessageResponse> getMessage(String messageId) =>
|
||||||
|
|||||||
@@ -80,10 +80,16 @@ class MessageApi {
|
|||||||
|
|
||||||
/// Deletes the given [messageId]
|
/// Deletes the given [messageId]
|
||||||
Future<EmptyResponse> deleteMessage(
|
Future<EmptyResponse> deleteMessage(
|
||||||
String messageId,
|
String messageId, {
|
||||||
) async {
|
bool? hard,
|
||||||
|
}) async {
|
||||||
final response = await _client.delete(
|
final response = await _client.delete(
|
||||||
'/messages/$messageId',
|
'/messages/$messageId',
|
||||||
|
queryParameters: hard != null
|
||||||
|
? {
|
||||||
|
'hard': hard,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
return EmptyResponse.fromJson(response.data);
|
return EmptyResponse.fromJson(response.data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class Event {
|
|||||||
this.channelId,
|
this.channelId,
|
||||||
this.channelType,
|
this.channelType,
|
||||||
this.parentId,
|
this.parentId,
|
||||||
|
this.hardDelete,
|
||||||
this.extraData = const {},
|
this.extraData = const {},
|
||||||
this.isLocal = true,
|
this.isLocal = true,
|
||||||
}) : createdAt = createdAt?.toUtc() ?? DateTime.now().toUtc();
|
}) : createdAt = createdAt?.toUtc() ?? DateTime.now().toUtc();
|
||||||
@@ -91,6 +92,10 @@ class Event {
|
|||||||
@JsonKey(defaultValue: false)
|
@JsonKey(defaultValue: false)
|
||||||
final bool isLocal;
|
final bool isLocal;
|
||||||
|
|
||||||
|
/// This is true if the message has been hard deleted
|
||||||
|
@JsonKey(includeIfNull: false)
|
||||||
|
final bool? hardDelete;
|
||||||
|
|
||||||
/// Map of custom channel extraData
|
/// Map of custom channel extraData
|
||||||
final Map<String, Object?> extraData;
|
final Map<String, Object?> extraData;
|
||||||
|
|
||||||
@@ -113,6 +118,7 @@ class Event {
|
|||||||
'channel_id',
|
'channel_id',
|
||||||
'channel_type',
|
'channel_type',
|
||||||
'parent_id',
|
'parent_id',
|
||||||
|
'hard_delete',
|
||||||
'is_local',
|
'is_local',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -139,6 +145,7 @@ class Event {
|
|||||||
int? unreadChannels,
|
int? unreadChannels,
|
||||||
bool? online,
|
bool? online,
|
||||||
String? parentId,
|
String? parentId,
|
||||||
|
bool? hardDelete,
|
||||||
Map<String, Object?>? extraData,
|
Map<String, Object?>? extraData,
|
||||||
}) =>
|
}) =>
|
||||||
Event(
|
Event(
|
||||||
@@ -158,6 +165,7 @@ class Event {
|
|||||||
channelId: channelId ?? this.channelId,
|
channelId: channelId ?? this.channelId,
|
||||||
channelType: channelType ?? this.channelType,
|
channelType: channelType ?? this.channelType,
|
||||||
parentId: parentId ?? this.parentId,
|
parentId: parentId ?? this.parentId,
|
||||||
|
hardDelete: hardDelete ?? this.hardDelete,
|
||||||
extraData: extraData ?? this.extraData,
|
extraData: extraData ?? this.extraData,
|
||||||
isLocal: isLocal,
|
isLocal: isLocal,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -37,30 +37,42 @@ Event _$EventFromJson(Map<String, dynamic> json) => Event(
|
|||||||
channelId: json['channel_id'] as String?,
|
channelId: json['channel_id'] as String?,
|
||||||
channelType: json['channel_type'] as String?,
|
channelType: json['channel_type'] as String?,
|
||||||
parentId: json['parent_id'] as String?,
|
parentId: json['parent_id'] as String?,
|
||||||
|
hardDelete: json['hard_delete'] as bool?,
|
||||||
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
|
||||||
isLocal: json['is_local'] as bool? ?? false,
|
isLocal: json['is_local'] as bool? ?? false,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$EventToJson(Event instance) => <String, dynamic>{
|
Map<String, dynamic> _$EventToJson(Event instance) {
|
||||||
'type': instance.type,
|
final val = <String, dynamic>{
|
||||||
'cid': instance.cid,
|
'type': instance.type,
|
||||||
'channel_id': instance.channelId,
|
'cid': instance.cid,
|
||||||
'channel_type': instance.channelType,
|
'channel_id': instance.channelId,
|
||||||
'connection_id': instance.connectionId,
|
'channel_type': instance.channelType,
|
||||||
'created_at': instance.createdAt.toIso8601String(),
|
'connection_id': instance.connectionId,
|
||||||
'me': instance.me?.toJson(),
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
'user': instance.user?.toJson(),
|
'me': instance.me?.toJson(),
|
||||||
'message': instance.message?.toJson(),
|
'user': instance.user?.toJson(),
|
||||||
'channel': instance.channel?.toJson(),
|
'message': instance.message?.toJson(),
|
||||||
'member': instance.member?.toJson(),
|
'channel': instance.channel?.toJson(),
|
||||||
'reaction': instance.reaction?.toJson(),
|
'member': instance.member?.toJson(),
|
||||||
'total_unread_count': instance.totalUnreadCount,
|
'reaction': instance.reaction?.toJson(),
|
||||||
'unread_channels': instance.unreadChannels,
|
'total_unread_count': instance.totalUnreadCount,
|
||||||
'online': instance.online,
|
'unread_channels': instance.unreadChannels,
|
||||||
'parent_id': instance.parentId,
|
'online': instance.online,
|
||||||
'is_local': instance.isLocal,
|
'parent_id': instance.parentId,
|
||||||
'extra_data': instance.extraData,
|
'is_local': instance.isLocal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void writeNotNull(String key, dynamic value) {
|
||||||
|
if (value != null) {
|
||||||
|
val[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeNotNull('hard_delete', instance.hardDelete);
|
||||||
|
val['extra_data'] = instance.extraData;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
EventChannel _$EventChannelFromJson(Map<String, dynamic> json) => EventChannel(
|
EventChannel _$EventChannelFromJson(Map<String, dynamic> json) => EventChannel(
|
||||||
members: (json['members'] as List<dynamic>?)
|
members: (json['members'] as List<dynamic>?)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ part 'read.g.dart';
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class Read extends Equatable {
|
class Read extends Equatable {
|
||||||
/// Constructor used for json serialization
|
/// Constructor used for json serialization
|
||||||
Read({
|
const Read({
|
||||||
required this.lastRead,
|
required this.lastRead,
|
||||||
required this.user,
|
required this.user,
|
||||||
this.unreadMessages = 0,
|
this.unreadMessages = 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user