diff --git a/lib/providers/sn_attachment.dart b/lib/providers/sn_attachment.dart index f4181bb..162746f 100644 --- a/lib/providers/sn_attachment.dart +++ b/lib/providers/sn_attachment.dart @@ -21,7 +21,7 @@ class SnAttachmentProvider { void putCache(Iterable items, {bool noCheck = false}) { for (final item in items) { - if ((item.isAnalyzed && item.isUploaded) || noCheck) { + if (item.isAnalyzed || noCheck) { _cache[item.rid] = item; } } @@ -34,7 +34,7 @@ class SnAttachmentProvider { final resp = await _sn.client.get('/cgi/uc/attachments/$rid/meta'); final out = SnAttachment.fromJson(resp.data); - if (out.isAnalyzed && out.isUploaded) { + if (out.isAnalyzed) { _cache[rid] = out; } @@ -62,11 +62,12 @@ class SnAttachmentProvider { 'id': pendingFetch.join(','), }, ); - final out = resp.data['data'].map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e)).toList(); + final List out = + resp.data['data'].map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e)).cast().toList(); for (final item in out) { if (item == null) continue; - if (item.isAnalyzed && item.isUploaded) { + if (item.isAnalyzed) { _cache[item.rid] = item; } result[randomMapping[item.rid]!] = item; @@ -117,7 +118,7 @@ class SnAttachmentProvider { return SnAttachment.fromJson(resp.data); } - Future<(SnAttachment, int)> chunkedUploadInitialize( + Future<(SnAttachmentFragment, int)> chunkedUploadInitialize( int size, String filename, String pool, @@ -134,7 +135,7 @@ class SnAttachmentProvider { mimetypeOverride = mimetype; } - final resp = await _sn.client.post('/cgi/uc/attachments/multipart', data: { + final resp = await _sn.client.post('/cgi/uc/fragments', data: { 'alt': fileAlt, 'name': filename, 'pool': pool, @@ -143,17 +144,17 @@ class SnAttachmentProvider { if (mimetypeOverride != null) 'mimetype': mimetypeOverride, }); - return (SnAttachment.fromJson(resp.data['meta']), resp.data['chunk_size'] as int); + return (SnAttachmentFragment.fromJson(resp.data['meta']), resp.data['chunk_size'] as int); } - Future _chunkedUploadOnePart( + Future _chunkedUploadOnePart( Uint8List data, String rid, String cid, { Function(double progress)? onProgress, }) async { final resp = await _sn.client.post( - '/cgi/uc/attachments/multipart/$rid/$cid', + '/cgi/uc/fragments/$rid/$cid', data: data, options: Options(headers: {'Content-Type': 'application/octet-stream'}), onSendProgress: (count, total) { @@ -163,21 +164,27 @@ class SnAttachmentProvider { }, ); - return SnAttachment.fromJson(resp.data); + if (resp.data['attachment'] != null) { + return SnAttachment.fromJson(resp.data['attachment']); + } else { + return SnAttachmentFragment.fromJson(resp.data['fragment']); + } } Future chunkedUploadParts( XFile file, - SnAttachment place, + SnAttachmentFragment place, int chunkSize, { Function(double progress)? onProgress, }) async { - final Map chunks = place.fileChunks ?? {}; + final Map chunks = place.fileChunks; var currentTask = 0; final queue = Queue>(); final activeTasks = >[]; + late SnAttachment out; + for (final entry in chunks.entries) { queue.add(() async { final beginCursor = entry.value * chunkSize; @@ -187,7 +194,7 @@ class SnAttachmentProvider { ); final data = Uint8List.fromList(await file.openRead(beginCursor, endCursor).expand((chunk) => chunk).toList()); - place = await _chunkedUploadOnePart( + final result = await _chunkedUploadOnePart( data, place.rid, entry.key, @@ -197,6 +204,12 @@ class SnAttachmentProvider { onProgress?.call(overallProgress); currentTask++; + + if (result is SnAttachmentFragment) { + place = result; + } else { + out = result as SnAttachment; + } }()); } @@ -213,7 +226,7 @@ class SnAttachmentProvider { } } - return place; + return out; } Future updateOne( diff --git a/lib/types/attachment.dart b/lib/types/attachment.dart index ab02f9b..40b25fc 100644 --- a/lib/types/attachment.dart +++ b/lib/types/attachment.dart @@ -19,7 +19,7 @@ class SnAttachment with _$SnAttachment { required int id, required DateTime createdAt, required DateTime updatedAt, - required dynamic deletedAt, + required DateTime? deletedAt, required String rid, required String uuid, required int size, @@ -31,19 +31,20 @@ class SnAttachment with _$SnAttachment { required int refCount, @Default(0) int contentRating, @Default(0) int qualityRating, - required dynamic fileChunks, - required dynamic cleanedAt, + required DateTime? cleanedAt, required bool isAnalyzed, - required bool isUploaded, required bool isSelfRef, - required dynamic ref, - required dynamic refId, + required SnAttachment? ref, + required int? refId, required SnAttachmentPool? pool, required int poolId, required int accountId, + int? thumbnailId, + SnAttachment? thumbnail, + int? compressedId, + SnAttachment? compressed, @Default({}) Map usermeta, @Default({}) Map metadata, - String? thumbnail, }) = _SnAttachment; factory SnAttachment.fromJson(Map json) => _$SnAttachmentFromJson(json); @@ -61,6 +62,37 @@ class SnAttachment with _$SnAttachment { }; } +@freezed +class SnAttachmentFragment with _$SnAttachmentFragment { + const SnAttachmentFragment._(); + + const factory SnAttachmentFragment({ + required int id, + required DateTime createdAt, + required DateTime updatedAt, + required DateTime? deletedAt, + required String rid, + required String uuid, + required int size, + required String name, + required String alt, + required String mimetype, + required String hash, + String? fingerprint, + @Default({}) Map fileChunks, + @Default([]) List fileChunksMissing, + }) = _SnAttachmentFragment; + + factory SnAttachmentFragment.fromJson(Map json) => _$SnAttachmentFragmentFromJson(json); + + SnMediaType get mediaType => switch (mimetype.split('/').firstOrNull) { + 'image' => SnMediaType.image, + 'video' => SnMediaType.video, + 'audio' => SnMediaType.audio, + _ => SnMediaType.file, + }; +} + @freezed class SnAttachmentPool with _$SnAttachmentPool { const factory SnAttachmentPool({ diff --git a/lib/types/attachment.freezed.dart b/lib/types/attachment.freezed.dart index 82c7e12..dcb763f 100644 --- a/lib/types/attachment.freezed.dart +++ b/lib/types/attachment.freezed.dart @@ -23,7 +23,7 @@ mixin _$SnAttachment { int get id => throw _privateConstructorUsedError; DateTime get createdAt => throw _privateConstructorUsedError; DateTime get updatedAt => throw _privateConstructorUsedError; - dynamic get deletedAt => throw _privateConstructorUsedError; + DateTime? get deletedAt => throw _privateConstructorUsedError; String get rid => throw _privateConstructorUsedError; String get uuid => throw _privateConstructorUsedError; int get size => throw _privateConstructorUsedError; @@ -35,19 +35,20 @@ mixin _$SnAttachment { int get refCount => throw _privateConstructorUsedError; int get contentRating => throw _privateConstructorUsedError; int get qualityRating => throw _privateConstructorUsedError; - dynamic get fileChunks => throw _privateConstructorUsedError; - dynamic get cleanedAt => throw _privateConstructorUsedError; + DateTime? get cleanedAt => throw _privateConstructorUsedError; bool get isAnalyzed => throw _privateConstructorUsedError; - bool get isUploaded => throw _privateConstructorUsedError; bool get isSelfRef => throw _privateConstructorUsedError; - dynamic get ref => throw _privateConstructorUsedError; - dynamic get refId => throw _privateConstructorUsedError; + SnAttachment? get ref => throw _privateConstructorUsedError; + int? get refId => throw _privateConstructorUsedError; SnAttachmentPool? get pool => throw _privateConstructorUsedError; int get poolId => throw _privateConstructorUsedError; int get accountId => throw _privateConstructorUsedError; + int? get thumbnailId => throw _privateConstructorUsedError; + SnAttachment? get thumbnail => throw _privateConstructorUsedError; + int? get compressedId => throw _privateConstructorUsedError; + SnAttachment? get compressed => throw _privateConstructorUsedError; Map get usermeta => throw _privateConstructorUsedError; Map get metadata => throw _privateConstructorUsedError; - String? get thumbnail => throw _privateConstructorUsedError; /// Serializes this SnAttachment to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -69,7 +70,7 @@ abstract class $SnAttachmentCopyWith<$Res> { {int id, DateTime createdAt, DateTime updatedAt, - dynamic deletedAt, + DateTime? deletedAt, String rid, String uuid, int size, @@ -81,21 +82,25 @@ abstract class $SnAttachmentCopyWith<$Res> { int refCount, int contentRating, int qualityRating, - dynamic fileChunks, - dynamic cleanedAt, + DateTime? cleanedAt, bool isAnalyzed, - bool isUploaded, bool isSelfRef, - dynamic ref, - dynamic refId, + SnAttachment? ref, + int? refId, SnAttachmentPool? pool, int poolId, int accountId, + int? thumbnailId, + SnAttachment? thumbnail, + int? compressedId, + SnAttachment? compressed, Map usermeta, - Map metadata, - String? thumbnail}); + Map metadata}); + $SnAttachmentCopyWith<$Res>? get ref; $SnAttachmentPoolCopyWith<$Res>? get pool; + $SnAttachmentCopyWith<$Res>? get thumbnail; + $SnAttachmentCopyWith<$Res>? get compressed; } /// @nodoc @@ -128,19 +133,20 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> Object? refCount = null, Object? contentRating = null, Object? qualityRating = null, - Object? fileChunks = freezed, Object? cleanedAt = freezed, Object? isAnalyzed = null, - Object? isUploaded = null, Object? isSelfRef = null, Object? ref = freezed, Object? refId = freezed, Object? pool = freezed, Object? poolId = null, Object? accountId = null, + Object? thumbnailId = freezed, + Object? thumbnail = freezed, + Object? compressedId = freezed, + Object? compressed = freezed, Object? usermeta = null, Object? metadata = null, - Object? thumbnail = freezed, }) { return _then(_value.copyWith( id: null == id @@ -158,7 +164,7 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> deletedAt: freezed == deletedAt ? _value.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable - as dynamic, + as DateTime?, rid: null == rid ? _value.rid : rid // ignore: cast_nullable_to_non_nullable @@ -203,22 +209,14 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> ? _value.qualityRating : qualityRating // ignore: cast_nullable_to_non_nullable as int, - fileChunks: freezed == fileChunks - ? _value.fileChunks - : fileChunks // ignore: cast_nullable_to_non_nullable - as dynamic, cleanedAt: freezed == cleanedAt ? _value.cleanedAt : cleanedAt // ignore: cast_nullable_to_non_nullable - as dynamic, + as DateTime?, isAnalyzed: null == isAnalyzed ? _value.isAnalyzed : isAnalyzed // ignore: cast_nullable_to_non_nullable as bool, - isUploaded: null == isUploaded - ? _value.isUploaded - : isUploaded // ignore: cast_nullable_to_non_nullable - as bool, isSelfRef: null == isSelfRef ? _value.isSelfRef : isSelfRef // ignore: cast_nullable_to_non_nullable @@ -226,11 +224,11 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> ref: freezed == ref ? _value.ref : ref // ignore: cast_nullable_to_non_nullable - as dynamic, + as SnAttachment?, refId: freezed == refId ? _value.refId : refId // ignore: cast_nullable_to_non_nullable - as dynamic, + as int?, pool: freezed == pool ? _value.pool : pool // ignore: cast_nullable_to_non_nullable @@ -243,6 +241,22 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> ? _value.accountId : accountId // ignore: cast_nullable_to_non_nullable as int, + thumbnailId: freezed == thumbnailId + ? _value.thumbnailId + : thumbnailId // ignore: cast_nullable_to_non_nullable + as int?, + thumbnail: freezed == thumbnail + ? _value.thumbnail + : thumbnail // ignore: cast_nullable_to_non_nullable + as SnAttachment?, + compressedId: freezed == compressedId + ? _value.compressedId + : compressedId // ignore: cast_nullable_to_non_nullable + as int?, + compressed: freezed == compressed + ? _value.compressed + : compressed // ignore: cast_nullable_to_non_nullable + as SnAttachment?, usermeta: null == usermeta ? _value.usermeta : usermeta // ignore: cast_nullable_to_non_nullable @@ -251,13 +265,23 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> ? _value.metadata : metadata // ignore: cast_nullable_to_non_nullable as Map, - thumbnail: freezed == thumbnail - ? _value.thumbnail - : thumbnail // ignore: cast_nullable_to_non_nullable - as String?, ) as $Val); } + /// Create a copy of SnAttachment + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SnAttachmentCopyWith<$Res>? get ref { + if (_value.ref == null) { + return null; + } + + return $SnAttachmentCopyWith<$Res>(_value.ref!, (value) { + return _then(_value.copyWith(ref: value) as $Val); + }); + } + /// Create a copy of SnAttachment /// with the given fields replaced by the non-null parameter values. @override @@ -271,6 +295,34 @@ class _$SnAttachmentCopyWithImpl<$Res, $Val extends SnAttachment> return _then(_value.copyWith(pool: value) as $Val); }); } + + /// Create a copy of SnAttachment + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SnAttachmentCopyWith<$Res>? get thumbnail { + if (_value.thumbnail == null) { + return null; + } + + return $SnAttachmentCopyWith<$Res>(_value.thumbnail!, (value) { + return _then(_value.copyWith(thumbnail: value) as $Val); + }); + } + + /// Create a copy of SnAttachment + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $SnAttachmentCopyWith<$Res>? get compressed { + if (_value.compressed == null) { + return null; + } + + return $SnAttachmentCopyWith<$Res>(_value.compressed!, (value) { + return _then(_value.copyWith(compressed: value) as $Val); + }); + } } /// @nodoc @@ -285,7 +337,7 @@ abstract class _$$SnAttachmentImplCopyWith<$Res> {int id, DateTime createdAt, DateTime updatedAt, - dynamic deletedAt, + DateTime? deletedAt, String rid, String uuid, int size, @@ -297,22 +349,29 @@ abstract class _$$SnAttachmentImplCopyWith<$Res> int refCount, int contentRating, int qualityRating, - dynamic fileChunks, - dynamic cleanedAt, + DateTime? cleanedAt, bool isAnalyzed, - bool isUploaded, bool isSelfRef, - dynamic ref, - dynamic refId, + SnAttachment? ref, + int? refId, SnAttachmentPool? pool, int poolId, int accountId, + int? thumbnailId, + SnAttachment? thumbnail, + int? compressedId, + SnAttachment? compressed, Map usermeta, - Map metadata, - String? thumbnail}); + Map metadata}); + @override + $SnAttachmentCopyWith<$Res>? get ref; @override $SnAttachmentPoolCopyWith<$Res>? get pool; + @override + $SnAttachmentCopyWith<$Res>? get thumbnail; + @override + $SnAttachmentCopyWith<$Res>? get compressed; } /// @nodoc @@ -343,19 +402,20 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> Object? refCount = null, Object? contentRating = null, Object? qualityRating = null, - Object? fileChunks = freezed, Object? cleanedAt = freezed, Object? isAnalyzed = null, - Object? isUploaded = null, Object? isSelfRef = null, Object? ref = freezed, Object? refId = freezed, Object? pool = freezed, Object? poolId = null, Object? accountId = null, + Object? thumbnailId = freezed, + Object? thumbnail = freezed, + Object? compressedId = freezed, + Object? compressed = freezed, Object? usermeta = null, Object? metadata = null, - Object? thumbnail = freezed, }) { return _then(_$SnAttachmentImpl( id: null == id @@ -373,7 +433,7 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> deletedAt: freezed == deletedAt ? _value.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable - as dynamic, + as DateTime?, rid: null == rid ? _value.rid : rid // ignore: cast_nullable_to_non_nullable @@ -418,22 +478,14 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> ? _value.qualityRating : qualityRating // ignore: cast_nullable_to_non_nullable as int, - fileChunks: freezed == fileChunks - ? _value.fileChunks - : fileChunks // ignore: cast_nullable_to_non_nullable - as dynamic, cleanedAt: freezed == cleanedAt ? _value.cleanedAt : cleanedAt // ignore: cast_nullable_to_non_nullable - as dynamic, + as DateTime?, isAnalyzed: null == isAnalyzed ? _value.isAnalyzed : isAnalyzed // ignore: cast_nullable_to_non_nullable as bool, - isUploaded: null == isUploaded - ? _value.isUploaded - : isUploaded // ignore: cast_nullable_to_non_nullable - as bool, isSelfRef: null == isSelfRef ? _value.isSelfRef : isSelfRef // ignore: cast_nullable_to_non_nullable @@ -441,11 +493,11 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> ref: freezed == ref ? _value.ref : ref // ignore: cast_nullable_to_non_nullable - as dynamic, + as SnAttachment?, refId: freezed == refId ? _value.refId : refId // ignore: cast_nullable_to_non_nullable - as dynamic, + as int?, pool: freezed == pool ? _value.pool : pool // ignore: cast_nullable_to_non_nullable @@ -458,6 +510,22 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> ? _value.accountId : accountId // ignore: cast_nullable_to_non_nullable as int, + thumbnailId: freezed == thumbnailId + ? _value.thumbnailId + : thumbnailId // ignore: cast_nullable_to_non_nullable + as int?, + thumbnail: freezed == thumbnail + ? _value.thumbnail + : thumbnail // ignore: cast_nullable_to_non_nullable + as SnAttachment?, + compressedId: freezed == compressedId + ? _value.compressedId + : compressedId // ignore: cast_nullable_to_non_nullable + as int?, + compressed: freezed == compressed + ? _value.compressed + : compressed // ignore: cast_nullable_to_non_nullable + as SnAttachment?, usermeta: null == usermeta ? _value._usermeta : usermeta // ignore: cast_nullable_to_non_nullable @@ -466,10 +534,6 @@ class __$$SnAttachmentImplCopyWithImpl<$Res> ? _value._metadata : metadata // ignore: cast_nullable_to_non_nullable as Map, - thumbnail: freezed == thumbnail - ? _value.thumbnail - : thumbnail // ignore: cast_nullable_to_non_nullable - as String?, )); } } @@ -493,19 +557,20 @@ class _$SnAttachmentImpl extends _SnAttachment { required this.refCount, this.contentRating = 0, this.qualityRating = 0, - required this.fileChunks, required this.cleanedAt, required this.isAnalyzed, - required this.isUploaded, required this.isSelfRef, required this.ref, required this.refId, required this.pool, required this.poolId, required this.accountId, + this.thumbnailId, + this.thumbnail, + this.compressedId, + this.compressed, final Map usermeta = const {}, - final Map metadata = const {}, - this.thumbnail}) + final Map metadata = const {}}) : _usermeta = usermeta, _metadata = metadata, super._(); @@ -520,7 +585,7 @@ class _$SnAttachmentImpl extends _SnAttachment { @override final DateTime updatedAt; @override - final dynamic deletedAt; + final DateTime? deletedAt; @override final String rid; @override @@ -546,25 +611,29 @@ class _$SnAttachmentImpl extends _SnAttachment { @JsonKey() final int qualityRating; @override - final dynamic fileChunks; - @override - final dynamic cleanedAt; + final DateTime? cleanedAt; @override final bool isAnalyzed; @override - final bool isUploaded; - @override final bool isSelfRef; @override - final dynamic ref; + final SnAttachment? ref; @override - final dynamic refId; + final int? refId; @override final SnAttachmentPool? pool; @override final int poolId; @override final int accountId; + @override + final int? thumbnailId; + @override + final SnAttachment? thumbnail; + @override + final int? compressedId; + @override + final SnAttachment? compressed; final Map _usermeta; @override @JsonKey() @@ -583,12 +652,9 @@ class _$SnAttachmentImpl extends _SnAttachment { return EqualUnmodifiableMapView(_metadata); } - @override - final String? thumbnail; - @override String toString() { - return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, fileChunks: $fileChunks, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isUploaded: $isUploaded, isSelfRef: $isSelfRef, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, usermeta: $usermeta, metadata: $metadata, thumbnail: $thumbnail)'; + return 'SnAttachment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, destination: $destination, refCount: $refCount, contentRating: $contentRating, qualityRating: $qualityRating, cleanedAt: $cleanedAt, isAnalyzed: $isAnalyzed, isSelfRef: $isSelfRef, ref: $ref, refId: $refId, pool: $pool, poolId: $poolId, accountId: $accountId, thumbnailId: $thumbnailId, thumbnail: $thumbnail, compressedId: $compressedId, compressed: $compressed, usermeta: $usermeta, metadata: $metadata)'; } @override @@ -601,7 +667,8 @@ class _$SnAttachmentImpl extends _SnAttachment { other.createdAt == createdAt) && (identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt) && - const DeepCollectionEquality().equals(other.deletedAt, deletedAt) && + (identical(other.deletedAt, deletedAt) || + other.deletedAt == deletedAt) && (identical(other.rid, rid) || other.rid == rid) && (identical(other.uuid, uuid) || other.uuid == uuid) && (identical(other.size, size) || other.size == size) && @@ -618,25 +685,28 @@ class _$SnAttachmentImpl extends _SnAttachment { other.contentRating == contentRating) && (identical(other.qualityRating, qualityRating) || other.qualityRating == qualityRating) && - const DeepCollectionEquality() - .equals(other.fileChunks, fileChunks) && - const DeepCollectionEquality().equals(other.cleanedAt, cleanedAt) && + (identical(other.cleanedAt, cleanedAt) || + other.cleanedAt == cleanedAt) && (identical(other.isAnalyzed, isAnalyzed) || other.isAnalyzed == isAnalyzed) && - (identical(other.isUploaded, isUploaded) || - other.isUploaded == isUploaded) && (identical(other.isSelfRef, isSelfRef) || other.isSelfRef == isSelfRef) && - const DeepCollectionEquality().equals(other.ref, ref) && - const DeepCollectionEquality().equals(other.refId, refId) && + (identical(other.ref, ref) || other.ref == ref) && + (identical(other.refId, refId) || other.refId == refId) && (identical(other.pool, pool) || other.pool == pool) && (identical(other.poolId, poolId) || other.poolId == poolId) && (identical(other.accountId, accountId) || other.accountId == accountId) && - const DeepCollectionEquality().equals(other._usermeta, _usermeta) && - const DeepCollectionEquality().equals(other._metadata, _metadata) && + (identical(other.thumbnailId, thumbnailId) || + other.thumbnailId == thumbnailId) && (identical(other.thumbnail, thumbnail) || - other.thumbnail == thumbnail)); + other.thumbnail == thumbnail) && + (identical(other.compressedId, compressedId) || + other.compressedId == compressedId) && + (identical(other.compressed, compressed) || + other.compressed == compressed) && + const DeepCollectionEquality().equals(other._usermeta, _usermeta) && + const DeepCollectionEquality().equals(other._metadata, _metadata)); } @JsonKey(includeFromJson: false, includeToJson: false) @@ -646,7 +716,7 @@ class _$SnAttachmentImpl extends _SnAttachment { id, createdAt, updatedAt, - const DeepCollectionEquality().hash(deletedAt), + deletedAt, rid, uuid, size, @@ -658,19 +728,20 @@ class _$SnAttachmentImpl extends _SnAttachment { refCount, contentRating, qualityRating, - const DeepCollectionEquality().hash(fileChunks), - const DeepCollectionEquality().hash(cleanedAt), + cleanedAt, isAnalyzed, - isUploaded, isSelfRef, - const DeepCollectionEquality().hash(ref), - const DeepCollectionEquality().hash(refId), + ref, + refId, pool, poolId, accountId, + thumbnailId, + thumbnail, + compressedId, + compressed, const DeepCollectionEquality().hash(_usermeta), - const DeepCollectionEquality().hash(_metadata), - thumbnail + const DeepCollectionEquality().hash(_metadata) ]); /// Create a copy of SnAttachment @@ -694,7 +765,7 @@ abstract class _SnAttachment extends SnAttachment { {required final int id, required final DateTime createdAt, required final DateTime updatedAt, - required final dynamic deletedAt, + required final DateTime? deletedAt, required final String rid, required final String uuid, required final int size, @@ -706,19 +777,20 @@ abstract class _SnAttachment extends SnAttachment { required final int refCount, final int contentRating, final int qualityRating, - required final dynamic fileChunks, - required final dynamic cleanedAt, + required final DateTime? cleanedAt, required final bool isAnalyzed, - required final bool isUploaded, required final bool isSelfRef, - required final dynamic ref, - required final dynamic refId, + required final SnAttachment? ref, + required final int? refId, required final SnAttachmentPool? pool, required final int poolId, required final int accountId, + final int? thumbnailId, + final SnAttachment? thumbnail, + final int? compressedId, + final SnAttachment? compressed, final Map usermeta, - final Map metadata, - final String? thumbnail}) = _$SnAttachmentImpl; + final Map metadata}) = _$SnAttachmentImpl; const _SnAttachment._() : super._(); factory _SnAttachment.fromJson(Map json) = @@ -731,7 +803,7 @@ abstract class _SnAttachment extends SnAttachment { @override DateTime get updatedAt; @override - dynamic get deletedAt; + DateTime? get deletedAt; @override String get rid; @override @@ -755,19 +827,15 @@ abstract class _SnAttachment extends SnAttachment { @override int get qualityRating; @override - dynamic get fileChunks; - @override - dynamic get cleanedAt; + DateTime? get cleanedAt; @override bool get isAnalyzed; @override - bool get isUploaded; - @override bool get isSelfRef; @override - dynamic get ref; + SnAttachment? get ref; @override - dynamic get refId; + int? get refId; @override SnAttachmentPool? get pool; @override @@ -775,11 +843,17 @@ abstract class _SnAttachment extends SnAttachment { @override int get accountId; @override + int? get thumbnailId; + @override + SnAttachment? get thumbnail; + @override + int? get compressedId; + @override + SnAttachment? get compressed; + @override Map get usermeta; @override Map get metadata; - @override - String? get thumbnail; /// Create a copy of SnAttachment /// with the given fields replaced by the non-null parameter values. @@ -789,6 +863,462 @@ abstract class _SnAttachment extends SnAttachment { throw _privateConstructorUsedError; } +SnAttachmentFragment _$SnAttachmentFragmentFromJson(Map json) { + return _SnAttachmentFragment.fromJson(json); +} + +/// @nodoc +mixin _$SnAttachmentFragment { + int get id => throw _privateConstructorUsedError; + DateTime get createdAt => throw _privateConstructorUsedError; + DateTime get updatedAt => throw _privateConstructorUsedError; + DateTime? get deletedAt => throw _privateConstructorUsedError; + String get rid => throw _privateConstructorUsedError; + String get uuid => throw _privateConstructorUsedError; + int get size => throw _privateConstructorUsedError; + String get name => throw _privateConstructorUsedError; + String get alt => throw _privateConstructorUsedError; + String get mimetype => throw _privateConstructorUsedError; + String get hash => throw _privateConstructorUsedError; + String? get fingerprint => throw _privateConstructorUsedError; + Map get fileChunks => throw _privateConstructorUsedError; + List get fileChunksMissing => throw _privateConstructorUsedError; + + /// Serializes this SnAttachmentFragment to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of SnAttachmentFragment + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $SnAttachmentFragmentCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $SnAttachmentFragmentCopyWith<$Res> { + factory $SnAttachmentFragmentCopyWith(SnAttachmentFragment value, + $Res Function(SnAttachmentFragment) then) = + _$SnAttachmentFragmentCopyWithImpl<$Res, SnAttachmentFragment>; + @useResult + $Res call( + {int id, + DateTime createdAt, + DateTime updatedAt, + DateTime? deletedAt, + String rid, + String uuid, + int size, + String name, + String alt, + String mimetype, + String hash, + String? fingerprint, + Map fileChunks, + List fileChunksMissing}); +} + +/// @nodoc +class _$SnAttachmentFragmentCopyWithImpl<$Res, + $Val extends SnAttachmentFragment> + implements $SnAttachmentFragmentCopyWith<$Res> { + _$SnAttachmentFragmentCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of SnAttachmentFragment + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? createdAt = null, + Object? updatedAt = null, + Object? deletedAt = freezed, + Object? rid = null, + Object? uuid = null, + Object? size = null, + Object? name = null, + Object? alt = null, + Object? mimetype = null, + Object? hash = null, + Object? fingerprint = freezed, + Object? fileChunks = null, + Object? fileChunksMissing = null, + }) { + return _then(_value.copyWith( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + createdAt: null == createdAt + ? _value.createdAt + : createdAt // ignore: cast_nullable_to_non_nullable + as DateTime, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + deletedAt: freezed == deletedAt + ? _value.deletedAt + : deletedAt // ignore: cast_nullable_to_non_nullable + as DateTime?, + rid: null == rid + ? _value.rid + : rid // ignore: cast_nullable_to_non_nullable + as String, + uuid: null == uuid + ? _value.uuid + : uuid // ignore: cast_nullable_to_non_nullable + as String, + size: null == size + ? _value.size + : size // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + alt: null == alt + ? _value.alt + : alt // ignore: cast_nullable_to_non_nullable + as String, + mimetype: null == mimetype + ? _value.mimetype + : mimetype // ignore: cast_nullable_to_non_nullable + as String, + hash: null == hash + ? _value.hash + : hash // ignore: cast_nullable_to_non_nullable + as String, + fingerprint: freezed == fingerprint + ? _value.fingerprint + : fingerprint // ignore: cast_nullable_to_non_nullable + as String?, + fileChunks: null == fileChunks + ? _value.fileChunks + : fileChunks // ignore: cast_nullable_to_non_nullable + as Map, + fileChunksMissing: null == fileChunksMissing + ? _value.fileChunksMissing + : fileChunksMissing // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$SnAttachmentFragmentImplCopyWith<$Res> + implements $SnAttachmentFragmentCopyWith<$Res> { + factory _$$SnAttachmentFragmentImplCopyWith(_$SnAttachmentFragmentImpl value, + $Res Function(_$SnAttachmentFragmentImpl) then) = + __$$SnAttachmentFragmentImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {int id, + DateTime createdAt, + DateTime updatedAt, + DateTime? deletedAt, + String rid, + String uuid, + int size, + String name, + String alt, + String mimetype, + String hash, + String? fingerprint, + Map fileChunks, + List fileChunksMissing}); +} + +/// @nodoc +class __$$SnAttachmentFragmentImplCopyWithImpl<$Res> + extends _$SnAttachmentFragmentCopyWithImpl<$Res, _$SnAttachmentFragmentImpl> + implements _$$SnAttachmentFragmentImplCopyWith<$Res> { + __$$SnAttachmentFragmentImplCopyWithImpl(_$SnAttachmentFragmentImpl _value, + $Res Function(_$SnAttachmentFragmentImpl) _then) + : super(_value, _then); + + /// Create a copy of SnAttachmentFragment + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? id = null, + Object? createdAt = null, + Object? updatedAt = null, + Object? deletedAt = freezed, + Object? rid = null, + Object? uuid = null, + Object? size = null, + Object? name = null, + Object? alt = null, + Object? mimetype = null, + Object? hash = null, + Object? fingerprint = freezed, + Object? fileChunks = null, + Object? fileChunksMissing = null, + }) { + return _then(_$SnAttachmentFragmentImpl( + id: null == id + ? _value.id + : id // ignore: cast_nullable_to_non_nullable + as int, + createdAt: null == createdAt + ? _value.createdAt + : createdAt // ignore: cast_nullable_to_non_nullable + as DateTime, + updatedAt: null == updatedAt + ? _value.updatedAt + : updatedAt // ignore: cast_nullable_to_non_nullable + as DateTime, + deletedAt: freezed == deletedAt + ? _value.deletedAt + : deletedAt // ignore: cast_nullable_to_non_nullable + as DateTime?, + rid: null == rid + ? _value.rid + : rid // ignore: cast_nullable_to_non_nullable + as String, + uuid: null == uuid + ? _value.uuid + : uuid // ignore: cast_nullable_to_non_nullable + as String, + size: null == size + ? _value.size + : size // ignore: cast_nullable_to_non_nullable + as int, + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + alt: null == alt + ? _value.alt + : alt // ignore: cast_nullable_to_non_nullable + as String, + mimetype: null == mimetype + ? _value.mimetype + : mimetype // ignore: cast_nullable_to_non_nullable + as String, + hash: null == hash + ? _value.hash + : hash // ignore: cast_nullable_to_non_nullable + as String, + fingerprint: freezed == fingerprint + ? _value.fingerprint + : fingerprint // ignore: cast_nullable_to_non_nullable + as String?, + fileChunks: null == fileChunks + ? _value._fileChunks + : fileChunks // ignore: cast_nullable_to_non_nullable + as Map, + fileChunksMissing: null == fileChunksMissing + ? _value._fileChunksMissing + : fileChunksMissing // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$SnAttachmentFragmentImpl extends _SnAttachmentFragment { + const _$SnAttachmentFragmentImpl( + {required this.id, + required this.createdAt, + required this.updatedAt, + required this.deletedAt, + required this.rid, + required this.uuid, + required this.size, + required this.name, + required this.alt, + required this.mimetype, + required this.hash, + this.fingerprint, + final Map fileChunks = const {}, + final List fileChunksMissing = const []}) + : _fileChunks = fileChunks, + _fileChunksMissing = fileChunksMissing, + super._(); + + factory _$SnAttachmentFragmentImpl.fromJson(Map json) => + _$$SnAttachmentFragmentImplFromJson(json); + + @override + final int id; + @override + final DateTime createdAt; + @override + final DateTime updatedAt; + @override + final DateTime? deletedAt; + @override + final String rid; + @override + final String uuid; + @override + final int size; + @override + final String name; + @override + final String alt; + @override + final String mimetype; + @override + final String hash; + @override + final String? fingerprint; + final Map _fileChunks; + @override + @JsonKey() + Map get fileChunks { + if (_fileChunks is EqualUnmodifiableMapView) return _fileChunks; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(_fileChunks); + } + + final List _fileChunksMissing; + @override + @JsonKey() + List get fileChunksMissing { + if (_fileChunksMissing is EqualUnmodifiableListView) + return _fileChunksMissing; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_fileChunksMissing); + } + + @override + String toString() { + return 'SnAttachmentFragment(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, rid: $rid, uuid: $uuid, size: $size, name: $name, alt: $alt, mimetype: $mimetype, hash: $hash, fingerprint: $fingerprint, fileChunks: $fileChunks, fileChunksMissing: $fileChunksMissing)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$SnAttachmentFragmentImpl && + (identical(other.id, id) || other.id == id) && + (identical(other.createdAt, createdAt) || + other.createdAt == createdAt) && + (identical(other.updatedAt, updatedAt) || + other.updatedAt == updatedAt) && + (identical(other.deletedAt, deletedAt) || + other.deletedAt == deletedAt) && + (identical(other.rid, rid) || other.rid == rid) && + (identical(other.uuid, uuid) || other.uuid == uuid) && + (identical(other.size, size) || other.size == size) && + (identical(other.name, name) || other.name == name) && + (identical(other.alt, alt) || other.alt == alt) && + (identical(other.mimetype, mimetype) || + other.mimetype == mimetype) && + (identical(other.hash, hash) || other.hash == hash) && + (identical(other.fingerprint, fingerprint) || + other.fingerprint == fingerprint) && + const DeepCollectionEquality() + .equals(other._fileChunks, _fileChunks) && + const DeepCollectionEquality() + .equals(other._fileChunksMissing, _fileChunksMissing)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, + id, + createdAt, + updatedAt, + deletedAt, + rid, + uuid, + size, + name, + alt, + mimetype, + hash, + fingerprint, + const DeepCollectionEquality().hash(_fileChunks), + const DeepCollectionEquality().hash(_fileChunksMissing)); + + /// Create a copy of SnAttachmentFragment + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$SnAttachmentFragmentImplCopyWith<_$SnAttachmentFragmentImpl> + get copyWith => + __$$SnAttachmentFragmentImplCopyWithImpl<_$SnAttachmentFragmentImpl>( + this, _$identity); + + @override + Map toJson() { + return _$$SnAttachmentFragmentImplToJson( + this, + ); + } +} + +abstract class _SnAttachmentFragment extends SnAttachmentFragment { + const factory _SnAttachmentFragment( + {required final int id, + required final DateTime createdAt, + required final DateTime updatedAt, + required final DateTime? deletedAt, + required final String rid, + required final String uuid, + required final int size, + required final String name, + required final String alt, + required final String mimetype, + required final String hash, + final String? fingerprint, + final Map fileChunks, + final List fileChunksMissing}) = _$SnAttachmentFragmentImpl; + const _SnAttachmentFragment._() : super._(); + + factory _SnAttachmentFragment.fromJson(Map json) = + _$SnAttachmentFragmentImpl.fromJson; + + @override + int get id; + @override + DateTime get createdAt; + @override + DateTime get updatedAt; + @override + DateTime? get deletedAt; + @override + String get rid; + @override + String get uuid; + @override + int get size; + @override + String get name; + @override + String get alt; + @override + String get mimetype; + @override + String get hash; + @override + String? get fingerprint; + @override + Map get fileChunks; + @override + List get fileChunksMissing; + + /// Create a copy of SnAttachmentFragment + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$SnAttachmentFragmentImplCopyWith<_$SnAttachmentFragmentImpl> + get copyWith => throw _privateConstructorUsedError; +} + SnAttachmentPool _$SnAttachmentPoolFromJson(Map json) { return _SnAttachmentPool.fromJson(json); } diff --git a/lib/types/attachment.g.dart b/lib/types/attachment.g.dart index ec0282c..634dea8 100644 --- a/lib/types/attachment.g.dart +++ b/lib/types/attachment.g.dart @@ -11,7 +11,9 @@ _$SnAttachmentImpl _$$SnAttachmentImplFromJson(Map json) => id: (json['id'] as num).toInt(), createdAt: DateTime.parse(json['created_at'] as String), updatedAt: DateTime.parse(json['updated_at'] as String), - deletedAt: json['deleted_at'], + deletedAt: json['deleted_at'] == null + ? null + : DateTime.parse(json['deleted_at'] as String), rid: json['rid'] as String, uuid: json['uuid'] as String, size: (json['size'] as num).toInt(), @@ -23,21 +25,30 @@ _$SnAttachmentImpl _$$SnAttachmentImplFromJson(Map json) => refCount: (json['ref_count'] as num).toInt(), contentRating: (json['content_rating'] as num?)?.toInt() ?? 0, qualityRating: (json['quality_rating'] as num?)?.toInt() ?? 0, - fileChunks: json['file_chunks'], - cleanedAt: json['cleaned_at'], + cleanedAt: json['cleaned_at'] == null + ? null + : DateTime.parse(json['cleaned_at'] as String), isAnalyzed: json['is_analyzed'] as bool, - isUploaded: json['is_uploaded'] as bool, isSelfRef: json['is_self_ref'] as bool, - ref: json['ref'], - refId: json['ref_id'], + ref: json['ref'] == null + ? null + : SnAttachment.fromJson(json['ref'] as Map), + refId: (json['ref_id'] as num?)?.toInt(), pool: json['pool'] == null ? null : SnAttachmentPool.fromJson(json['pool'] as Map), poolId: (json['pool_id'] as num).toInt(), accountId: (json['account_id'] as num).toInt(), + thumbnailId: (json['thumbnail_id'] as num?)?.toInt(), + thumbnail: json['thumbnail'] == null + ? null + : SnAttachment.fromJson(json['thumbnail'] as Map), + compressedId: (json['compressed_id'] as num?)?.toInt(), + compressed: json['compressed'] == null + ? null + : SnAttachment.fromJson(json['compressed'] as Map), usermeta: json['usermeta'] as Map? ?? const {}, metadata: json['metadata'] as Map? ?? const {}, - thumbnail: json['thumbnail'] as String?, ); Map _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) => @@ -45,7 +56,7 @@ Map _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) => 'id': instance.id, 'created_at': instance.createdAt.toIso8601String(), 'updated_at': instance.updatedAt.toIso8601String(), - 'deleted_at': instance.deletedAt, + 'deleted_at': instance.deletedAt?.toIso8601String(), 'rid': instance.rid, 'uuid': instance.uuid, 'size': instance.size, @@ -57,19 +68,66 @@ Map _$$SnAttachmentImplToJson(_$SnAttachmentImpl instance) => 'ref_count': instance.refCount, 'content_rating': instance.contentRating, 'quality_rating': instance.qualityRating, - 'file_chunks': instance.fileChunks, - 'cleaned_at': instance.cleanedAt, + 'cleaned_at': instance.cleanedAt?.toIso8601String(), 'is_analyzed': instance.isAnalyzed, - 'is_uploaded': instance.isUploaded, 'is_self_ref': instance.isSelfRef, - 'ref': instance.ref, + 'ref': instance.ref?.toJson(), 'ref_id': instance.refId, 'pool': instance.pool?.toJson(), 'pool_id': instance.poolId, 'account_id': instance.accountId, + 'thumbnail_id': instance.thumbnailId, + 'thumbnail': instance.thumbnail?.toJson(), + 'compressed_id': instance.compressedId, + 'compressed': instance.compressed?.toJson(), 'usermeta': instance.usermeta, 'metadata': instance.metadata, - 'thumbnail': instance.thumbnail, + }; + +_$SnAttachmentFragmentImpl _$$SnAttachmentFragmentImplFromJson( + Map json) => + _$SnAttachmentFragmentImpl( + id: (json['id'] as num).toInt(), + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + deletedAt: json['deleted_at'] == null + ? null + : DateTime.parse(json['deleted_at'] as String), + rid: json['rid'] as String, + uuid: json['uuid'] as String, + size: (json['size'] as num).toInt(), + name: json['name'] as String, + alt: json['alt'] as String, + mimetype: json['mimetype'] as String, + hash: json['hash'] as String, + fingerprint: json['fingerprint'] as String?, + fileChunks: (json['file_chunks'] as Map?)?.map( + (k, e) => MapEntry(k, (e as num).toInt()), + ) ?? + const {}, + fileChunksMissing: (json['file_chunks_missing'] as List?) + ?.map((e) => e as String) + .toList() ?? + const [], + ); + +Map _$$SnAttachmentFragmentImplToJson( + _$SnAttachmentFragmentImpl instance) => + { + 'id': instance.id, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt?.toIso8601String(), + 'rid': instance.rid, + 'uuid': instance.uuid, + 'size': instance.size, + 'name': instance.name, + 'alt': instance.alt, + 'mimetype': instance.mimetype, + 'hash': instance.hash, + 'fingerprint': instance.fingerprint, + 'file_chunks': instance.fileChunks, + 'file_chunks_missing': instance.fileChunksMissing, }; _$SnAttachmentPoolImpl _$$SnAttachmentPoolImplFromJson( diff --git a/lib/widgets/attachment/attachment_item.dart b/lib/widgets/attachment/attachment_item.dart index 9f387ff..9ab9d98 100644 --- a/lib/widgets/attachment/attachment_item.dart +++ b/lib/widgets/attachment/attachment_item.dart @@ -215,9 +215,9 @@ class _AttachmentItemContentVideoState extends State<_AttachmentItemContentVideo behavior: HitTestBehavior.opaque, child: Stack( children: [ - if (widget.data.thumbnail?.isNotEmpty ?? false) + if (widget.data.thumbnail != null) AutoResizeUniversalImage( - sn.getAttachmentUrl(widget.data.thumbnail!), + sn.getAttachmentUrl(widget.data.thumbnail!.rid), fit: BoxFit.cover, ) else diff --git a/lib/widgets/post/post_media_pending_list.dart b/lib/widgets/post/post_media_pending_list.dart index 10f7d0e..8dd6d21 100644 --- a/lib/widgets/post/post_media_pending_list.dart +++ b/lib/widgets/post/post_media_pending_list.dart @@ -315,7 +315,7 @@ class _PostMediaPendingItem extends StatelessWidget { fit: StackFit.expand, children: [ if (media.attachment?.thumbnail != null) - AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment!.thumbnail!)), + AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment!.thumbnail!.rid)), const Icon(Symbols.videocam, color: Colors.white, shadows: [ Shadow( offset: Offset(1, 1), @@ -332,7 +332,7 @@ class _PostMediaPendingItem extends StatelessWidget { fit: StackFit.expand, children: [ if (media.attachment?.thumbnail != null) - AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment!.thumbnail!)), + AutoResizeUniversalImage(sn.getAttachmentUrl(media.attachment!.thumbnail!.rid)), const Icon(Symbols.audio_file, color: Colors.white, shadows: [ Shadow( offset: Offset(1, 1),