Post reaction detail popover

This commit is contained in:
2025-10-12 22:05:47 +08:00
parent 707143e998
commit 3ae56f3d89
9 changed files with 698 additions and 189 deletions

View File

@@ -4,23 +4,23 @@ part 'heatmap.freezed.dart';
part 'heatmap.g.dart'; part 'heatmap.g.dart';
@freezed @freezed
sealed class SnHeatmap with _$SnPublisherHeatmap { sealed class SnHeatmap with _$SnHeatmap {
const factory SnHeatmap({ const factory SnHeatmap({
required String unit, required String unit,
@JsonKey(name: 'period_start') required DateTime periodStart, @JsonKey(name: 'period_start') required DateTime periodStart,
@JsonKey(name: 'period_end') required DateTime periodEnd, @JsonKey(name: 'period_end') required DateTime periodEnd,
required List<SnHeatmapItem> items, required List<SnHeatmapItem> items,
}) = _SnPublisherHeatmap; }) = _SnHeatmap;
factory SnHeatmap.fromJson(Map<String, dynamic> json) => factory SnHeatmap.fromJson(Map<String, dynamic> json) =>
_$SnPublisherHeatmapFromJson(json); _$SnHeatmapFromJson(json);
} }
@freezed @freezed
sealed class SnHeatmapItem with _$SnPublisherHeatmapItem { sealed class SnHeatmapItem with _$SnHeatmapItem {
const factory SnHeatmapItem({required DateTime date, required int count}) = const factory SnHeatmapItem({required DateTime date, required int count}) =
_SnPublisherHeatmapItem; _SnHeatmapItem;
factory SnHeatmapItem.fromJson(Map<String, dynamic> json) => factory SnHeatmapItem.fromJson(Map<String, dynamic> json) =>
_$SnPublisherHeatmapItemFromJson(json); _$SnHeatmapItemFromJson(json);
} }

View File

