From adb231278c46d96103f27036806c52671ddfb70f Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 1 Jan 2026 01:47:09 +0800 Subject: [PATCH] :sparkles: Able to render fediverse posts --- assets/i18n/en-US.json | 4 +- lib/models/activitypub.dart | 13 + lib/models/activitypub.freezed.dart | 290 +++++++++++++++++++++ lib/models/activitypub.g.dart | 20 ++ lib/models/post.dart | 9 +- lib/models/post.freezed.dart | 114 +++++--- lib/models/post.g.dart | 20 +- lib/pods/timeline.dart | 1 + lib/screens/posts/post_detail.dart | 74 +++--- lib/widgets/activitypub/actor_profile.dart | 58 +++++ lib/widgets/post/compose_info_banner.dart | 66 ++++- lib/widgets/post/post_award_sheet.dart | 72 ++++- lib/widgets/post/post_item.dart | 2 +- lib/widgets/post/post_item_screenshot.dart | 4 +- lib/widgets/post/post_shared.dart | 203 ++++++++++++--- 15 files changed, 814 insertions(+), 136 deletions(-) create mode 100644 lib/widgets/activitypub/actor_profile.dart diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index af4b6ea3..df5ee6bb 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -1559,5 +1559,7 @@ "unfollowedUser": "Unfollowed @{}", "followingEmpty": "You're not following anyone yet", "followersEmpty": "No followers yet", - "followingEmptyHint": "Start by searching for users or explore other instances" + "followingEmptyHint": "Start by searching for users or explore other instances", + "fediversePost": "Fediverse Post", + "fediversePostDescribe": "Post from the Fediverse Network" } \ No newline at end of file diff --git a/lib/models/activitypub.dart b/lib/models/activitypub.dart index 718235f0..6bb8ce0f 100644 --- a/lib/models/activitypub.dart +++ b/lib/models/activitypub.dart @@ -93,3 +93,16 @@ sealed class SnActivityPubFollowResponse with _$SnActivityPubFollowResponse { factory SnActivityPubFollowResponse.fromJson(Map json) => _$SnActivityPubFollowResponseFromJson(json); } + +@freezed +sealed class SnActorStatusResponse with _$SnActorStatusResponse { + const factory SnActorStatusResponse({ + required bool enabled, + @Default(0) int followerCount, + SnActivityPubActor? actor, + String? actorUri, + }) = _SnActorStatusResponse; + + factory SnActorStatusResponse.fromJson(Map json) => + _$SnActorStatusResponseFromJson(json); +} diff --git a/lib/models/activitypub.freezed.dart b/lib/models/activitypub.freezed.dart index 15bc4854..b70b6609 100644 --- a/lib/models/activitypub.freezed.dart +++ b/lib/models/activitypub.freezed.dart @@ -1242,4 +1242,294 @@ as String, } + +/// @nodoc +mixin _$SnActorStatusResponse { + + bool get enabled; int get followerCount; SnActivityPubActor? get actor; String? get actorUri; +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnActorStatusResponseCopyWith get copyWith => _$SnActorStatusResponseCopyWithImpl(this as SnActorStatusResponse, _$identity); + + /// Serializes this SnActorStatusResponse to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnActorStatusResponse&&(identical(other.enabled, enabled) || other.enabled == enabled)&&(identical(other.followerCount, followerCount) || other.followerCount == followerCount)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.actorUri, actorUri) || other.actorUri == actorUri)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,enabled,followerCount,actor,actorUri); + +@override +String toString() { + return 'SnActorStatusResponse(enabled: $enabled, followerCount: $followerCount, actor: $actor, actorUri: $actorUri)'; +} + + +} + +/// @nodoc +abstract mixin class $SnActorStatusResponseCopyWith<$Res> { + factory $SnActorStatusResponseCopyWith(SnActorStatusResponse value, $Res Function(SnActorStatusResponse) _then) = _$SnActorStatusResponseCopyWithImpl; +@useResult +$Res call({ + bool enabled, int followerCount, SnActivityPubActor? actor, String? actorUri +}); + + +$SnActivityPubActorCopyWith<$Res>? get actor; + +} +/// @nodoc +class _$SnActorStatusResponseCopyWithImpl<$Res> + implements $SnActorStatusResponseCopyWith<$Res> { + _$SnActorStatusResponseCopyWithImpl(this._self, this._then); + + final SnActorStatusResponse _self; + final $Res Function(SnActorStatusResponse) _then; + +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? enabled = null,Object? followerCount = null,Object? actor = freezed,Object? actorUri = freezed,}) { + return _then(_self.copyWith( +enabled: null == enabled ? _self.enabled : enabled // ignore: cast_nullable_to_non_nullable +as bool,followerCount: null == followerCount ? _self.followerCount : followerCount // ignore: cast_nullable_to_non_nullable +as int,actor: freezed == actor ? _self.actor : actor // ignore: cast_nullable_to_non_nullable +as SnActivityPubActor?,actorUri: freezed == actorUri ? _self.actorUri : actorUri // ignore: cast_nullable_to_non_nullable +as String?, + )); +} +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnActivityPubActorCopyWith<$Res>? get actor { + if (_self.actor == null) { + return null; + } + + return $SnActivityPubActorCopyWith<$Res>(_self.actor!, (value) { + return _then(_self.copyWith(actor: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [SnActorStatusResponse]. +extension SnActorStatusResponsePatterns on SnActorStatusResponse { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _SnActorStatusResponse value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _SnActorStatusResponse() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _SnActorStatusResponse value) $default,){ +final _that = this; +switch (_that) { +case _SnActorStatusResponse(): +return $default(_that);} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _SnActorStatusResponse value)? $default,){ +final _that = this; +switch (_that) { +case _SnActorStatusResponse() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( bool enabled, int followerCount, SnActivityPubActor? actor, String? actorUri)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _SnActorStatusResponse() when $default != null: +return $default(_that.enabled,_that.followerCount,_that.actor,_that.actorUri);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( bool enabled, int followerCount, SnActivityPubActor? actor, String? actorUri) $default,) {final _that = this; +switch (_that) { +case _SnActorStatusResponse(): +return $default(_that.enabled,_that.followerCount,_that.actor,_that.actorUri);} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool enabled, int followerCount, SnActivityPubActor? actor, String? actorUri)? $default,) {final _that = this; +switch (_that) { +case _SnActorStatusResponse() when $default != null: +return $default(_that.enabled,_that.followerCount,_that.actor,_that.actorUri);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _SnActorStatusResponse implements SnActorStatusResponse { + const _SnActorStatusResponse({required this.enabled, this.followerCount = 0, this.actor, this.actorUri}); + factory _SnActorStatusResponse.fromJson(Map json) => _$SnActorStatusResponseFromJson(json); + +@override final bool enabled; +@override@JsonKey() final int followerCount; +@override final SnActivityPubActor? actor; +@override final String? actorUri; + +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnActorStatusResponseCopyWith<_SnActorStatusResponse> get copyWith => __$SnActorStatusResponseCopyWithImpl<_SnActorStatusResponse>(this, _$identity); + +@override +Map toJson() { + return _$SnActorStatusResponseToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnActorStatusResponse&&(identical(other.enabled, enabled) || other.enabled == enabled)&&(identical(other.followerCount, followerCount) || other.followerCount == followerCount)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.actorUri, actorUri) || other.actorUri == actorUri)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,enabled,followerCount,actor,actorUri); + +@override +String toString() { + return 'SnActorStatusResponse(enabled: $enabled, followerCount: $followerCount, actor: $actor, actorUri: $actorUri)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnActorStatusResponseCopyWith<$Res> implements $SnActorStatusResponseCopyWith<$Res> { + factory _$SnActorStatusResponseCopyWith(_SnActorStatusResponse value, $Res Function(_SnActorStatusResponse) _then) = __$SnActorStatusResponseCopyWithImpl; +@override @useResult +$Res call({ + bool enabled, int followerCount, SnActivityPubActor? actor, String? actorUri +}); + + +@override $SnActivityPubActorCopyWith<$Res>? get actor; + +} +/// @nodoc +class __$SnActorStatusResponseCopyWithImpl<$Res> + implements _$SnActorStatusResponseCopyWith<$Res> { + __$SnActorStatusResponseCopyWithImpl(this._self, this._then); + + final _SnActorStatusResponse _self; + final $Res Function(_SnActorStatusResponse) _then; + +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? enabled = null,Object? followerCount = null,Object? actor = freezed,Object? actorUri = freezed,}) { + return _then(_SnActorStatusResponse( +enabled: null == enabled ? _self.enabled : enabled // ignore: cast_nullable_to_non_nullable +as bool,followerCount: null == followerCount ? _self.followerCount : followerCount // ignore: cast_nullable_to_non_nullable +as int,actor: freezed == actor ? _self.actor : actor // ignore: cast_nullable_to_non_nullable +as SnActivityPubActor?,actorUri: freezed == actorUri ? _self.actorUri : actorUri // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +/// Create a copy of SnActorStatusResponse +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnActivityPubActorCopyWith<$Res>? get actor { + if (_self.actor == null) { + return null; + } + + return $SnActivityPubActorCopyWith<$Res>(_self.actor!, (value) { + return _then(_self.copyWith(actor: value)); + }); +} +} + // dart format on diff --git a/lib/models/activitypub.g.dart b/lib/models/activitypub.g.dart index 212c7412..0598fef1 100644 --- a/lib/models/activitypub.g.dart +++ b/lib/models/activitypub.g.dart @@ -164,3 +164,23 @@ Map _$SnActivityPubFollowResponseToJson( 'success': instance.success, 'message': instance.message, }; + +_SnActorStatusResponse _$SnActorStatusResponseFromJson( + Map json, +) => _SnActorStatusResponse( + enabled: json['enabled'] as bool, + followerCount: (json['follower_count'] as num?)?.toInt() ?? 0, + actor: json['actor'] == null + ? null + : SnActivityPubActor.fromJson(json['actor'] as Map), + actorUri: json['actor_uri'] as String?, +); + +Map _$SnActorStatusResponseToJson( + _SnActorStatusResponse instance, +) => { + 'enabled': instance.enabled, + 'follower_count': instance.followerCount, + 'actor': instance.actor?.toJson(), + 'actor_uri': instance.actorUri, +}; diff --git a/lib/models/post.dart b/lib/models/post.dart index db5166d0..9da4d9a4 100644 --- a/lib/models/post.dart +++ b/lib/models/post.dart @@ -1,5 +1,6 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:island/models/account.dart'; +import 'package:island/models/activitypub.dart'; import 'package:island/models/file.dart'; import 'package:island/models/post_category.dart'; import 'package:island/models/post_tag.dart'; @@ -39,8 +40,14 @@ sealed class SnPost with _$SnPost { SnPost? forwardedPost, String? realmId, SnRealm? realm, + String? publisherId, + SnPublisher? publisher, + String? actorid, + SnActivityPubActor? actor, + String? fediverseUri, + int? fediverseType, + @Default(0) int contentType, @Default([]) List attachments, - required SnPublisher publisher, @Default({}) Map reactionsCount, @Default({}) Map reactionsMade, @Default([]) List reactions, diff --git a/lib/models/post.freezed.dart b/lib/models/post.freezed.dart index ba4e3d41..b9593283 100644 --- a/lib/models/post.freezed.dart +++ b/lib/models/post.freezed.dart @@ -15,7 +15,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$SnPost { - String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; List get attachments; SnPublisher get publisher; Map get reactionsCount; Map get reactionsMade; List get reactions; List get tags; List get categories; List get collections; List get featuredRecords; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get repliedGone; bool get forwardedGone; bool get isTruncated; + String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime? get publishedAt; int get visibility; String? get content; String? get slug; int get type; Map? get meta; SnPostEmbedView? get embedView; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; int get awardedScore; int? get pinMode; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; String? get realmId; SnRealm? get realm; String? get publisherId; SnPublisher? get publisher; String? get actorid; SnActivityPubActor? get actor; String? get fediverseUri; int? get fediverseType; int get contentType; List get attachments; Map get reactionsCount; Map get reactionsMade; List get reactions; List get tags; List get categories; List get collections; List get featuredRecords; DateTime? get createdAt; DateTime? get updatedAt; DateTime? get deletedAt; bool get repliedGone; bool get forwardedGone; bool get isTruncated; /// Create a copy of SnPost /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -28,16 +28,16 @@ $SnPostCopyWith get copyWith => _$SnPostCopyWithImpl(this as SnP @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&const DeepCollectionEquality().equals(other.featuredRecords, featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.repliedGone, repliedGone) || other.repliedGone == repliedGone)&&(identical(other.forwardedGone, forwardedGone) || other.forwardedGone == forwardedGone)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.actorid, actorid) || other.actorid == actorid)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.fediverseUri, fediverseUri) || other.fediverseUri == fediverseUri)&&(identical(other.fediverseType, fediverseType) || other.fediverseType == fediverseType)&&(identical(other.contentType, contentType) || other.contentType == contentType)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactionsMade, reactionsMade)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&const DeepCollectionEquality().equals(other.featuredRecords, featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.repliedGone, repliedGone) || other.repliedGone == repliedGone)&&(identical(other.forwardedGone, forwardedGone) || other.forwardedGone == forwardedGone)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),const DeepCollectionEquality().hash(featuredRecords),createdAt,updatedAt,deletedAt,repliedGone,forwardedGone,isTruncated]); +int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,publisherId,publisher,actorid,actor,fediverseUri,fediverseType,contentType,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactionsMade),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),const DeepCollectionEquality().hash(featuredRecords),createdAt,updatedAt,deletedAt,repliedGone,forwardedGone,isTruncated]); @override String toString() { - return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, repliedGone: $repliedGone, forwardedGone: $forwardedGone, isTruncated: $isTruncated)'; + return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, publisherId: $publisherId, publisher: $publisher, actorid: $actorid, actor: $actor, fediverseUri: $fediverseUri, fediverseType: $fediverseType, contentType: $contentType, attachments: $attachments, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, repliedGone: $repliedGone, forwardedGone: $forwardedGone, isTruncated: $isTruncated)'; } @@ -48,11 +48,11 @@ abstract mixin class $SnPostCopyWith<$Res> { factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl; @useResult $Res call({ - String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List attachments, SnPublisher publisher, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated + String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, String? publisherId, SnPublisher? publisher, String? actorid, SnActivityPubActor? actor, String? fediverseUri, int? fediverseType, int contentType, List attachments, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated }); -$SnPostEmbedViewCopyWith<$Res>? get embedView;$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnRealmCopyWith<$Res>? get realm;$SnPublisherCopyWith<$Res> get publisher; +$SnPostEmbedViewCopyWith<$Res>? get embedView;$SnPostCopyWith<$Res>? get threadedPost;$SnPostCopyWith<$Res>? get repliedPost;$SnPostCopyWith<$Res>? get forwardedPost;$SnRealmCopyWith<$Res>? get realm;$SnPublisherCopyWith<$Res>? get publisher;$SnActivityPubActorCopyWith<$Res>? get actor; } /// @nodoc @@ -65,7 +65,7 @@ class _$SnPostCopyWithImpl<$Res> /// Create a copy of SnPost /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? repliedGone = null,Object? forwardedGone = null,Object? isTruncated = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? publisherId = freezed,Object? publisher = freezed,Object? actorid = freezed,Object? actor = freezed,Object? fediverseUri = freezed,Object? fediverseType = freezed,Object? contentType = null,Object? attachments = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? repliedGone = null,Object? forwardedGone = null,Object? isTruncated = null,}) { return _then(_self.copyWith( id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable @@ -94,9 +94,15 @@ as SnPost?,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : as String?,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable as SnPost?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable -as SnRealm?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable -as List,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable -as SnPublisher,reactionsCount: null == reactionsCount ? _self.reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable +as SnRealm?,publisherId: freezed == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable +as String?,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as SnPublisher?,actorid: freezed == actorid ? _self.actorid : actorid // ignore: cast_nullable_to_non_nullable +as String?,actor: freezed == actor ? _self.actor : actor // ignore: cast_nullable_to_non_nullable +as SnActivityPubActor?,fediverseUri: freezed == fediverseUri ? _self.fediverseUri : fediverseUri // ignore: cast_nullable_to_non_nullable +as String?,fediverseType: freezed == fediverseType ? _self.fediverseType : fediverseType // ignore: cast_nullable_to_non_nullable +as int?,contentType: null == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable +as int,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable +as List,reactionsCount: null == reactionsCount ? _self.reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable as Map,reactionsMade: null == reactionsMade ? _self.reactionsMade : reactionsMade // ignore: cast_nullable_to_non_nullable as Map,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable as List,tags: null == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable @@ -176,11 +182,26 @@ $SnRealmCopyWith<$Res>? get realm { /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') -$SnPublisherCopyWith<$Res> get publisher { - - return $SnPublisherCopyWith<$Res>(_self.publisher, (value) { +$SnPublisherCopyWith<$Res>? get publisher { + if (_self.publisher == null) { + return null; + } + + return $SnPublisherCopyWith<$Res>(_self.publisher!, (value) { return _then(_self.copyWith(publisher: value)); }); +}/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnActivityPubActorCopyWith<$Res>? get actor { + if (_self.actor == null) { + return null; + } + + return $SnActivityPubActorCopyWith<$Res>(_self.actor!, (value) { + return _then(_self.copyWith(actor: value)); + }); } } @@ -260,10 +281,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List attachments, SnPublisher publisher, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, String? publisherId, SnPublisher? publisher, String? actorid, SnActivityPubActor? actor, String? fediverseUri, int? fediverseType, int contentType, List attachments, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _SnPost() when $default != null: -return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);case _: +return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.publisherId,_that.publisher,_that.actorid,_that.actor,_that.fediverseUri,_that.fediverseType,_that.contentType,_that.attachments,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);case _: return orElse(); } @@ -281,10 +302,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List attachments, SnPublisher publisher, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, String? publisherId, SnPublisher? publisher, String? actorid, SnActivityPubActor? actor, String? fediverseUri, int? fediverseType, int contentType, List attachments, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated) $default,) {final _that = this; switch (_that) { case _SnPost(): -return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);} +return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.publisherId,_that.publisher,_that.actorid,_that.actor,_that.fediverseUri,_that.fediverseType,_that.contentType,_that.attachments,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);} } /// A variant of `when` that fallback to returning `null` /// @@ -298,10 +319,10 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List attachments, SnPublisher publisher, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, String? publisherId, SnPublisher? publisher, String? actorid, SnActivityPubActor? actor, String? fediverseUri, int? fediverseType, int contentType, List attachments, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated)? $default,) {final _that = this; switch (_that) { case _SnPost() when $default != null: -return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.attachments,_that.publisher,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);case _: +return $default(_that.id,_that.title,_that.description,_that.language,_that.editedAt,_that.publishedAt,_that.visibility,_that.content,_that.slug,_that.type,_that.meta,_that.embedView,_that.viewsUnique,_that.viewsTotal,_that.upvotes,_that.downvotes,_that.repliesCount,_that.awardedScore,_that.pinMode,_that.threadedPostId,_that.threadedPost,_that.repliedPostId,_that.repliedPost,_that.forwardedPostId,_that.forwardedPost,_that.realmId,_that.realm,_that.publisherId,_that.publisher,_that.actorid,_that.actor,_that.fediverseUri,_that.fediverseType,_that.contentType,_that.attachments,_that.reactionsCount,_that.reactionsMade,_that.reactions,_that.tags,_that.categories,_that.collections,_that.featuredRecords,_that.createdAt,_that.updatedAt,_that.deletedAt,_that.repliedGone,_that.forwardedGone,_that.isTruncated);case _: return null; } @@ -313,7 +334,7 @@ return $default(_that.id,_that.title,_that.description,_that.language,_that.edit @JsonSerializable() class _SnPost implements SnPost { - const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, final List attachments = const [], required this.publisher, final Map reactionsCount = const {}, final Map reactionsMade = const {}, final List reactions = const [], final List tags = const [], final List categories = const [], final List collections = const [], final List featuredRecords = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.repliedGone = false, this.forwardedGone = false, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections,_featuredRecords = featuredRecords; + const _SnPost({required this.id, this.title, this.description, this.language, this.editedAt, this.publishedAt = null, this.visibility = 0, this.content, this.slug, this.type = 0, final Map? meta, this.embedView, this.viewsUnique = 0, this.viewsTotal = 0, this.upvotes = 0, this.downvotes = 0, this.repliesCount = 0, this.awardedScore = 0, this.pinMode, this.threadedPostId, this.threadedPost, this.repliedPostId, this.repliedPost, this.forwardedPostId, this.forwardedPost, this.realmId, this.realm, this.publisherId, this.publisher, this.actorid, this.actor, this.fediverseUri, this.fediverseType, this.contentType = 0, final List attachments = const [], final Map reactionsCount = const {}, final Map reactionsMade = const {}, final List reactions = const [], final List tags = const [], final List categories = const [], final List collections = const [], final List featuredRecords = const [], this.createdAt = null, this.updatedAt = null, this.deletedAt, this.repliedGone = false, this.forwardedGone = false, this.isTruncated = false}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactionsMade = reactionsMade,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections,_featuredRecords = featuredRecords; factory _SnPost.fromJson(Map json) => _$SnPostFromJson(json); @override final String id; @@ -351,6 +372,13 @@ class _SnPost implements SnPost { @override final SnPost? forwardedPost; @override final String? realmId; @override final SnRealm? realm; +@override final String? publisherId; +@override final SnPublisher? publisher; +@override final String? actorid; +@override final SnActivityPubActor? actor; +@override final String? fediverseUri; +@override final int? fediverseType; +@override@JsonKey() final int contentType; final List _attachments; @override@JsonKey() List get attachments { if (_attachments is EqualUnmodifiableListView) return _attachments; @@ -358,7 +386,6 @@ class _SnPost implements SnPost { return EqualUnmodifiableListView(_attachments); } -@override final SnPublisher publisher; final Map _reactionsCount; @override@JsonKey() Map get reactionsCount { if (_reactionsCount is EqualUnmodifiableMapView) return _reactionsCount; @@ -428,16 +455,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&const DeepCollectionEquality().equals(other._featuredRecords, _featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.repliedGone, repliedGone) || other.repliedGone == repliedGone)&&(identical(other.forwardedGone, forwardedGone) || other.forwardedGone == forwardedGone)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.slug, slug) || other.slug == slug)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.embedView, embedView) || other.embedView == embedView)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.awardedScore, awardedScore) || other.awardedScore == awardedScore)&&(identical(other.pinMode, pinMode) || other.pinMode == pinMode)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&(identical(other.realmId, realmId) || other.realmId == realmId)&&(identical(other.realm, realm) || other.realm == realm)&&(identical(other.publisherId, publisherId) || other.publisherId == publisherId)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&(identical(other.actorid, actorid) || other.actorid == actorid)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.fediverseUri, fediverseUri) || other.fediverseUri == fediverseUri)&&(identical(other.fediverseType, fediverseType) || other.fediverseType == fediverseType)&&(identical(other.contentType, contentType) || other.contentType == contentType)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactionsMade, _reactionsMade)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&const DeepCollectionEquality().equals(other._featuredRecords, _featuredRecords)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.repliedGone, repliedGone) || other.repliedGone == repliedGone)&&(identical(other.forwardedGone, forwardedGone) || other.forwardedGone == forwardedGone)&&(identical(other.isTruncated, isTruncated) || other.isTruncated == isTruncated)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),const DeepCollectionEquality().hash(_featuredRecords),createdAt,updatedAt,deletedAt,repliedGone,forwardedGone,isTruncated]); +int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,slug,type,const DeepCollectionEquality().hash(_meta),embedView,viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,awardedScore,pinMode,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,realmId,realm,publisherId,publisher,actorid,actor,fediverseUri,fediverseType,contentType,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactionsMade),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),const DeepCollectionEquality().hash(_featuredRecords),createdAt,updatedAt,deletedAt,repliedGone,forwardedGone,isTruncated]); @override String toString() { - return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, repliedGone: $repliedGone, forwardedGone: $forwardedGone, isTruncated: $isTruncated)'; + return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, slug: $slug, type: $type, meta: $meta, embedView: $embedView, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, awardedScore: $awardedScore, pinMode: $pinMode, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, realmId: $realmId, realm: $realm, publisherId: $publisherId, publisher: $publisher, actorid: $actorid, actor: $actor, fediverseUri: $fediverseUri, fediverseType: $fediverseType, contentType: $contentType, attachments: $attachments, reactionsCount: $reactionsCount, reactionsMade: $reactionsMade, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, featuredRecords: $featuredRecords, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, repliedGone: $repliedGone, forwardedGone: $forwardedGone, isTruncated: $isTruncated)'; } @@ -448,11 +475,11 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> { factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl; @override @useResult $Res call({ - String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, List attachments, SnPublisher publisher, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated + String id, String? title, String? description, String? language, DateTime? editedAt, DateTime? publishedAt, int visibility, String? content, String? slug, int type, Map? meta, SnPostEmbedView? embedView, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, int awardedScore, int? pinMode, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, String? realmId, SnRealm? realm, String? publisherId, SnPublisher? publisher, String? actorid, SnActivityPubActor? actor, String? fediverseUri, int? fediverseType, int contentType, List attachments, Map reactionsCount, Map reactionsMade, List reactions, List tags, List categories, List collections, List featuredRecords, DateTime? createdAt, DateTime? updatedAt, DateTime? deletedAt, bool repliedGone, bool forwardedGone, bool isTruncated }); -@override $SnPostEmbedViewCopyWith<$Res>? get embedView;@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnRealmCopyWith<$Res>? get realm;@override $SnPublisherCopyWith<$Res> get publisher; +@override $SnPostEmbedViewCopyWith<$Res>? get embedView;@override $SnPostCopyWith<$Res>? get threadedPost;@override $SnPostCopyWith<$Res>? get repliedPost;@override $SnPostCopyWith<$Res>? get forwardedPost;@override $SnRealmCopyWith<$Res>? get realm;@override $SnPublisherCopyWith<$Res>? get publisher;@override $SnActivityPubActorCopyWith<$Res>? get actor; } /// @nodoc @@ -465,7 +492,7 @@ class __$SnPostCopyWithImpl<$Res> /// Create a copy of SnPost /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? repliedGone = null,Object? forwardedGone = null,Object? isTruncated = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = freezed,Object? visibility = null,Object? content = freezed,Object? slug = freezed,Object? type = null,Object? meta = freezed,Object? embedView = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? awardedScore = null,Object? pinMode = freezed,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? realmId = freezed,Object? realm = freezed,Object? publisherId = freezed,Object? publisher = freezed,Object? actorid = freezed,Object? actor = freezed,Object? fediverseUri = freezed,Object? fediverseType = freezed,Object? contentType = null,Object? attachments = null,Object? reactionsCount = null,Object? reactionsMade = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? featuredRecords = null,Object? createdAt = freezed,Object? updatedAt = freezed,Object? deletedAt = freezed,Object? repliedGone = null,Object? forwardedGone = null,Object? isTruncated = null,}) { return _then(_SnPost( id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable @@ -494,9 +521,15 @@ as SnPost?,forwardedPostId: freezed == forwardedPostId ? _self.forwardedPostId : as String?,forwardedPost: freezed == forwardedPost ? _self.forwardedPost : forwardedPost // ignore: cast_nullable_to_non_nullable as SnPost?,realmId: freezed == realmId ? _self.realmId : realmId // ignore: cast_nullable_to_non_nullable as String?,realm: freezed == realm ? _self.realm : realm // ignore: cast_nullable_to_non_nullable -as SnRealm?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable -as List,publisher: null == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable -as SnPublisher,reactionsCount: null == reactionsCount ? _self._reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable +as SnRealm?,publisherId: freezed == publisherId ? _self.publisherId : publisherId // ignore: cast_nullable_to_non_nullable +as String?,publisher: freezed == publisher ? _self.publisher : publisher // ignore: cast_nullable_to_non_nullable +as SnPublisher?,actorid: freezed == actorid ? _self.actorid : actorid // ignore: cast_nullable_to_non_nullable +as String?,actor: freezed == actor ? _self.actor : actor // ignore: cast_nullable_to_non_nullable +as SnActivityPubActor?,fediverseUri: freezed == fediverseUri ? _self.fediverseUri : fediverseUri // ignore: cast_nullable_to_non_nullable +as String?,fediverseType: freezed == fediverseType ? _self.fediverseType : fediverseType // ignore: cast_nullable_to_non_nullable +as int?,contentType: null == contentType ? _self.contentType : contentType // ignore: cast_nullable_to_non_nullable +as int,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable +as List,reactionsCount: null == reactionsCount ? _self._reactionsCount : reactionsCount // ignore: cast_nullable_to_non_nullable as Map,reactionsMade: null == reactionsMade ? _self._reactionsMade : reactionsMade // ignore: cast_nullable_to_non_nullable as Map,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable as List,tags: null == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable @@ -577,11 +610,26 @@ $SnRealmCopyWith<$Res>? get realm { /// with the given fields replaced by the non-null parameter values. @override @pragma('vm:prefer-inline') -$SnPublisherCopyWith<$Res> get publisher { - - return $SnPublisherCopyWith<$Res>(_self.publisher, (value) { +$SnPublisherCopyWith<$Res>? get publisher { + if (_self.publisher == null) { + return null; + } + + return $SnPublisherCopyWith<$Res>(_self.publisher!, (value) { return _then(_self.copyWith(publisher: value)); }); +}/// Create a copy of SnPost +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnActivityPubActorCopyWith<$Res>? get actor { + if (_self.actor == null) { + return null; + } + + return $SnActivityPubActorCopyWith<$Res>(_self.actor!, (value) { + return _then(_self.copyWith(actor: value)); + }); } } diff --git a/lib/models/post.g.dart b/lib/models/post.g.dart index d74b0c42..08935e00 100644 --- a/lib/models/post.g.dart +++ b/lib/models/post.g.dart @@ -48,12 +48,22 @@ _SnPost _$SnPostFromJson(Map json) => _SnPost( realm: json['realm'] == null ? null : SnRealm.fromJson(json['realm'] as Map), + publisherId: json['publisher_id'] as String?, + publisher: json['publisher'] == null + ? null + : SnPublisher.fromJson(json['publisher'] as Map), + actorid: json['actorid'] as String?, + actor: json['actor'] == null + ? null + : SnActivityPubActor.fromJson(json['actor'] as Map), + fediverseUri: json['fediverse_uri'] as String?, + fediverseType: (json['fediverse_type'] as num?)?.toInt(), + contentType: (json['content_type'] as num?)?.toInt() ?? 0, attachments: (json['attachments'] as List?) ?.map((e) => SnCloudFile.fromJson(e as Map)) .toList() ?? const [], - publisher: SnPublisher.fromJson(json['publisher'] as Map), reactionsCount: (json['reactions_count'] as Map?)?.map( (k, e) => MapEntry(k, (e as num).toInt()), @@ -123,8 +133,14 @@ Map _$SnPostToJson(_SnPost instance) => { 'forwarded_post': instance.forwardedPost?.toJson(), 'realm_id': instance.realmId, 'realm': instance.realm?.toJson(), + 'publisher_id': instance.publisherId, + 'publisher': instance.publisher?.toJson(), + 'actorid': instance.actorid, + 'actor': instance.actor?.toJson(), + 'fediverse_uri': instance.fediverseUri, + 'fediverse_type': instance.fediverseType, + 'content_type': instance.contentType, 'attachments': instance.attachments.map((e) => e.toJson()).toList(), - 'publisher': instance.publisher.toJson(), 'reactions_count': instance.reactionsCount, 'reactions_made': instance.reactionsMade, 'reactions': instance.reactions, diff --git a/lib/pods/timeline.dart b/lib/pods/timeline.dart index fc75dbdc..ae2ffc9c 100644 --- a/lib/pods/timeline.dart +++ b/lib/pods/timeline.dart @@ -24,6 +24,7 @@ class ActivityListNotifier extends AsyncNotifier> if (cursor != null) 'cursor': cursor, 'take': pageSize, if (currentFilter != null) 'filter': currentFilter, + 'showFediverse': true, }; final response = await client.get( diff --git a/lib/screens/posts/post_detail.dart b/lib/screens/posts/post_detail.dart index b89ab2d0..567930f2 100644 --- a/lib/screens/posts/post_detail.dart +++ b/lib/screens/posts/post_detail.dart @@ -80,7 +80,7 @@ class PostActionButtons extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final user = ref.watch(userInfoProvider); final isAuthor = - user.value != null && user.value?.id == post.publisher.accountId; + user.value != null && user.value?.id == post.publisher?.accountId; String formatScore(int score) { if (score >= 1000000) { @@ -303,10 +303,9 @@ class PostActionButtons extends HookConsumerWidget { ); }, icon: const Icon(Symbols.emoji_events), - label: - post.awardedScore > 0 - ? Text('${formatScore(post.awardedScore)} pts') - : Text('award').tr(), + label: post.awardedScore > 0 + ? Text('${formatScore(post.awardedScore)} pts') + : Text('award').tr(), ), ); @@ -323,10 +322,9 @@ class PostActionButtons extends HookConsumerWidget { actions.add( Row( mainAxisSize: MainAxisSize.min, - children: - replyButtons - .map((e) => SizedBox(height: kButtonHeight, child: e)) - .toList(), + children: replyButtons + .map((e) => SizedBox(height: kButtonHeight, child: e)) + .toList(), ), ); @@ -415,16 +413,15 @@ class PostActionButtons extends HookConsumerWidget { ); // Add gaps between actions (excluding first one) using FP style - final children = - actions.asMap().entries.expand((entry) { - final index = entry.key; - final action = entry.value; - if (index == 0) { - return [action]; - } else { - return [const Gap(8), action]; - } - }).toList(); + final children = actions.asMap().entries.expand((entry) { + final index = entry.key; + final action = entry.value; + if (index == 0) { + return [action]; + } else { + return [const Gap(8), action]; + } + }).toList(); return Container( height: kButtonHeight, @@ -518,33 +515,28 @@ class PostDetailScreen extends HookConsumerWidget { bottom: 16 + MediaQuery.of(context).padding.bottom, left: 16, right: 16, - child: - ConstrainedBox( - constraints: BoxConstraints(maxWidth: 660), - child: postState.when( - data: - (post) => PostQuickReply( - parent: post!, - onPosted: () { - ref - .read(postRepliesProvider(id).notifier) - .refresh(); - }, - ), - loading: () => const SizedBox.shrink(), - error: (_, _) => const SizedBox.shrink(), - ), - ).center(), + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 660), + child: postState.when( + data: (post) => PostQuickReply( + parent: post!, + onPosted: () { + ref.read(postRepliesProvider(id).notifier).refresh(); + }, + ), + loading: () => const SizedBox.shrink(), + error: (_, _) => const SizedBox.shrink(), + ), + ).center(), ), ], ); }, loading: () => ResponseLoadingWidget(), - error: - (e, _) => ResponseErrorWidget( - error: e, - onRetry: () => ref.invalidate(postProvider(id)), - ), + error: (e, _) => ResponseErrorWidget( + error: e, + onRetry: () => ref.invalidate(postProvider(id)), + ), ), ); } diff --git a/lib/widgets/activitypub/actor_profile.dart b/lib/widgets/activitypub/actor_profile.dart new file mode 100644 index 00000000..9979798e --- /dev/null +++ b/lib/widgets/activitypub/actor_profile.dart @@ -0,0 +1,58 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:island/models/activitypub.dart'; +import 'package:material_symbols_icons/symbols.dart'; + +class ActorAvatarWidget extends StatelessWidget { + final SnActivityPubActor actor; + final double radius; + + const ActorAvatarWidget({super.key, required this.actor, this.radius = 16}); + + @override + Widget build(BuildContext context) { + final avatarUrl = actor.avatarUrl; + if (avatarUrl == null) { + return CircleAvatar( + radius: radius, + backgroundColor: Theme.of(context).colorScheme.surfaceContainer, + child: Icon( + Symbols.person, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ); + } + + return Stack( + children: [ + CircleAvatar( + backgroundImage: CachedNetworkImageProvider(avatarUrl), + radius: radius, + backgroundColor: Theme.of(context).colorScheme.surfaceContainer, + child: Icon( + Symbols.person, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + Positioned( + right: 0, + bottom: 0, + child: CircleAvatar( + backgroundImage: actor.instance.iconUrl != null + ? CachedNetworkImageProvider(actor.instance.iconUrl!) + : null, + radius: radius * 0.4, + backgroundColor: Theme.of(context).colorScheme.primary, + child: actor.instance.iconUrl == null + ? Icon( + Symbols.public, + size: radius * 0.6, + color: Theme.of(context).colorScheme.onPrimary, + ) + : null, + ), + ), + ], + ); + } +} diff --git a/lib/widgets/post/compose_info_banner.dart b/lib/widgets/post/compose_info_banner.dart index f5edfe93..90890b27 100644 --- a/lib/widgets/post/compose_info_banner.dart +++ b/lib/widgets/post/compose_info_banner.dart @@ -115,10 +115,9 @@ class ComposeInfoBanner extends StatelessWidget { const Gap(8), CompactReferencePost( post: post, - onTap: - onReferencePostTap != null - ? () => onReferencePostTap!(context, post) - : null, + onTap: onReferencePostTap != null + ? () => onReferencePostTap!(context, post) + : null, ), ], ).padding(all: 16), @@ -133,6 +132,58 @@ class CompactReferencePost extends StatelessWidget { const CompactReferencePost({super.key, required this.post, this.onTap}); + Widget _buildProfilePicture(BuildContext context) { + // Handle publisher case + if (post.publisher != null) { + return ProfilePictureWidget( + fileId: post.publisher!.picture?.id, + radius: 16, + ); + } + // Handle actor case + if (post.actor != null) { + final avatarUrl = post.actor!.avatarUrl; + if (avatarUrl != null) { + return Container( + width: 32, + height: 32, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(16), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: Image.network( + avatarUrl, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Icon( + Symbols.account_circle, + size: 16, + color: Theme.of(context).colorScheme.onPrimaryContainer, + ); + }, + ), + ), + ); + } + } + // Fallback + return ProfilePictureWidget(fileId: null, radius: 16); + } + + String _getDisplayName() { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.nick; + } + // Handle actor case + if (post.actor != null) { + return post.actor!.displayName ?? post.actor!.username ?? 'Unknown'; + } + return 'Unknown'; + } + @override Widget build(BuildContext context) { final theme = Theme.of(context); @@ -148,17 +199,14 @@ class CompactReferencePost extends StatelessWidget { ), child: Row( children: [ - ProfilePictureWidget( - fileId: post.publisher.picture?.id, - radius: 16, - ), + _buildProfilePicture(context), const Gap(8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - post.publisher.nick, + _getDisplayName(), style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, diff --git a/lib/widgets/post/post_award_sheet.dart b/lib/widgets/post/post_award_sheet.dart index cfcbbf2c..6c628631 100644 --- a/lib/widgets/post/post_award_sheet.dart +++ b/lib/widgets/post/post_award_sheet.dart @@ -16,6 +16,59 @@ class PostAwardSheet extends HookConsumerWidget { final SnPost post; const PostAwardSheet({super.key, required this.post}); + Widget _buildProfilePicture(BuildContext context, {double radius = 16}) { + // Handle publisher case + if (post.publisher != null) { + return ProfilePictureWidget( + file: + post.publisher!.picture ?? post.publisher!.account?.profile.picture, + radius: radius, + ); + } + // Handle actor case + if (post.actor != null) { + final avatarUrl = post.actor!.avatarUrl; + if (avatarUrl != null) { + return Container( + width: radius * 2, + height: radius * 2, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primaryContainer, + borderRadius: BorderRadius.circular(radius), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(radius), + child: Image.network( + avatarUrl, + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) { + return Icon( + Symbols.account_circle, + size: radius, + color: Theme.of(context).colorScheme.onPrimaryContainer, + ); + }, + ), + ), + ); + } + } + // Fallback + return ProfilePictureWidget(fileId: null, radius: radius); + } + + String _getPublisherName() { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.name; + } + // Handle actor case + if (post.actor != null) { + return post.actor!.username ?? 'Unknown'; + } + return 'Unknown'; + } + @override Widget build(BuildContext context, WidgetRef ref) { final messageController = useTextEditingController(); @@ -97,14 +150,13 @@ class PostAwardSheet extends HookConsumerWidget { SizedBox( width: double.infinity, child: FilledButton.icon( - onPressed: - () => _submitAward( - context, - ref, - messageController, - amountController, - selectedAttitude.value, - ), + onPressed: () => _submitAward( + context, + ref, + messageController, + amountController, + selectedAttitude.value, + ), icon: const Icon(Symbols.star), label: Text('awardSubmit'.tr()), ), @@ -157,12 +209,12 @@ class PostAwardSheet extends HookConsumerWidget { spacing: 6, children: [ Text( - 'awardByPublisher'.tr(args: ['@${post.publisher.name}']), + 'awardByPublisher'.tr(args: ['@${_getPublisherName()}']), style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), - ProfilePictureWidget(file: post.publisher.picture, radius: 8), + _buildProfilePicture(context, radius: 8), ], ), ], diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index 3b59d45c..5c3949b6 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -90,7 +90,7 @@ class PostActionableItem extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final user = ref.watch(userInfoProvider); final isAuthor = useMemoized( - () => user.value != null && user.value?.id == item.publisher.accountId, + () => user.value != null && item.publisher?.accountId == user.value?.id, [user], ); diff --git a/lib/widgets/post/post_item_screenshot.dart b/lib/widgets/post/post_item_screenshot.dart index 285ef703..1455b309 100644 --- a/lib/widgets/post/post_item_screenshot.dart +++ b/lib/widgets/post/post_item_screenshot.dart @@ -196,8 +196,8 @@ class PostItemScreenshot extends ConsumerWidget { children: [ ProfilePictureWidget( file: - post.publisher.picture ?? - post.publisher.account?.profile.picture, + post.publisher?.picture ?? + post.publisher?.account?.profile.picture, radius: 12, ).padding(top: 4), if (post.content?.isNotEmpty ?? false) diff --git a/lib/widgets/post/post_shared.dart b/lib/widgets/post/post_shared.dart index 28cb133b..ed989277 100644 --- a/lib/widgets/post/post_shared.dart +++ b/lib/widgets/post/post_shared.dart @@ -6,10 +6,13 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:html2md/html2md.dart' as html2md; +import 'package:island/models/account.dart'; import 'package:island/models/post.dart'; import 'package:island/pods/network.dart'; import 'package:island/services/time.dart'; import 'package:island/widgets/account/account_name.dart'; +import 'package:island/widgets/activitypub/actor_profile.dart'; import 'package:island/widgets/alert.dart'; import 'package:island/widgets/content/cloud_file_collection.dart'; import 'package:island/widgets/content/cloud_files.dart'; @@ -24,6 +27,14 @@ part 'post_shared.g.dart'; const kMessageEnableEmbedTypes = ['text', 'messages.new']; +/// Converts HTML content to markdown if contentType indicates HTML (contentType == 1) +String _convertContentToMarkdown(SnPost post) { + if (post.contentType == 1 && post.content != null) { + return html2md.convert(post.content!); + } + return post.content ?? ''; +} + class RepliesState { final List posts; final bool loading; @@ -120,6 +131,27 @@ class PostReplyPreview extends HookConsumerWidget { this.onOpen, }); + Widget _buildProfilePicture( + BuildContext context, + SnPost post, { + double radius = 16, + }) { + // Handle publisher case + if (post.publisher != null) { + return ProfilePictureWidget( + file: + post.publisher!.picture ?? post.publisher!.account?.profile.picture, + radius: radius, + ); + } + // Handle actor case + if (post.actor != null) { + return ActorAvatarWidget(actor: post.actor!, radius: radius); + } + // Fallback + return ProfilePictureWidget(fileId: null, radius: radius); + } + @override Widget build(BuildContext context, WidgetRef ref) { final repliesState = ref.watch(repliesProvider(parent.id)); @@ -157,16 +189,15 @@ class PostReplyPreview extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 8, children: [ - ProfilePictureWidget( - file: - post.publisher.picture ?? - post.publisher.account?.profile.picture, + _buildProfilePicture( + context, + post, radius: 12, ).padding(top: 4), if (post.content?.isNotEmpty ?? false) Expanded( child: MarkdownTextContent( - content: post.content!, + content: _convertContentToMarkdown(post), attachments: post.attachments, ).padding(top: 2), ) @@ -244,16 +275,15 @@ class PostReplyPreview extends HookConsumerWidget { crossAxisAlignment: CrossAxisAlignment.start, spacing: 8, children: [ - ProfilePictureWidget( - file: - data.value?.publisher.picture ?? - data.value?.publisher.account?.profile.picture, + _buildProfilePicture( + context, + data.value!, radius: 12, ).padding(top: 4), if (data.value?.content?.isNotEmpty ?? false) Expanded( child: MarkdownTextContent( - content: data.value!.content!, + content: _convertContentToMarkdown(data.value!), attachments: data.value!.attachments, ), ) @@ -408,6 +438,38 @@ class ReferencedPostWidget extends StatelessWidget { this.renderingPadding = EdgeInsets.zero, }); + Widget _buildProfilePicture( + BuildContext context, + SnPost post, { + double radius = 16, + }) { + // Handle publisher case + if (post.publisher != null) { + return ProfilePictureWidget( + fileId: post.publisher!.picture?.id, + radius: radius, + ); + } + // Handle actor case + if (post.actor != null) { + return ActorAvatarWidget(actor: post.actor!, radius: radius); + } + // Fallback + return ProfilePictureWidget(fileId: null, radius: radius); + } + + String _getDisplayName(SnPost post) { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.nick; + } + // Handle actor case + if (post.actor != null) { + return post.actor!.displayName ?? post.actor!.username ?? 'Unknown'; + } + return 'Unknown'; + } + @override Widget build(BuildContext context) { final referencePost = item.repliedPost ?? item.forwardedPost; @@ -479,17 +541,14 @@ class ReferencedPostWidget extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ProfilePictureWidget( - fileId: referencePost!.publisher.picture?.id, - radius: 16, - ), + _buildProfilePicture(context, referencePost!, radius: 16), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - referencePost.publisher.nick, + _getDisplayName(referencePost), style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, @@ -541,7 +600,7 @@ class ReferencedPostWidget extends StatelessWidget { ).padding(bottom: 2), if (referencePost.content?.isNotEmpty ?? false) MarkdownTextContent( - content: referencePost.content!, + content: _convertContentToMarkdown(referencePost), textStyle: const TextStyle(fontSize: 14), isSelectable: false, linesMargin: referencePost.type == 0 @@ -620,6 +679,72 @@ class PostHeader extends StatelessWidget { this.hideOverlay = false, }); + Widget _buildProfilePicture( + BuildContext context, + SnPost post, { + double radius = 16, + }) { + // Handle publisher case + if (post.publisher != null) { + return ProfilePictureWidget( + file: + post.publisher!.picture ?? post.publisher!.account?.profile.picture, + radius: radius, + borderRadius: post.publisher!.type == 0 ? null : 6, + ); + } + // Handle actor case + if (post.actor != null) { + return ActorAvatarWidget(actor: post.actor!, radius: radius); + } + // Fallback + return ProfilePictureWidget(fileId: null, radius: radius); + } + + String _getDisplayName(SnPost post) { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.nick; + } + // Handle actor case + if (post.actor != null) { + return post.actor!.displayName ?? post.actor!.username ?? 'unknown'.tr(); + } + return 'unknown'.tr(); + } + + String? _getPublisherName(SnPost post) { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.name; + } + // Handle actor case + if (post.actor != null) { + return '${post.actor!.username}@${post.actor!.instance.domain}'; + } + return null; + } + + int _getPublisherType(SnPost post) { + // Handle publisher case + if (post.publisher != null) { + return post.publisher!.type; + } + return 0; // Default to user type + } + + bool _hasAccount(SnPost post) { + return post.publisher?.account != null; + } + + SnAccount? _getAccount(SnPost post) { + return post.publisher?.account; + } + + SnVerificationMark? _getVerification(SnPost post) { + return post.publisher?.verification; + } + @override Widget build(BuildContext context) { return Column( @@ -629,21 +754,17 @@ class PostHeader extends StatelessWidget { spacing: 12, children: [ GestureDetector( - onTap: isInteractive + onTap: isInteractive && _getPublisherName(item) != null ? () { context.pushNamed( 'publisherProfile', - pathParameters: {'name': item.publisher.name}, + pathParameters: { + 'name': _getPublisherName(item) as String, + }, ); } : null, - child: ProfilePictureWidget( - file: - item.publisher.picture ?? - item.publisher.account?.profile.picture, - radius: 16, - borderRadius: item.publisher.type == 0 ? null : 6, - ), + child: _buildProfilePicture(context, item, radius: 16), ), Expanded( child: Column( @@ -656,24 +777,23 @@ class PostHeader extends StatelessWidget { children: [ Flexible( child: - (item.publisher.account != null && - item.publisher.type == 0) + (_hasAccount(item) && _getPublisherType(item) == 0) ? AccountName( hideOverlay: hideOverlay, - account: item.publisher.account!, - textOverride: item.publisher.nick, + account: _getAccount(item)!, + textOverride: _getDisplayName(item), style: TextStyle(fontWeight: FontWeight.bold), hideVerificationMark: true, ) : Text( - item.publisher.nick, + _getDisplayName(item), maxLines: 1, overflow: TextOverflow.ellipsis, ).bold(), ), - if (item.publisher.verification != null) + if (_getVerification(item) != null) VerificationMark( - mark: item.publisher.verification!, + mark: _getVerification(item)!, hideOverlay: hideOverlay, ), if (item.realm == null) @@ -681,7 +801,7 @@ class PostHeader extends StatelessWidget { child: isCompact ? const SizedBox.shrink() : Text( - '@${item.publisher.name}', + '@${_getPublisherName(item) ?? 'unknown'}', maxLines: 1, overflow: TextOverflow.ellipsis, ).fontSize(11), @@ -891,6 +1011,17 @@ class PostBody extends ConsumerWidget { ), ); } + if (item.fediverseUri != null) { + metadataChildren.add( + Row( + spacing: 8, + children: [ + const Icon(Symbols.globe, size: 16), + Text('fediversePostDescribe'.tr()).fontSize(13), + ], + ), + ); + } return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -937,7 +1068,7 @@ class PostBody extends ConsumerWidget { ) else MarkdownTextContent( - content: '${item.content!}...', + content: '${_convertContentToMarkdown(item)}...', attachments: item.attachments, ), ], @@ -974,8 +1105,8 @@ class PostBody extends ConsumerWidget { ).padding(bottom: 4), MarkdownTextContent( content: item.isTruncated - ? '${item.content!}...' - : item.content ?? '', + ? '${_convertContentToMarkdown(item)}...' + : _convertContentToMarkdown(item), isSelectable: isTextSelectable, attachments: item.attachments, ),