Able to render fediverse reactions (likes)

This commit is contained in:
2026-01-01 02:37:05 +08:00
parent 93d2670063
commit 3b564f7e7f
4 changed files with 149 additions and 106 deletions

View File

@@ -162,10 +162,12 @@ sealed class SnPostReaction with _$SnPostReaction {
required String symbol, required String symbol,
required int attitude, required int attitude,
required String postId, required String postId,
required String accountId,
required DateTime createdAt, required DateTime createdAt,
required DateTime updatedAt, required DateTime updatedAt,
@Default(null) SnAccount? account, String? actorId,
SnActivityPubActor? actor,
String? accountId,
SnAccount? account,
DateTime? deletedAt, DateTime? deletedAt,
}) = _SnPostReaction; }) = _SnPostReaction;

View File

@@ -1985,7 +1985,7 @@ as DateTime?,
/// @nodoc /// @nodoc
mixin _$SnPostReaction { mixin _$SnPostReaction {
String get id; String get symbol; int get attitude; String get postId; String get accountId; DateTime get createdAt; DateTime get updatedAt; SnAccount? get account; DateTime? get deletedAt; String get id; String get symbol; int get attitude; String get postId; DateTime get createdAt; DateTime get updatedAt; String? get actorId; SnActivityPubActor? get actor; String? get accountId; SnAccount? get account; DateTime? get deletedAt;
/// Create a copy of SnPostReaction /// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@@ -1998,16 +1998,16 @@ $SnPostReactionCopyWith<SnPostReaction> get copyWith => _$SnPostReactionCopyWith
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.actorId, actorId) || other.actorId == actorId)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt); int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,createdAt,updatedAt,actorId,actor,accountId,account,deletedAt);
@override @override
String toString() { String toString() {
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)'; return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, createdAt: $createdAt, updatedAt: $updatedAt, actorId: $actorId, actor: $actor, accountId: $accountId, account: $account, deletedAt: $deletedAt)';
} }
@@ -2018,11 +2018,11 @@ abstract mixin class $SnPostReactionCopyWith<$Res> {
factory $SnPostReactionCopyWith(SnPostReaction value, $Res Function(SnPostReaction) _then) = _$SnPostReactionCopyWithImpl; factory $SnPostReactionCopyWith(SnPostReaction value, $Res Function(SnPostReaction) _then) = _$SnPostReactionCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt String id, String symbol, int attitude, String postId, DateTime createdAt, DateTime updatedAt, String? actorId, SnActivityPubActor? actor, String? accountId, SnAccount? account, DateTime? deletedAt
}); });
$SnAccountCopyWith<$Res>? get account; $SnActivityPubActorCopyWith<$Res>? get actor;$SnAccountCopyWith<$Res>? get account;
} }
/// @nodoc /// @nodoc
@@ -2035,16 +2035,18 @@ class _$SnPostReactionCopyWithImpl<$Res>
/// Create a copy of SnPostReaction /// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? account = freezed,Object? deletedAt = freezed,}) { @pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? createdAt = null,Object? updatedAt = null,Object? actorId = freezed,Object? actor = freezed,Object? accountId = freezed,Object? account = freezed,Object? deletedAt = freezed,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable as DateTime,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?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?, as DateTime?,
)); ));
@@ -2053,6 +2055,18 @@ as DateTime?,
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @override
@pragma('vm:prefer-inline') @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));
});
}/// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account { $SnAccountCopyWith<$Res>? get account {
if (_self.account == null) { if (_self.account == null) {
return null; return null;
@@ -2140,10 +2154,10 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id, String symbol, int attitude, String postId, DateTime createdAt, DateTime updatedAt, String? actorId, SnActivityPubActor? actor, String? accountId, SnAccount? account, DateTime? deletedAt)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _SnPostReaction() when $default != null: case _SnPostReaction() when $default != null:
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_that.deletedAt);case _: return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.createdAt,_that.updatedAt,_that.actorId,_that.actor,_that.accountId,_that.account,_that.deletedAt);case _:
return orElse(); return orElse();
} }
@@ -2161,10 +2175,10 @@ return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountI
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id, String symbol, int attitude, String postId, DateTime createdAt, DateTime updatedAt, String? actorId, SnActivityPubActor? actor, String? accountId, SnAccount? account, DateTime? deletedAt) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPostReaction(): case _SnPostReaction():
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_that.deletedAt);} return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.createdAt,_that.updatedAt,_that.actorId,_that.actor,_that.accountId,_that.account,_that.deletedAt);}
} }
/// A variant of `when` that fallback to returning `null` /// A variant of `when` that fallback to returning `null`
/// ///
@@ -2178,10 +2192,10 @@ return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountI
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id, String symbol, int attitude, String postId, DateTime createdAt, DateTime updatedAt, String? actorId, SnActivityPubActor? actor, String? accountId, SnAccount? account, DateTime? deletedAt)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPostReaction() when $default != null: case _SnPostReaction() when $default != null:
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_that.deletedAt);case _: return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.createdAt,_that.updatedAt,_that.actorId,_that.actor,_that.accountId,_that.account,_that.deletedAt);case _:
return null; return null;
} }
@@ -2193,17 +2207,19 @@ return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountI
@JsonSerializable() @JsonSerializable()
class _SnPostReaction implements SnPostReaction { class _SnPostReaction implements SnPostReaction {
const _SnPostReaction({required this.id, required this.symbol, required this.attitude, required this.postId, required this.accountId, required this.createdAt, required this.updatedAt, this.account = null, this.deletedAt}); const _SnPostReaction({required this.id, required this.symbol, required this.attitude, required this.postId, required this.createdAt, required this.updatedAt, this.actorId, this.actor, this.accountId, this.account, this.deletedAt});
factory _SnPostReaction.fromJson(Map<String, dynamic> json) => _$SnPostReactionFromJson(json); factory _SnPostReaction.fromJson(Map<String, dynamic> json) => _$SnPostReactionFromJson(json);
@override final String id; @override final String id;
@override final String symbol; @override final String symbol;
@override final int attitude; @override final int attitude;
@override final String postId; @override final String postId;
@override final String accountId;
@override final DateTime createdAt; @override final DateTime createdAt;
@override final DateTime updatedAt; @override final DateTime updatedAt;
@override@JsonKey() final SnAccount? account; @override final String? actorId;
@override final SnActivityPubActor? actor;
@override final String? accountId;
@override final SnAccount? account;
@override final DateTime? deletedAt; @override final DateTime? deletedAt;
/// Create a copy of SnPostReaction /// Create a copy of SnPostReaction
@@ -2219,16 +2235,16 @@ Map<String, dynamic> toJson() {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPostReaction&&(identical(other.id, id) || other.id == id)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude)&&(identical(other.postId, postId) || other.postId == postId)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.actorId, actorId) || other.actorId == actorId)&&(identical(other.actor, actor) || other.actor == actor)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.account, account) || other.account == account)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt); int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,createdAt,updatedAt,actorId,actor,accountId,account,deletedAt);
@override @override
String toString() { String toString() {
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)'; return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, createdAt: $createdAt, updatedAt: $updatedAt, actorId: $actorId, actor: $actor, accountId: $accountId, account: $account, deletedAt: $deletedAt)';
} }
@@ -2239,11 +2255,11 @@ abstract mixin class _$SnPostReactionCopyWith<$Res> implements $SnPostReactionCo
factory _$SnPostReactionCopyWith(_SnPostReaction value, $Res Function(_SnPostReaction) _then) = __$SnPostReactionCopyWithImpl; factory _$SnPostReactionCopyWith(_SnPostReaction value, $Res Function(_SnPostReaction) _then) = __$SnPostReactionCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt String id, String symbol, int attitude, String postId, DateTime createdAt, DateTime updatedAt, String? actorId, SnActivityPubActor? actor, String? accountId, SnAccount? account, DateTime? deletedAt
}); });
@override $SnAccountCopyWith<$Res>? get account; @override $SnActivityPubActorCopyWith<$Res>? get actor;@override $SnAccountCopyWith<$Res>? get account;
} }
/// @nodoc /// @nodoc
@@ -2256,16 +2272,18 @@ class __$SnPostReactionCopyWithImpl<$Res>
/// Create a copy of SnPostReaction /// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? accountId = null,Object? createdAt = null,Object? updatedAt = null,Object? account = freezed,Object? deletedAt = freezed,}) { @override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? symbol = null,Object? attitude = null,Object? postId = null,Object? createdAt = null,Object? updatedAt = null,Object? actorId = freezed,Object? actor = freezed,Object? accountId = freezed,Object? account = freezed,Object? deletedAt = freezed,}) {
return _then(_SnPostReaction( return _then(_SnPostReaction(
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable as String,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable as int,postId: null == postId ? _self.postId : postId // ignore: cast_nullable_to_non_nullable
as String,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
as DateTime,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable as DateTime,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?,accountId: freezed == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
as String?,account: freezed == account ? _self.account : account // ignore: cast_nullable_to_non_nullable
as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable as SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?, as DateTime?,
)); ));
@@ -2275,6 +2293,18 @@ as DateTime?,
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @override
@pragma('vm:prefer-inline') @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));
});
}/// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$SnAccountCopyWith<$Res>? get account { $SnAccountCopyWith<$Res>? get account {
if (_self.account == null) { if (_self.account == null) {
return null; return null;

View File

@@ -248,9 +248,13 @@ _SnPostReaction _$SnPostReactionFromJson(Map<String, dynamic> json) =>
symbol: json['symbol'] as String, symbol: json['symbol'] as String,
attitude: (json['attitude'] as num).toInt(), attitude: (json['attitude'] as num).toInt(),
postId: json['post_id'] as String, postId: json['post_id'] as String,
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String), createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String), updatedAt: DateTime.parse(json['updated_at'] as String),
actorId: json['actor_id'] as String?,
actor: json['actor'] == null
? null
: SnActivityPubActor.fromJson(json['actor'] as Map<String, dynamic>),
accountId: json['account_id'] as String?,
account: json['account'] == null account: json['account'] == null
? null ? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>), : SnAccount.fromJson(json['account'] as Map<String, dynamic>),
@@ -265,9 +269,11 @@ Map<String, dynamic> _$SnPostReactionToJson(_SnPostReaction instance) =>
'symbol': instance.symbol, 'symbol': instance.symbol,
'attitude': instance.attitude, 'attitude': instance.attitude,
'post_id': instance.postId, 'post_id': instance.postId,
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(), 'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(), 'updated_at': instance.updatedAt.toIso8601String(),
'actor_id': instance.actorId,
'actor': instance.actor?.toJson(),
'account_id': instance.accountId,
'account': instance.account?.toJson(), 'account': instance.account?.toJson(),
'deleted_at': instance.deletedAt?.toIso8601String(), 'deleted_at': instance.deletedAt?.toIso8601String(),
}; };