@@ -13,16 +13,16 @@ part of 'heatmap.dart';
T _$identity<T>(T value) => value; T _$identity<T>(T value) => value;
/// @nodoc /// @nodoc
mixin _$SnPublisherHeatmap { mixin _$SnHeatmap {
String get unit;@JsonKey(name: 'period_start') DateTime get periodStart;@JsonKey(name: 'period_end') DateTime get periodEnd; List<SnHeatmapItem> get items; String get unit;@JsonKey(name: 'period_start') DateTime get periodStart;@JsonKey(name: 'period_end') DateTime get periodEnd; List<SnHeatmapItem> get items;
/// Create a copy of SnPublisherHeatmap /// Create a copy of SnHeatmap
/// 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)
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
$SnPublisherHeatmapCopyWith<SnHeatmap> get copyWith => _$SnPublisherHeatmapCopyWithImpl<SnHeatmap>(this as SnHeatmap, _$identity); $SnHeatmapCopyWith<SnHeatmap> get copyWith => _$SnHeatmapCopyWithImpl<SnHeatmap>(this as SnHeatmap, _$identity);
/// Serializes this SnPublisherHeatmap to a JSON map. /// Serializes this SnHeatmap to a JSON map.
Map<String, dynamic> toJson(); Map<String, dynamic> toJson();
@@ -37,15 +37,15 @@ int get hashCode => Object.hash(runtimeType,unit,periodStart,periodEnd,const Dee
@override @override
String toString() { String toString() {
return 'SnPublisherHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)'; return 'SnHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)';
} }
} }
/// @nodoc /// @nodoc
abstract mixin class $SnPublisherHeatmapCopyWith<$Res> { abstract mixin class $SnHeatmapCopyWith<$Res> {
factory $SnPublisherHeatmapCopyWith(SnHeatmap value, $Res Function(SnHeatmap) _then) = _$SnPublisherHeatmapCopyWithImpl; factory $SnHeatmapCopyWith(SnHeatmap value, $Res Function(SnHeatmap) _then) = _$SnHeatmapCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items
@@ -56,14 +56,14 @@ $Res call({
} }
/// @nodoc /// @nodoc
class _$SnPublisherHeatmapCopyWithImpl<$Res> class _$SnHeatmapCopyWithImpl<$Res>
implements $SnPublisherHeatmapCopyWith<$Res> { implements $SnHeatmapCopyWith<$Res> {
_$SnPublisherHeatmapCopyWithImpl(this._self, this._then); _$SnHeatmapCopyWithImpl(this._self, this._then);
final SnHeatmap _self; final SnHeatmap _self;
final $Res Function(SnHeatmap) _then; final $Res Function(SnHeatmap) _then;
/// Create a copy of SnPublisherHeatmap /// Create a copy of SnHeatmap
/// 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? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
@@ -79,7 +79,7 @@ as List<SnHeatmapItem>,
/// Adds pattern-matching-related methods to [SnHeatmap]. /// Adds pattern-matching-related methods to [SnHeatmap].
extension SnPublisherHeatmapPatterns on SnHeatmap { extension SnHeatmapPatterns on SnHeatmap {
/// A variant of `map` that fallback to returning `orElse`. /// A variant of `map` that fallback to returning `orElse`.
/// ///
/// It is equivalent to doing: /// It is equivalent to doing:
@@ -92,10 +92,10 @@ extension SnPublisherHeatmapPatterns on SnHeatmap {
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPublisherHeatmap value)? $default,{required TResult orElse(),}){ @optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnHeatmap value)? $default,{required TResult orElse(),}){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap() when $default != null: case _SnHeatmap() when $default != null:
return $default(_that);case _: return $default(_that);case _:
return orElse(); return orElse();
@@ -114,10 +114,10 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPublisherHeatmap value) $default,){ @optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnHeatmap value) $default,){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap(): case _SnHeatmap():
return $default(_that);} return $default(_that);}
} }
/// A variant of `map` that fallback to returning `null`. /// A variant of `map` that fallback to returning `null`.
@@ -132,10 +132,10 @@ return $default(_that);}
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPublisherHeatmap value)? $default,){ @optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnHeatmap value)? $default,){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap() when $default != null: case _SnHeatmap() when $default != null:
return $default(_that);case _: return $default(_that);case _:
return null; return null;
@@ -155,7 +155,7 @@ return $default(_that);case _:
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap() when $default != null: case _SnHeatmap() when $default != null:
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _: return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _:
return orElse(); return orElse();
@@ -176,7 +176,7 @@ return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap(): case _SnHeatmap():
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);} return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);}
} }
/// A variant of `when` that fallback to returning `null` /// A variant of `when` that fallback to returning `null`
@@ -193,7 +193,7 @@ return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);}
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String unit, @JsonKey(name: 'period_start') DateTime periodStart, @JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmap() when $default != null: case _SnHeatmap() when $default != null:
return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _: return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _:
return null; return null;
@@ -205,9 +205,9 @@ return $default(_that.unit,_that.periodStart,_that.periodEnd,_that.items);case _
/// @nodoc /// @nodoc
@JsonSerializable() @JsonSerializable()
class _SnPublisherHeatmap implements SnHeatmap { class _SnHeatmap implements SnHeatmap {
const _SnPublisherHeatmap({required this.unit, @JsonKey(name: 'period_start') required this.periodStart, @JsonKey(name: 'period_end') required this.periodEnd, required final List<SnHeatmapItem> items}): _items = items; const _SnHeatmap({required this.unit, @JsonKey(name: 'period_start') required this.periodStart, @JsonKey(name: 'period_end') required this.periodEnd, required final List<SnHeatmapItem> items}): _items = items;
factory _SnPublisherHeatmap.fromJson(Map<String, dynamic> json) => _$SnPublisherHeatmapFromJson(json); factory _SnHeatmap.fromJson(Map<String, dynamic> json) => _$SnHeatmapFromJson(json);
@override final String unit; @override final String unit;
@override@JsonKey(name: 'period_start') final DateTime periodStart; @override@JsonKey(name: 'period_start') final DateTime periodStart;
@@ -220,20 +220,20 @@ class _SnPublisherHeatmap implements SnHeatmap {
} }
/// Create a copy of SnPublisherHeatmap /// Create a copy of SnHeatmap
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false) @override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$SnPublisherHeatmapCopyWith<_SnPublisherHeatmap> get copyWith => __$SnPublisherHeatmapCopyWithImpl<_SnPublisherHeatmap>(this, _$identity); _$SnHeatmapCopyWith<_SnHeatmap> get copyWith => __$SnHeatmapCopyWithImpl<_SnHeatmap>(this, _$identity);
@override @override
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return _$SnPublisherHeatmapToJson(this, ); return _$SnHeatmapToJson(this, );
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPublisherHeatmap&&(identical(other.unit, unit) || other.unit == unit)&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&const DeepCollectionEquality().equals(other._items, _items)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnHeatmap&&(identical(other.unit, unit) || other.unit == unit)&&(identical(other.periodStart, periodStart) || other.periodStart == periodStart)&&(identical(other.periodEnd, periodEnd) || other.periodEnd == periodEnd)&&const DeepCollectionEquality().equals(other._items, _items));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@@ -242,15 +242,15 @@ int get hashCode => Object.hash(runtimeType,unit,periodStart,periodEnd,const Dee
@override @override
String toString() { String toString() {
return 'SnPublisherHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)'; return 'SnHeatmap(unit: $unit, periodStart: $periodStart, periodEnd: $periodEnd, items: $items)';
} }
} }
/// @nodoc /// @nodoc
abstract mixin class _$SnPublisherHeatmapCopyWith<$Res> implements $SnPublisherHeatmapCopyWith<$Res> { abstract mixin class _$SnHeatmapCopyWith<$Res> implements $SnHeatmapCopyWith<$Res> {
factory _$SnPublisherHeatmapCopyWith(_SnPublisherHeatmap value, $Res Function(_SnPublisherHeatmap) _then) = __$SnPublisherHeatmapCopyWithImpl; factory _$SnHeatmapCopyWith(_SnHeatmap value, $Res Function(_SnHeatmap) _then) = __$SnHeatmapCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items String unit,@JsonKey(name: 'period_start') DateTime periodStart,@JsonKey(name: 'period_end') DateTime periodEnd, List<SnHeatmapItem> items
@@ -261,17 +261,17 @@ $Res call({
} }
/// @nodoc /// @nodoc
class __$SnPublisherHeatmapCopyWithImpl<$Res> class __$SnHeatmapCopyWithImpl<$Res>
implements _$SnPublisherHeatmapCopyWith<$Res> { implements _$SnHeatmapCopyWith<$Res> {
__$SnPublisherHeatmapCopyWithImpl(this._self, this._then); __$SnHeatmapCopyWithImpl(this._self, this._then);
final _SnPublisherHeatmap _self; final _SnHeatmap _self;
final $Res Function(_SnPublisherHeatmap) _then; final $Res Function(_SnHeatmap) _then;
/// Create a copy of SnPublisherHeatmap /// Create a copy of SnHeatmap
/// 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? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? unit = null,Object? periodStart = null,Object? periodEnd = null,Object? items = null,}) {
return _then(_SnPublisherHeatmap( return _then(_SnHeatmap(
unit: null == unit ? _self.unit : unit // ignore: cast_nullable_to_non_nullable unit: null == unit ? _self.unit : unit // ignore: cast_nullable_to_non_nullable
as String,periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable as String,periodStart: null == periodStart ? _self.periodStart : periodStart // ignore: cast_nullable_to_non_nullable
as DateTime,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable as DateTime,periodEnd: null == periodEnd ? _self.periodEnd : periodEnd // ignore: cast_nullable_to_non_nullable
@@ -285,16 +285,16 @@ as List<SnHeatmapItem>,
/// @nodoc /// @nodoc
mixin _$SnPublisherHeatmapItem { mixin _$SnHeatmapItem {
DateTime get date; int get count; DateTime get date; int get count;
/// Create a copy of SnPublisherHeatmapItem /// Create a copy of SnHeatmapItem
/// 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)
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
$SnPublisherHeatmapItemCopyWith<SnHeatmapItem> get copyWith => _$SnPublisherHeatmapItemCopyWithImpl<SnHeatmapItem>(this as SnHeatmapItem, _$identity); $SnHeatmapItemCopyWith<SnHeatmapItem> get copyWith => _$SnHeatmapItemCopyWithImpl<SnHeatmapItem>(this as SnHeatmapItem, _$identity);
/// Serializes this SnPublisherHeatmapItem to a JSON map. /// Serializes this SnHeatmapItem to a JSON map.
Map<String, dynamic> toJson(); Map<String, dynamic> toJson();
@@ -309,15 +309,15 @@ int get hashCode => Object.hash(runtimeType,date,count);
@override @override
String toString() { String toString() {
return 'SnPublisherHeatmapItem(date: $date, count: $count)'; return 'SnHeatmapItem(date: $date, count: $count)';
} }
} }
/// @nodoc /// @nodoc
abstract mixin class $SnPublisherHeatmapItemCopyWith<$Res> { abstract mixin class $SnHeatmapItemCopyWith<$Res> {
factory $SnPublisherHeatmapItemCopyWith(SnHeatmapItem value, $Res Function(SnHeatmapItem) _then) = _$SnPublisherHeatmapItemCopyWithImpl; factory $SnHeatmapItemCopyWith(SnHeatmapItem value, $Res Function(SnHeatmapItem) _then) = _$SnHeatmapItemCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
DateTime date, int count DateTime date, int count
@@ -328,14 +328,14 @@ $Res call({
} }
/// @nodoc /// @nodoc
class _$SnPublisherHeatmapItemCopyWithImpl<$Res> class _$SnHeatmapItemCopyWithImpl<$Res>
implements $SnPublisherHeatmapItemCopyWith<$Res> { implements $SnHeatmapItemCopyWith<$Res> {
_$SnPublisherHeatmapItemCopyWithImpl(this._self, this._then); _$SnHeatmapItemCopyWithImpl(this._self, this._then);
final SnHeatmapItem _self; final SnHeatmapItem _self;
final $Res Function(SnHeatmapItem) _then; final $Res Function(SnHeatmapItem) _then;
/// Create a copy of SnPublisherHeatmapItem /// Create a copy of SnHeatmapItem
/// 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? date = null,Object? count = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? date = null,Object? count = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
@@ -349,7 +349,7 @@ as int,
/// Adds pattern-matching-related methods to [SnHeatmapItem]. /// Adds pattern-matching-related methods to [SnHeatmapItem].
extension SnPublisherHeatmapItemPatterns on SnHeatmapItem { extension SnHeatmapItemPatterns on SnHeatmapItem {
/// A variant of `map` that fallback to returning `orElse`. /// A variant of `map` that fallback to returning `orElse`.
/// ///
/// It is equivalent to doing: /// It is equivalent to doing:
@@ -362,10 +362,10 @@ extension SnPublisherHeatmapItemPatterns on SnHeatmapItem {
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnPublisherHeatmapItem value)? $default,{required TResult orElse(),}){ @optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnHeatmapItem value)? $default,{required TResult orElse(),}){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem() when $default != null: case _SnHeatmapItem() when $default != null:
return $default(_that);case _: return $default(_that);case _:
return orElse(); return orElse();
@@ -384,10 +384,10 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnPublisherHeatmapItem value) $default,){ @optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnHeatmapItem value) $default,){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem(): case _SnHeatmapItem():
return $default(_that);} return $default(_that);}
} }
/// A variant of `map` that fallback to returning `null`. /// A variant of `map` that fallback to returning `null`.
@@ -402,10 +402,10 @@ return $default(_that);}
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnPublisherHeatmapItem value)? $default,){ @optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnHeatmapItem value)? $default,){
final _that = this; final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem() when $default != null: case _SnHeatmapItem() when $default != null:
return $default(_that);case _: return $default(_that);case _:
return null; return null;
@@ -425,7 +425,7 @@ return $default(_that);case _:
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime date, int count)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( DateTime date, int count)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem() when $default != null: case _SnHeatmapItem() when $default != null:
return $default(_that.date,_that.count);case _: return $default(_that.date,_that.count);case _:
return orElse(); return orElse();
@@ -446,7 +446,7 @@ return $default(_that.date,_that.count);case _:
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime date, int count) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( DateTime date, int count) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem(): case _SnHeatmapItem():
return $default(_that.date,_that.count);} return $default(_that.date,_that.count);}
} }
/// A variant of `when` that fallback to returning `null` /// A variant of `when` that fallback to returning `null`
@@ -463,7 +463,7 @@ return $default(_that.date,_that.count);}
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime date, int count)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( DateTime date, int count)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _SnPublisherHeatmapItem() when $default != null: case _SnHeatmapItem() when $default != null:
return $default(_that.date,_that.count);case _: return $default(_that.date,_that.count);case _:
return null; return null;
@@ -475,27 +475,27 @@ return $default(_that.date,_that.count);case _:
/// @nodoc /// @nodoc
@JsonSerializable() @JsonSerializable()
class _SnPublisherHeatmapItem implements SnHeatmapItem { class _SnHeatmapItem implements SnHeatmapItem {
const _SnPublisherHeatmapItem({required this.date, required this.count}); const _SnHeatmapItem({required this.date, required this.count});
factory _SnPublisherHeatmapItem.fromJson(Map<String, dynamic> json) => _$SnPublisherHeatmapItemFromJson(json); factory _SnHeatmapItem.fromJson(Map<String, dynamic> json) => _$SnHeatmapItemFromJson(json);
@override final DateTime date; @override final DateTime date;
@override final int count; @override final int count;
/// Create a copy of SnPublisherHeatmapItem /// Create a copy of SnHeatmapItem
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false) @override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$SnPublisherHeatmapItemCopyWith<_SnPublisherHeatmapItem> get copyWith => __$SnPublisherHeatmapItemCopyWithImpl<_SnPublisherHeatmapItem>(this, _$identity); _$SnHeatmapItemCopyWith<_SnHeatmapItem> get copyWith => __$SnHeatmapItemCopyWithImpl<_SnHeatmapItem>(this, _$identity);
@override @override
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return _$SnPublisherHeatmapItemToJson(this, ); return _$SnHeatmapItemToJson(this, );
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPublisherHeatmapItem&&(identical(other.date, date) || other.date == date)&&(identical(other.count, count) || other.count == count)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnHeatmapItem&&(identical(other.date, date) || other.date == date)&&(identical(other.count, count) || other.count == count));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@@ -504,15 +504,15 @@ int get hashCode => Object.hash(runtimeType,date,count);
@override @override
String toString() { String toString() {
return 'SnPublisherHeatmapItem(date: $date, count: $count)'; return 'SnHeatmapItem(date: $date, count: $count)';
} }
} }
/// @nodoc /// @nodoc
abstract mixin class _$SnPublisherHeatmapItemCopyWith<$Res> implements $SnPublisherHeatmapItemCopyWith<$Res> { abstract mixin class _$SnHeatmapItemCopyWith<$Res> implements $SnHeatmapItemCopyWith<$Res> {
factory _$SnPublisherHeatmapItemCopyWith(_SnPublisherHeatmapItem value, $Res Function(_SnPublisherHeatmapItem) _then) = __$SnPublisherHeatmapItemCopyWithImpl; factory _$SnHeatmapItemCopyWith(_SnHeatmapItem value, $Res Function(_SnHeatmapItem) _then) = __$SnHeatmapItemCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
DateTime date, int count DateTime date, int count
@@ -523,17 +523,17 @@ $Res call({
} }
/// @nodoc /// @nodoc
class __$SnPublisherHeatmapItemCopyWithImpl<$Res> class __$SnHeatmapItemCopyWithImpl<$Res>
implements _$SnPublisherHeatmapItemCopyWith<$Res> { implements _$SnHeatmapItemCopyWith<$Res> {
__$SnPublisherHeatmapItemCopyWithImpl(this._self, this._then); __$SnHeatmapItemCopyWithImpl(this._self, this._then);
final _SnPublisherHeatmapItem _self; final _SnHeatmapItem _self;
final $Res Function(_SnPublisherHeatmapItem) _then; final $Res Function(_SnHeatmapItem) _then;
/// Create a copy of SnPublisherHeatmapItem /// Create a copy of SnHeatmapItem
/// 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? date = null,Object? count = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? date = null,Object? count = null,}) {
return _then(_SnPublisherHeatmapItem( return _then(_SnHeatmapItem(
date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
as DateTime,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable as DateTime,count: null == count ? _self.count : count // ignore: cast_nullable_to_non_nullable
as int, as int,

View File

@@ -6,8 +6,7 @@ part of 'heatmap.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
_SnPublisherHeatmap _$SnPublisherHeatmapFromJson(Map<String, dynamic> json) => _SnHeatmap _$SnHeatmapFromJson(Map<String, dynamic> json) => _SnHeatmap(
_SnPublisherHeatmap(
unit: json['unit'] as String, unit: json['unit'] as String,
periodStart: DateTime.parse(json['period_start'] as String), periodStart: DateTime.parse(json['period_start'] as String),
periodEnd: DateTime.parse(json['period_end'] as String), periodEnd: DateTime.parse(json['period_end'] as String),
@@ -15,9 +14,9 @@ _SnPublisherHeatmap _$SnPublisherHeatmapFromJson(Map<String, dynamic> json) =>
(json['items'] as List<dynamic>) (json['items'] as List<dynamic>)
.map((e) => SnHeatmapItem.fromJson(e as Map<String, dynamic>)) .map((e) => SnHeatmapItem.fromJson(e as Map<String, dynamic>))
.toList(), .toList(),
); );
Map<String, dynamic> _$SnPublisherHeatmapToJson(_SnPublisherHeatmap instance) => Map<String, dynamic> _$SnHeatmapToJson(_SnHeatmap instance) =>
<String, dynamic>{ <String, dynamic>{
'unit': instance.unit, 'unit': instance.unit,
'period_start': instance.periodStart.toIso8601String(), 'period_start': instance.periodStart.toIso8601String(),
@@ -25,16 +24,14 @@ Map<String, dynamic> _$SnPublisherHeatmapToJson(_SnPublisherHeatmap instance) =>
'items': instance.items.map((e) => e.toJson()).toList(), 'items': instance.items.map((e) => e.toJson()).toList(),
}; };
_SnPublisherHeatmapItem _$SnPublisherHeatmapItemFromJson( _SnHeatmapItem _$SnHeatmapItemFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> json, _SnHeatmapItem(
) => _SnPublisherHeatmapItem(
date: DateTime.parse(json['date'] as String), date: DateTime.parse(json['date'] as String),
count: (json['count'] as num).toInt(), count: (json['count'] as num).toInt(),
); );
Map<String, dynamic> _$SnPublisherHeatmapItemToJson( Map<String, dynamic> _$SnHeatmapItemToJson(_SnHeatmapItem instance) =>
_SnPublisherHeatmapItem instance, <String, dynamic>{
) => <String, dynamic>{
'date': instance.date.toIso8601String(), 'date': instance.date.toIso8601String(),
'count': instance.count, 'count': instance.count,
}; };

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:island/models/account.dart';
import 'package:island/models/file.dart'; import 'package:island/models/file.dart';
import 'package:island/models/post_category.dart'; import 'package:island/models/post_category.dart';
import 'package:island/models/post_tag.dart'; import 'package:island/models/post_tag.dart';
@@ -142,3 +143,21 @@ sealed class SnPostAward with _$SnPostAward {
factory SnPostAward.fromJson(Map<String, dynamic> json) => factory SnPostAward.fromJson(Map<String, dynamic> json) =>
_$SnPostAwardFromJson(json); _$SnPostAwardFromJson(json);
} }
@freezed
sealed class SnPostReaction with _$SnPostReaction {
const factory SnPostReaction({
required String id,
required String symbol,
required int attitude,
required String postId,
required String accountId,
required DateTime createdAt,
required DateTime updatedAt,
@Default(null) SnAccount? account,
DateTime? deletedAt,
}) = _SnPostReaction;
factory SnPostReaction.fromJson(Map<String, dynamic> json) =>
_$SnPostReactionFromJson(json);
}

View File

@@ -1900,4 +1900,309 @@ as DateTime?,
} }
/// @nodoc
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;
/// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SnPostReactionCopyWith<SnPostReaction> get copyWith => _$SnPostReactionCopyWithImpl<SnPostReaction>(this as SnPostReaction, _$identity);
/// Serializes this SnPostReaction to a JSON map.
Map<String, dynamic> toJson();
@override
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));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt);
@override
String toString() {
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class $SnPostReactionCopyWith<$Res> {
factory $SnPostReactionCopyWith(SnPostReaction value, $Res Function(SnPostReaction) _then) = _$SnPostReactionCopyWithImpl;
@useResult
$Res call({
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt
});
$SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
class _$SnPostReactionCopyWithImpl<$Res>
implements $SnPostReactionCopyWith<$Res> {
_$SnPostReactionCopyWithImpl(this._self, this._then);
final SnPostReaction _self;
final $Res Function(SnPostReaction) _then;
/// Create a copy of SnPostReaction
/// 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,}) {
return _then(_self.copyWith(
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,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 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 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 SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// 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 {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
/// Adds pattern-matching-related methods to [SnPostReaction].
extension SnPostReactionPatterns on SnPostReaction {
/// 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 extends Object?>(TResult Function( _SnPostReaction value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _SnPostReaction() 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 extends Object?>(TResult Function( _SnPostReaction value) $default,){
final _that = this;
switch (_that) {
case _SnPostReaction():
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 extends Object?>(TResult? Function( _SnPostReaction value)? $default,){
final _that = this;
switch (_that) {
case _SnPostReaction() 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 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;
switch (_that) {
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 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 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;
switch (_that) {
case _SnPostReaction():
return $default(_that.id,_that.symbol,_that.attitude,_that.postId,_that.accountId,_that.createdAt,_that.updatedAt,_that.account,_that.deletedAt);}
}
/// 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 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;
switch (_that) {
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 null;
}
}
}
/// @nodoc
@JsonSerializable()
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});
factory _SnPostReaction.fromJson(Map<String, dynamic> json) => _$SnPostReactionFromJson(json);
@override final String id;
@override final String symbol;
@override final int attitude;
@override final String postId;
@override final String accountId;
@override final DateTime createdAt;
@override final DateTime updatedAt;
@override@JsonKey() final SnAccount? account;
@override final DateTime? deletedAt;
/// Create a copy of SnPostReaction
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$SnPostReactionCopyWith<_SnPostReaction> get copyWith => __$SnPostReactionCopyWithImpl<_SnPostReaction>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$SnPostReactionToJson(this, );
}
@override
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));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,id,symbol,attitude,postId,accountId,createdAt,updatedAt,account,deletedAt);
@override
String toString() {
return 'SnPostReaction(id: $id, symbol: $symbol, attitude: $attitude, postId: $postId, accountId: $accountId, createdAt: $createdAt, updatedAt: $updatedAt, account: $account, deletedAt: $deletedAt)';
}
}
/// @nodoc
abstract mixin class _$SnPostReactionCopyWith<$Res> implements $SnPostReactionCopyWith<$Res> {
factory _$SnPostReactionCopyWith(_SnPostReaction value, $Res Function(_SnPostReaction) _then) = __$SnPostReactionCopyWithImpl;
@override @useResult
$Res call({
String id, String symbol, int attitude, String postId, String accountId, DateTime createdAt, DateTime updatedAt, SnAccount? account, DateTime? deletedAt
});
@override $SnAccountCopyWith<$Res>? get account;
}
/// @nodoc
class __$SnPostReactionCopyWithImpl<$Res>
implements _$SnPostReactionCopyWith<$Res> {
__$SnPostReactionCopyWithImpl(this._self, this._then);
final _SnPostReaction _self;
final $Res Function(_SnPostReaction) _then;
/// Create a copy of SnPostReaction
/// 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,}) {
return _then(_SnPostReaction(
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,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 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 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 SnAccount?,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
as DateTime?,
));
}
/// 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 {
if (_self.account == null) {
return null;
}
return $SnAccountCopyWith<$Res>(_self.account!, (value) {
return _then(_self.copyWith(account: value));
});
}
}
// dart format on // dart format on

