refactor!: initial attachments refactor.

Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
Sahil Kumar
2023-07-28 21:07:02 +05:30
committed by xsahil03x
parent eb6f0852e8
commit f246de55a1
61 changed files with 3628 additions and 1712 deletions
@@ -10,13 +10,24 @@ import 'package:uuid/uuid.dart';
part 'attachment.g.dart';
mixin AttachmentType {
/// Backend specified types.
static const image = 'image';
static const file = 'file';
static const giphy = 'giphy';
static const video = 'video';
/// Application custom types.
static const urlPreview = 'url_preview';
}
/// The class that contains the information about an attachment
@JsonSerializable(includeIfNull: false)
class Attachment extends Equatable {
/// Constructor used for json serialization
Attachment({
String? id,
this.type,
String? type,
this.titleLink,
String? title,
this.thumbUrl,
@@ -33,14 +44,16 @@ class Attachment extends Equatable {
this.authorLink,
this.authorIcon,
this.assetUrl,
List<Action>? actions,
this.actions = const [],
this.originalWidth,
this.originalHeight,
Map<String, Object?> extraData = const {},
this.file,
UploadState? uploadState,
}) : id = id ?? const Uuid().v4(),
_type = type,
title = title ?? file?.name,
localUri = file?.path != null ? Uri.parse(file!.path!) : null,
actions = actions ?? [],
// For backwards compatibility,
// set 'file_size', 'mime_type' in [extraData].
extraData = {
@@ -84,7 +97,15 @@ class Attachment extends Equatable {
///The attachment type based on the URL resource. This can be: audio,
///image or video
final String? type;
String? get type {
if (_type == AttachmentType.image && titleLink != null) {
return AttachmentType.urlPreview;
}
return _type;
}
final String? _type;
///The link to which the attachment message points to.
final String? titleLink;
@@ -126,6 +147,12 @@ class Attachment extends Equatable {
/// Actions from a command
final List<Action>? actions;
/// The original width of the attached image.
final int? originalWidth;
/// The original height of the attached image.
final int? originalHeight;
final Uri? localUri;
/// The file present inside this attachment.
@@ -175,6 +202,8 @@ class Attachment extends Equatable {
'author_icon',
'asset_url',
'actions',
'original_width',
'original_height',
];
/// Known db specific top level fields.
@@ -214,6 +243,8 @@ class Attachment extends Equatable {
String? authorIcon,
String? assetUrl,
List<Action>? actions,
int? originalWidth,
int? originalHeight,
AttachmentFile? file,
UploadState? uploadState,
Map<String, Object?>? extraData,
@@ -238,6 +269,8 @@ class Attachment extends Equatable {
authorIcon: authorIcon ?? this.authorIcon,
assetUrl: assetUrl ?? this.assetUrl,
actions: actions ?? this.actions,
originalWidth: originalWidth ?? this.originalWidth,
originalHeight: originalHeight ?? this.originalHeight,
file: file ?? this.file,
uploadState: uploadState ?? this.uploadState,
extraData: extraData ?? this.extraData,
@@ -264,6 +297,8 @@ class Attachment extends Equatable {
authorIcon: other.authorIcon,
assetUrl: other.assetUrl,
actions: other.actions,
originalWidth: other.originalWidth,
originalHeight: other.originalHeight,
file: other.file,
uploadState: other.uploadState,
extraData: other.extraData,
@@ -291,6 +326,8 @@ class Attachment extends Equatable {
authorIcon,
assetUrl,
actions,
originalWidth,
originalHeight,
file,
uploadState,
extraData,
@@ -28,6 +28,8 @@ Attachment _$AttachmentFromJson(Map<String, dynamic> json) => Attachment(
actions: (json['actions'] as List<dynamic>?)
?.map((e) => Action.fromJson(e as Map<String, dynamic>))
.toList(),
originalWidth: json['original_width'] as int?,
originalHeight: json['original_height'] as int?,
extraData: json['extra_data'] as Map<String, dynamic>? ?? const {},
file: json['file'] == null
? null
@@ -64,6 +66,8 @@ Map<String, dynamic> _$AttachmentToJson(Attachment instance) {
writeNotNull('author_icon', instance.authorIcon);
writeNotNull('asset_url', instance.assetUrl);
writeNotNull('actions', instance.actions?.map((e) => e.toJson()).toList());
writeNotNull('original_width', instance.originalWidth);
writeNotNull('original_height', instance.originalHeight);
writeNotNull('file', instance.file?.toJson());
val['upload_state'] = instance.uploadState.toJson();
val['extra_data'] = instance.extraData;
@@ -0,0 +1,69 @@
import 'package:stream_chat/src/core/models/attachment.dart';
/// {@template giphy_info_type}
/// The different types of quality for a Giphy attachment.
/// {@endtemplate}
enum GiphyInfoType {
/// Original quality giphy, the largest size to load.
original('original'),
/// Lower quality with a fixed height, adjusts width according to the
/// Giphy aspect ratio. Lower size than [original].
fixedHeight('fixed_height'),
/// Still image of the [fixedHeight] giphy.
fixedHeightStill('fixed_height_still'),
/// Lower quality with a fixed height with width adjusted according to the
/// aspect ratio and played at a lower frame rate. Significantly lower size,
/// but visually less appealing.
fixedHeightDownsampled('fixed_height_downsampled');
/// {@macro giphy_info_type}
const GiphyInfoType(this.value);
/// The value of the [GiphyInfoType].
final String value;
}
/// {@template giphy_info}
/// A class that contains extra information about a Giphy attachment.
/// {@endtemplate}
class GiphyInfo {
/// {@macro giphy_info}
const GiphyInfo({
required this.url,
required this.width,
required this.height,
});
/// The url for the Giphy image.
final String url;
/// The width of the Giphy image.
final double width;
/// The height of the Giphy image.
final double height;
@override
String toString() => 'GiphyInfo{url: $url, width: $width, height: $height}';
}
/// GiphyInfo extension on [Attachment] class.
extension GiphyInfoX on Attachment {
/// Returns the [GiphyInfo] for the given [type].
GiphyInfo? giphyInfo(GiphyInfoType type) {
final giphy = extraData['giphy'] as Map<String, Object?>?;
if (giphy == null) return null;
final info = giphy[type.value] as Map<String, Object?>?;
if (info == null) return null;
return GiphyInfo(
url: info['url']! as String,
width: double.parse(info['width']! as String),
height: double.parse(info['height']! as String),
);
}
}
@@ -215,6 +215,9 @@ class Message extends Equatable {
/// Message custom extraData.
final Map<String, Object?> extraData;
/// True if the message is a error.
bool get isError => type == 'error';
/// True if the message is a system info.
bool get isSystem => type == 'system';
@@ -28,6 +28,7 @@ export 'src/core/http/interceptor/logging_interceptor.dart';
export 'src/core/models/action.dart';
export 'src/core/models/attachment.dart';
export 'src/core/models/attachment_file.dart';
export 'src/core/models/attachment_giphy_info.dart';
export 'src/core/models/channel_config.dart';
export 'src/core/models/channel_model.dart';
export 'src/core/models/channel_mute.dart';
@@ -805,7 +805,7 @@ void main() {
emits(ConnectionStatus.disconnected),
);
await client.disconnectUser();
await client.disconnectUser(flushChatPersistence: true);
expect(client.state.currentUser, isNull);
expect(client.wsConnectionStatus, ConnectionStatus.disconnected);