View File

@@ -11,6 +11,7 @@ import 'package:island/pods/network.dart';
import 'package:island/pods/paging.dart'; import 'package:island/pods/paging.dart';
import 'package:island/services/time.dart'; import 'package:island/services/time.dart';
import 'package:island/widgets/account/account_pfc.dart'; import 'package:island/widgets/account/account_pfc.dart';
import 'package:island/widgets/activitypub/actor_profile.dart';
import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/cloud_files.dart';
import 'package:island/widgets/content/sheet.dart'; import 'package:island/widgets/content/sheet.dart';
import 'package:island/widgets/paging/pagination_list.dart'; import 'package:island/widgets/paging/pagination_list.dart';
@@ -119,7 +120,10 @@ class PostReactionSheet extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
TabBar( TabBar(
tabs: [Tab(text: 'overview'.tr()), Tab(text: 'custom'.tr())], tabs: [
Tab(text: 'overview'.tr()),
Tab(text: 'custom'.tr()),
],
), ),
Expanded( Expanded(
child: TabBarView( child: TabBarView(
@@ -162,8 +166,7 @@ class PostReactionSheet extends StatelessWidget {
} }
Widget _buildCustomReactionSection(BuildContext context) { Widget _buildCustomReactionSection(BuildContext context) {
final customReactions = final customReactions = reactionsCount.entries
reactionsCount.entries
.where((entry) => entry.key.contains('+')) .where((entry) => entry.key.contains('+'))
.map((entry) => entry.key) .map((entry) => entry.key)
.toList(); .toList();
@@ -235,8 +238,7 @@ class PostReactionSheet extends StatelessWidget {
offset: Offset(0, 0), offset: Offset(0, 0),
child: Card( child: Card(
margin: const EdgeInsets.symmetric(vertical: 4), margin: const EdgeInsets.symmetric(vertical: 4),
color: color: Theme.of(
Theme.of(
context, context,
).colorScheme.surfaceContainerLowest, ).colorScheme.surfaceContainerLowest,
child: InkWell( child: InkWell(
@@ -314,8 +316,7 @@ class PostReactionSheet extends StatelessWidget {
String title, String title,
int attitude, int attitude,
) { ) {
final allReactions = final allReactions = kReactionTemplates.entries
kReactionTemplates.entries
.where((entry) => entry.value.attitude == attitude) .where((entry) => entry.value.attitude == attitude)
.map((entry) => entry.key) .map((entry) => entry.key)
.toList(); .toList();
@@ -384,8 +385,7 @@ class PostReactionSheet extends StatelessWidget {
Navigator.pop(context); Navigator.pop(context);
}, },
child: Container( child: Container(
decoration: decoration: hasImage
hasImage
? BoxDecoration( ? BoxDecoration(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
image: DecorationImage( image: DecorationImage(
@@ -393,8 +393,7 @@ class PostReactionSheet extends StatelessWidget {
'assets/images/stickers/$symbol.png', 'assets/images/stickers/$symbol.png',
), ),
fit: BoxFit.cover, fit: BoxFit.cover,
colorFilter: colorFilter: (reactionsMade[symbol] ?? false)
(reactionsMade[symbol] ?? false)
? ColorFilter.mode( ? ColorFilter.mode(
Theme.of(context) Theme.of(context)
.colorScheme .colorScheme
@@ -428,8 +427,7 @@ class PostReactionSheet extends StatelessWidget {
), ),
), ),
Column( Column(
mainAxisAlignment: mainAxisAlignment: hasImage
hasImage
? MainAxisAlignment.end ? MainAxisAlignment.end
: MainAxisAlignment.center, : MainAxisAlignment.center,
children: [ children: [
@@ -439,8 +437,7 @@ class PostReactionSheet extends StatelessWidget {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
color: hasImage ? Colors.white : null, color: hasImage ? Colors.white : null,
shadows: shadows: hasImage
hasImage
? [ ? [
const Shadow( const Shadow(
blurRadius: 4, blurRadius: 4,
@@ -518,12 +515,18 @@ class ReactionDetailsPopup extends HookConsumerWidget {
itemBuilder: (context, index, reaction) { itemBuilder: (context, index, reaction) {
return ListTile( return ListTile(
leading: AccountPfcGestureDetector( leading: AccountPfcGestureDetector(
uname: reaction.account?.name ?? 'unknown', uname: reaction.account?.name,
child: ProfilePictureWidget( child: reaction.actor != null
? ActorPictureWidget(actor: reaction.actor!)
: ProfilePictureWidget(
file: reaction.account?.profile.picture, file: reaction.account?.profile.picture,
), ),
), ),
title: Text(reaction.account?.nick ?? 'unknown'.tr()), title: Text(
reaction.actor?.displayName ??
reaction.account?.nick ??
'unknown'.tr(),
),
subtitle: Text( subtitle: Text(
'${reaction.createdAt.formatRelative(context)} · ${reaction.createdAt.formatSystem()}', '${reaction.createdAt.formatRelative(context)} · ${reaction.createdAt.formatSystem()}',
), ),
@@ -626,19 +629,22 @@ class CustomReactionForm extends HookConsumerWidget {
padding, padding,
screenSize.width - popoverWidth - padding, screenSize.width - popoverWidth - padding,
); );
final horizontalOffset = ((screenSize.width - popoverWidth) / final horizontalOffset =
2) ((screenSize.width - popoverWidth) / 2).clamp(
.clamp(padding, maxHorizontalOffset); padding,
maxHorizontalOffset,
);
// Calculate safe vertical position (bottom-aligned, but within bounds) // Calculate safe vertical position (bottom-aligned, but within bounds)
final maxVerticalOffset = math.max( final maxVerticalOffset = math.max(
padding, padding,
screenSize.height - popoverHeight - padding, screenSize.height - popoverHeight - padding,
); );
final verticalOffset = (screenSize.height - final verticalOffset =
popoverHeight - (screenSize.height - popoverHeight - padding).clamp(
padding) padding,
.clamp(padding, maxVerticalOffset); maxVerticalOffset,
);
await showStickerPickerPopover( await showStickerPickerPopover(
context, context,
@@ -714,8 +720,7 @@ Future<void> showReactionDetailsPopup(
await showPopupCard<void>( await showPopupCard<void>(
offset: offset, offset: offset,
context: context, context: context,
builder: builder: (context) => ReactionDetailsPopup(
(context) => ReactionDetailsPopup(
symbol: symbol, symbol: symbol,
postId: postId, postId: postId,
totalCount: totalCount, totalCount: totalCount,