View File

@@ -230,3 +230,35 @@ Map<String, dynamic> _$SnPostAwardToJson(_SnPostAward instance) =>
'updated_at': instance.updatedAt?.toIso8601String(), 'updated_at': instance.updatedAt?.toIso8601String(),
'deleted_at': instance.deletedAt?.toIso8601String(), 'deleted_at': instance.deletedAt?.toIso8601String(),
}; };
_SnPostReaction _$SnPostReactionFromJson(Map<String, dynamic> json) =>
_SnPostReaction(
id: json['id'] as String,
symbol: json['symbol'] as String,
attitude: (json['attitude'] as num).toInt(),
postId: json['post_id'] as String,
accountId: json['account_id'] as String,
createdAt: DateTime.parse(json['created_at'] as String),
updatedAt: DateTime.parse(json['updated_at'] as String),
account:
json['account'] == null
? null
: SnAccount.fromJson(json['account'] as Map<String, dynamic>),
deletedAt:
json['deleted_at'] == null
? null
: DateTime.parse(json['deleted_at'] as String),
);
Map<String, dynamic> _$SnPostReactionToJson(_SnPostReaction instance) =>
<String, dynamic>{
'id': instance.id,
'symbol': instance.symbol,
'attitude': instance.attitude,
'post_id': instance.postId,
'account_id': instance.accountId,
'created_at': instance.createdAt.toIso8601String(),
'updated_at': instance.updatedAt.toIso8601String(),
'account': instance.account?.toJson(),
'deleted_at': instance.deletedAt?.toIso8601String(),
};

View File

@@ -149,7 +149,7 @@ class _PublisherStatsProviderElement
String? get uname => (origin as PublisherStatsProvider).uname; String? get uname => (origin as PublisherStatsProvider).uname;
} }
String _$publisherHeatmapHash() => r'780dfb05b8610a37cfcd937fd04cf5bbe9b298c9'; String _$publisherHeatmapHash() => r'5f70c55e14629ec8628445a317888e02fccd9af2';
/// See also [publisherHeatmap]. /// See also [publisherHeatmap].
@ProviderFor(publisherHeatmap) @ProviderFor(publisherHeatmap)

View File

@@ -579,6 +579,7 @@ class PostItem extends HookConsumerWidget {
onReact: (symbol, attitude) { onReact: (symbol, attitude) {
reactPost(symbol, attitude); reactPost(symbol, attitude);
}, },
postId: item.id,
); );
}, },
); );
@@ -686,6 +687,7 @@ class PostReactionList extends HookConsumerWidget {
onReact: (symbol, attitude) { onReact: (symbol, attitude) {
reactPost(symbol, attitude); reactPost(symbol, attitude);
}, },
postId: parentId,
); );
}, },
); );

View File

@@ -1,7 +1,15 @@
import 'dart:math' as math;
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_popup_card/flutter_popup_card.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/post.dart'; import 'package:island/models/post.dart';
import 'package:island/pods/network.dart';
import 'package:island/services/time.dart';
import 'package:island/widgets/content/cloud_files.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
@@ -39,10 +47,12 @@ class PostReactionSheet extends StatelessWidget {
final Map<String, int> reactionsCount; final Map<String, int> reactionsCount;
final Map<String, bool> reactionsMade; final Map<String, bool> reactionsMade;
final Function(String symbol, int attitude) onReact; final Function(String symbol, int attitude) onReact;
final String postId;
const PostReactionSheet({ const PostReactionSheet({
required this.reactionsCount, required this.reactionsCount,
required this.reactionsMade, required this.reactionsMade,
required this.onReact, required this.onReact,
required this.postId,
}); });
@override @override
@@ -144,7 +154,18 @@ class PostReactionSheet extends StatelessWidget {
final symbol = allReactions[index]; final symbol = allReactions[index];
final count = reactionsCount[symbol] ?? 0; final count = reactionsCount[symbol] ?? 0;
final hasImage = _getReactionImageAvailable(symbol); final hasImage = _getReactionImageAvailable(symbol);
return Badge( return GestureDetector(
onLongPressStart: (details) {
if (count > 0) {
showReactionDetailsPopup(
context,
symbol,
details.localPosition,
postId,
);
}
},
child: Badge(
label: Text('x$count'), label: Text('x$count'),
isLabelVisible: count > 0, isLabelVisible: count > 0,
textColor: Theme.of(context).colorScheme.onPrimary, textColor: Theme.of(context).colorScheme.onPrimary,
@@ -235,6 +256,7 @@ class PostReactionSheet extends StatelessWidget {
), ),
), ),
), ),
),
); );
}, },
), ),
@@ -243,3 +265,135 @@ class PostReactionSheet extends StatelessWidget {
); );
} }
} }
class ReactionDetailsPopup extends HookConsumerWidget {
final String symbol;
final String postId;
const ReactionDetailsPopup({
super.key,
required this.symbol,
required this.postId,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final reactions = useState<List<SnPostReaction>>([]);
final isLoading = useState(false);
final hasMore = useState(true);
final offset = useState(0);
Future<void> loadReactions() async {
if (isLoading.value || !hasMore.value) return;
isLoading.value = true;
try {
final client = ref.watch(apiClientProvider);
final response = await client.get(
'/sphere/posts/${postId}/reactions',
queryParameters: {
'symbol': symbol,
'offset': offset.value,
'take': 20,
},
);
final newReactions =
(response.data as List)
.map((json) => SnPostReaction.fromJson(json))
.toList();
if (newReactions.length < 20) {
hasMore.value = false;
}
reactions.value = [...reactions.value, ...newReactions];
offset.value += newReactions.length;
} catch (err) {
// Handle error
} finally {
isLoading.value = false;
}
}
useEffect(() {
loadReactions();
return null;
}, []);
final width = math.min(MediaQuery.of(context).size.width * 0.8, 480.0);
return PopupCard(
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
child: SizedBox(
width: width,
height: 400,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
_buildReactionIcon(symbol, 24),
const Gap(8),
Text(
ReactInfo.getTranslationKey(symbol),
style: Theme.of(context).textTheme.titleMedium,
).tr(),
const Spacer(),
Text('${reactions.value.length} reactions'.tr()),
],
),
),
const Divider(height: 1),
Expanded(
child: ListView.builder(
itemCount: reactions.value.length + (hasMore.value ? 1 : 0),
itemBuilder: (context, index) {
if (index == reactions.value.length) {
if (isLoading.value) {
return const Center(
child: Padding(
padding: EdgeInsets.all(16),
child: CircularProgressIndicator(),
),
);
} else {
loadReactions();
return const SizedBox.shrink();
}
}
final reaction = reactions.value[index];
return ListTile(
leading: ProfilePictureWidget(
file: reaction.account?.profile.picture,
),
title: Text(reaction.account?.nick ?? 'unknown'.tr()),
subtitle: Text(
'${reaction.createdAt.formatRelative(context)} · ${reaction.createdAt.formatSystem()}',
),
);
},
),
),
],
),
),
);
}
}
Future<void> showReactionDetailsPopup(
BuildContext context,
String symbol,
Offset offset,
String postId,
) async {
await showPopupCard<void>(
offset: offset,
context: context,
builder: (context) => ReactionDetailsPopup(symbol: symbol, postId: postId),
alignment: Alignment.center,
dimBackground: true,
);
}