✨ Refined presense activity
This commit is contained in:
		@@ -1302,5 +1302,9 @@
 | 
				
			|||||||
    "aiThought": "AI Thought",
 | 
					    "aiThought": "AI Thought",
 | 
				
			||||||
    "aiThoughtTitle": "Let sn-chan think",
 | 
					    "aiThoughtTitle": "Let sn-chan think",
 | 
				
			||||||
    "postReferenceUnavailable": "Referenced post is unavailable",
 | 
					    "postReferenceUnavailable": "Referenced post is unavailable",
 | 
				
			||||||
    "fabLocation": "FAB Location"
 | 
					    "fabLocation": "FAB Location",
 | 
				
			||||||
 | 
					    "activities": "Activities",
 | 
				
			||||||
 | 
					    "presenceTypeGaming": "Playing",
 | 
				
			||||||
 | 
					    "presenceTypeMusic": "Listening to Music",
 | 
				
			||||||
 | 
					    "presenceTypeWorkout": "Working out"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,8 +19,8 @@ sealed class SnNotableDay with _$SnNotableDay {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
sealed class SnActivity with _$SnActivity {
 | 
					sealed class SnTimelineEvent with _$SnTimelineEvent {
 | 
				
			||||||
  const factory SnActivity({
 | 
					  const factory SnTimelineEvent({
 | 
				
			||||||
    required String id,
 | 
					    required String id,
 | 
				
			||||||
    required String type,
 | 
					    required String type,
 | 
				
			||||||
    required String resourceIdentifier,
 | 
					    required String resourceIdentifier,
 | 
				
			||||||
@@ -28,10 +28,10 @@ sealed class SnActivity with _$SnActivity {
 | 
				
			|||||||
    required DateTime createdAt,
 | 
					    required DateTime createdAt,
 | 
				
			||||||
    required DateTime updatedAt,
 | 
					    required DateTime updatedAt,
 | 
				
			||||||
    required DateTime? deletedAt,
 | 
					    required DateTime? deletedAt,
 | 
				
			||||||
  }) = _SnActivity;
 | 
					  }) = _SnTimelineEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  factory SnActivity.fromJson(Map<String, dynamic> json) =>
 | 
					  factory SnTimelineEvent.fromJson(Map<String, dynamic> json) =>
 | 
				
			||||||
      _$SnActivityFromJson(json);
 | 
					      _$SnTimelineEventFromJson(json);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@freezed
 | 
					@freezed
 | 
				
			||||||
@@ -79,7 +79,7 @@ sealed class SnEventCalendarEntry with _$SnEventCalendarEntry {
 | 
				
			|||||||
sealed class SnPresenceActivity with _$SnPresenceActivity {
 | 
					sealed class SnPresenceActivity with _$SnPresenceActivity {
 | 
				
			||||||
  const factory SnPresenceActivity({
 | 
					  const factory SnPresenceActivity({
 | 
				
			||||||
    required String id,
 | 
					    required String id,
 | 
				
			||||||
    required String type,
 | 
					    required int type,
 | 
				
			||||||
    required String? manualId,
 | 
					    required String? manualId,
 | 
				
			||||||
    required String? title,
 | 
					    required String? title,
 | 
				
			||||||
    required String? subtitle,
 | 
					    required String? subtitle,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -288,22 +288,22 @@ as List<int>,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
mixin _$SnActivity {
 | 
					mixin _$SnTimelineEvent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 String get id; String get type; String get resourceIdentifier; dynamic get data; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
					 String get id; String get type; String get resourceIdentifier; dynamic get data; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
				
			||||||
/// Create a copy of SnActivity
 | 
					/// Create a copy of SnTimelineEvent
 | 
				
			||||||
/// 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')
 | 
				
			||||||
$SnActivityCopyWith<SnActivity> get copyWith => _$SnActivityCopyWithImpl<SnActivity>(this as SnActivity, _$identity);
 | 
					$SnTimelineEventCopyWith<SnTimelineEvent> get copyWith => _$SnTimelineEventCopyWithImpl<SnTimelineEvent>(this as SnTimelineEvent, _$identity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Serializes this SnActivity to a JSON map.
 | 
					  /// Serializes this SnTimelineEvent to a JSON map.
 | 
				
			||||||
  Map<String, dynamic> toJson();
 | 
					  Map<String, dynamic> toJson();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override
 | 
					@override
 | 
				
			||||||
bool operator ==(Object other) {
 | 
					bool operator ==(Object other) {
 | 
				
			||||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is SnActivity&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
					  return identical(this, other) || (other.runtimeType == runtimeType&&other is SnTimelineEvent&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@JsonKey(includeFromJson: false, includeToJson: false)
 | 
					@JsonKey(includeFromJson: false, includeToJson: false)
 | 
				
			||||||
@@ -312,15 +312,15 @@ int get hashCode => Object.hash(runtimeType,id,type,resourceIdentifier,const Dee
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@override
 | 
					@override
 | 
				
			||||||
String toString() {
 | 
					String toString() {
 | 
				
			||||||
  return 'SnActivity(id: $id, type: $type, resourceIdentifier: $resourceIdentifier, data: $data, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
 | 
					  return 'SnTimelineEvent(id: $id, type: $type, resourceIdentifier: $resourceIdentifier, data: $data, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
abstract mixin class $SnActivityCopyWith<$Res>  {
 | 
					abstract mixin class $SnTimelineEventCopyWith<$Res>  {
 | 
				
			||||||
  factory $SnActivityCopyWith(SnActivity value, $Res Function(SnActivity) _then) = _$SnActivityCopyWithImpl;
 | 
					  factory $SnTimelineEventCopyWith(SnTimelineEvent value, $Res Function(SnTimelineEvent) _then) = _$SnTimelineEventCopyWithImpl;
 | 
				
			||||||
@useResult
 | 
					@useResult
 | 
				
			||||||
$Res call({
 | 
					$Res call({
 | 
				
			||||||
 String id, String type, String resourceIdentifier, dynamic data, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
					 String id, String type, String resourceIdentifier, dynamic data, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
				
			||||||
@@ -331,14 +331,14 @@ $Res call({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
class _$SnActivityCopyWithImpl<$Res>
 | 
					class _$SnTimelineEventCopyWithImpl<$Res>
 | 
				
			||||||
    implements $SnActivityCopyWith<$Res> {
 | 
					    implements $SnTimelineEventCopyWith<$Res> {
 | 
				
			||||||
  _$SnActivityCopyWithImpl(this._self, this._then);
 | 
					  _$SnTimelineEventCopyWithImpl(this._self, this._then);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final SnActivity _self;
 | 
					  final SnTimelineEvent _self;
 | 
				
			||||||
  final $Res Function(SnActivity) _then;
 | 
					  final $Res Function(SnTimelineEvent) _then;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create a copy of SnActivity
 | 
					/// Create a copy of SnTimelineEvent
 | 
				
			||||||
/// 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? type = null,Object? resourceIdentifier = null,Object? data = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
					@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? type = null,Object? resourceIdentifier = null,Object? data = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
				
			||||||
  return _then(_self.copyWith(
 | 
					  return _then(_self.copyWith(
 | 
				
			||||||
@@ -356,8 +356,8 @@ as DateTime?,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Adds pattern-matching-related methods to [SnActivity].
 | 
					/// Adds pattern-matching-related methods to [SnTimelineEvent].
 | 
				
			||||||
extension SnActivityPatterns on SnActivity {
 | 
					extension SnTimelineEventPatterns on SnTimelineEvent {
 | 
				
			||||||
/// 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:
 | 
				
			||||||
@@ -370,10 +370,10 @@ extension SnActivityPatterns on SnActivity {
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnActivity value)?  $default,{required TResult orElse(),}){
 | 
					@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _SnTimelineEvent value)?  $default,{required TResult orElse(),}){
 | 
				
			||||||
final _that = this;
 | 
					final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity() when $default != null:
 | 
					case _SnTimelineEvent() when $default != null:
 | 
				
			||||||
return $default(_that);case _:
 | 
					return $default(_that);case _:
 | 
				
			||||||
  return orElse();
 | 
					  return orElse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -392,10 +392,10 @@ return $default(_that);case _:
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnActivity value)  $default,){
 | 
					@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _SnTimelineEvent value)  $default,){
 | 
				
			||||||
final _that = this;
 | 
					final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity():
 | 
					case _SnTimelineEvent():
 | 
				
			||||||
return $default(_that);}
 | 
					return $default(_that);}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/// A variant of `map` that fallback to returning `null`.
 | 
					/// A variant of `map` that fallback to returning `null`.
 | 
				
			||||||
@@ -410,10 +410,10 @@ return $default(_that);}
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnActivity value)?  $default,){
 | 
					@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _SnTimelineEvent value)?  $default,){
 | 
				
			||||||
final _that = this;
 | 
					final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity() when $default != null:
 | 
					case _SnTimelineEvent() when $default != null:
 | 
				
			||||||
return $default(_that);case _:
 | 
					return $default(_that);case _:
 | 
				
			||||||
  return null;
 | 
					  return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -433,7 +433,7 @@ return $default(_that);case _:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
					@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity() when $default != null:
 | 
					case _SnTimelineEvent() when $default != null:
 | 
				
			||||||
return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
					return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
				
			||||||
  return orElse();
 | 
					  return orElse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -454,7 +454,7 @@ return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.cr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
					@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity():
 | 
					case _SnTimelineEvent():
 | 
				
			||||||
return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);}
 | 
					return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/// A variant of `when` that fallback to returning `null`
 | 
					/// A variant of `when` that fallback to returning `null`
 | 
				
			||||||
@@ -471,7 +471,7 @@ return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.cr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
					@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  String type,  String resourceIdentifier,  dynamic data,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnActivity() when $default != null:
 | 
					case _SnTimelineEvent() when $default != null:
 | 
				
			||||||
return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
					return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
				
			||||||
  return null;
 | 
					  return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -483,9 +483,9 @@ return $default(_that.id,_that.type,_that.resourceIdentifier,_that.data,_that.cr
 | 
				
			|||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
@JsonSerializable()
 | 
					@JsonSerializable()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _SnActivity implements SnActivity {
 | 
					class _SnTimelineEvent implements SnTimelineEvent {
 | 
				
			||||||
  const _SnActivity({required this.id, required this.type, required this.resourceIdentifier, required this.data, required this.createdAt, required this.updatedAt, required this.deletedAt});
 | 
					  const _SnTimelineEvent({required this.id, required this.type, required this.resourceIdentifier, required this.data, required this.createdAt, required this.updatedAt, required this.deletedAt});
 | 
				
			||||||
  factory _SnActivity.fromJson(Map<String, dynamic> json) => _$SnActivityFromJson(json);
 | 
					  factory _SnTimelineEvent.fromJson(Map<String, dynamic> json) => _$SnTimelineEventFromJson(json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override final  String id;
 | 
					@override final  String id;
 | 
				
			||||||
@override final  String type;
 | 
					@override final  String type;
 | 
				
			||||||
@@ -495,20 +495,20 @@ class _SnActivity implements SnActivity {
 | 
				
			|||||||
@override final  DateTime updatedAt;
 | 
					@override final  DateTime updatedAt;
 | 
				
			||||||
@override final  DateTime? deletedAt;
 | 
					@override final  DateTime? deletedAt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create a copy of SnActivity
 | 
					/// Create a copy of SnTimelineEvent
 | 
				
			||||||
/// 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')
 | 
				
			||||||
_$SnActivityCopyWith<_SnActivity> get copyWith => __$SnActivityCopyWithImpl<_SnActivity>(this, _$identity);
 | 
					_$SnTimelineEventCopyWith<_SnTimelineEvent> get copyWith => __$SnTimelineEventCopyWithImpl<_SnTimelineEvent>(this, _$identity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override
 | 
					@override
 | 
				
			||||||
Map<String, dynamic> toJson() {
 | 
					Map<String, dynamic> toJson() {
 | 
				
			||||||
  return _$SnActivityToJson(this, );
 | 
					  return _$SnTimelineEventToJson(this, );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override
 | 
					@override
 | 
				
			||||||
bool operator ==(Object other) {
 | 
					bool operator ==(Object other) {
 | 
				
			||||||
  return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnActivity&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
					  return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnTimelineEvent&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.resourceIdentifier, resourceIdentifier) || other.resourceIdentifier == resourceIdentifier)&&const DeepCollectionEquality().equals(other.data, data)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@JsonKey(includeFromJson: false, includeToJson: false)
 | 
					@JsonKey(includeFromJson: false, includeToJson: false)
 | 
				
			||||||
@@ -517,15 +517,15 @@ int get hashCode => Object.hash(runtimeType,id,type,resourceIdentifier,const Dee
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@override
 | 
					@override
 | 
				
			||||||
String toString() {
 | 
					String toString() {
 | 
				
			||||||
  return 'SnActivity(id: $id, type: $type, resourceIdentifier: $resourceIdentifier, data: $data, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
 | 
					  return 'SnTimelineEvent(id: $id, type: $type, resourceIdentifier: $resourceIdentifier, data: $data, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
abstract mixin class _$SnActivityCopyWith<$Res> implements $SnActivityCopyWith<$Res> {
 | 
					abstract mixin class _$SnTimelineEventCopyWith<$Res> implements $SnTimelineEventCopyWith<$Res> {
 | 
				
			||||||
  factory _$SnActivityCopyWith(_SnActivity value, $Res Function(_SnActivity) _then) = __$SnActivityCopyWithImpl;
 | 
					  factory _$SnTimelineEventCopyWith(_SnTimelineEvent value, $Res Function(_SnTimelineEvent) _then) = __$SnTimelineEventCopyWithImpl;
 | 
				
			||||||
@override @useResult
 | 
					@override @useResult
 | 
				
			||||||
$Res call({
 | 
					$Res call({
 | 
				
			||||||
 String id, String type, String resourceIdentifier, dynamic data, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
					 String id, String type, String resourceIdentifier, dynamic data, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
				
			||||||
@@ -536,17 +536,17 @@ $Res call({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
class __$SnActivityCopyWithImpl<$Res>
 | 
					class __$SnTimelineEventCopyWithImpl<$Res>
 | 
				
			||||||
    implements _$SnActivityCopyWith<$Res> {
 | 
					    implements _$SnTimelineEventCopyWith<$Res> {
 | 
				
			||||||
  __$SnActivityCopyWithImpl(this._self, this._then);
 | 
					  __$SnTimelineEventCopyWithImpl(this._self, this._then);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final _SnActivity _self;
 | 
					  final _SnTimelineEvent _self;
 | 
				
			||||||
  final $Res Function(_SnActivity) _then;
 | 
					  final $Res Function(_SnTimelineEvent) _then;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Create a copy of SnActivity
 | 
					/// Create a copy of SnTimelineEvent
 | 
				
			||||||
/// 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? type = null,Object? resourceIdentifier = null,Object? data = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
					@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? type = null,Object? resourceIdentifier = null,Object? data = freezed,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
 | 
				
			||||||
  return _then(_SnActivity(
 | 
					  return _then(_SnTimelineEvent(
 | 
				
			||||||
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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
					as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String,resourceIdentifier: null == resourceIdentifier ? _self.resourceIdentifier : resourceIdentifier // ignore: cast_nullable_to_non_nullable
 | 
					as String,resourceIdentifier: null == resourceIdentifier ? _self.resourceIdentifier : resourceIdentifier // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
@@ -1429,7 +1429,7 @@ $SnCheckInResultCopyWith<$Res>? get checkInResult {
 | 
				
			|||||||
/// @nodoc
 | 
					/// @nodoc
 | 
				
			||||||
mixin _$SnPresenceActivity {
 | 
					mixin _$SnPresenceActivity {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 String get id; String get type; String? get manualId; String? get title; String? get subtitle; String? get caption; Map<String, dynamic>? get meta; int get leaseMinutes; DateTime get leaseExpiresAt; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
					 String get id; int get type; String? get manualId; String? get title; String? get subtitle; String? get caption; Map<String, dynamic>? get meta; int get leaseMinutes; DateTime get leaseExpiresAt; String get accountId; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
 | 
				
			||||||
/// Create a copy of SnPresenceActivity
 | 
					/// Create a copy of SnPresenceActivity
 | 
				
			||||||
/// 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)
 | 
				
			||||||
@@ -1462,7 +1462,7 @@ abstract mixin class $SnPresenceActivityCopyWith<$Res>  {
 | 
				
			|||||||
  factory $SnPresenceActivityCopyWith(SnPresenceActivity value, $Res Function(SnPresenceActivity) _then) = _$SnPresenceActivityCopyWithImpl;
 | 
					  factory $SnPresenceActivityCopyWith(SnPresenceActivity value, $Res Function(SnPresenceActivity) _then) = _$SnPresenceActivityCopyWithImpl;
 | 
				
			||||||
@useResult
 | 
					@useResult
 | 
				
			||||||
$Res call({
 | 
					$Res call({
 | 
				
			||||||
 String id, String type, String? manualId, String? title, String? subtitle, String? caption, Map<String, dynamic>? meta, int leaseMinutes, DateTime leaseExpiresAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
					 String id, int type, String? manualId, String? title, String? subtitle, String? caption, Map<String, dynamic>? meta, int leaseMinutes, DateTime leaseExpiresAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1483,7 +1483,7 @@ class _$SnPresenceActivityCopyWithImpl<$Res>
 | 
				
			|||||||
  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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
					as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String,manualId: freezed == manualId ? _self.manualId : manualId // ignore: cast_nullable_to_non_nullable
 | 
					as int,manualId: freezed == manualId ? _self.manualId : manualId // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
					as String?,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,subtitle: freezed == subtitle ? _self.subtitle : subtitle // ignore: cast_nullable_to_non_nullable
 | 
					as String?,subtitle: freezed == subtitle ? _self.subtitle : subtitle // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,caption: freezed == caption ? _self.caption : caption // ignore: cast_nullable_to_non_nullable
 | 
					as String?,caption: freezed == caption ? _self.caption : caption // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
@@ -1576,7 +1576,7 @@ return $default(_that);case _:
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  String type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
					@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String id,  int type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,{required TResult orElse(),}) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnPresenceActivity() when $default != null:
 | 
					case _SnPresenceActivity() when $default != null:
 | 
				
			||||||
return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
					return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
				
			||||||
@@ -1597,7 +1597,7 @@ return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_t
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  String type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
					@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String id,  int type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)  $default,) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnPresenceActivity():
 | 
					case _SnPresenceActivity():
 | 
				
			||||||
return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
 | 
					return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);}
 | 
				
			||||||
@@ -1614,7 +1614,7 @@ return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_t
 | 
				
			|||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  String type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
					@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String id,  int type,  String? manualId,  String? title,  String? subtitle,  String? caption,  Map<String, dynamic>? meta,  int leaseMinutes,  DateTime leaseExpiresAt,  String accountId,  DateTime createdAt,  DateTime updatedAt,  DateTime? deletedAt)?  $default,) {final _that = this;
 | 
				
			||||||
switch (_that) {
 | 
					switch (_that) {
 | 
				
			||||||
case _SnPresenceActivity() when $default != null:
 | 
					case _SnPresenceActivity() when $default != null:
 | 
				
			||||||
return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
					return $default(_that.id,_that.type,_that.manualId,_that.title,_that.subtitle,_that.caption,_that.meta,_that.leaseMinutes,_that.leaseExpiresAt,_that.accountId,_that.createdAt,_that.updatedAt,_that.deletedAt);case _:
 | 
				
			||||||
@@ -1633,7 +1633,7 @@ class _SnPresenceActivity implements SnPresenceActivity {
 | 
				
			|||||||
  factory _SnPresenceActivity.fromJson(Map<String, dynamic> json) => _$SnPresenceActivityFromJson(json);
 | 
					  factory _SnPresenceActivity.fromJson(Map<String, dynamic> json) => _$SnPresenceActivityFromJson(json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@override final  String id;
 | 
					@override final  String id;
 | 
				
			||||||
@override final  String type;
 | 
					@override final  int type;
 | 
				
			||||||
@override final  String? manualId;
 | 
					@override final  String? manualId;
 | 
				
			||||||
@override final  String? title;
 | 
					@override final  String? title;
 | 
				
			||||||
@override final  String? subtitle;
 | 
					@override final  String? subtitle;
 | 
				
			||||||
@@ -1687,7 +1687,7 @@ abstract mixin class _$SnPresenceActivityCopyWith<$Res> implements $SnPresenceAc
 | 
				
			|||||||
  factory _$SnPresenceActivityCopyWith(_SnPresenceActivity value, $Res Function(_SnPresenceActivity) _then) = __$SnPresenceActivityCopyWithImpl;
 | 
					  factory _$SnPresenceActivityCopyWith(_SnPresenceActivity value, $Res Function(_SnPresenceActivity) _then) = __$SnPresenceActivityCopyWithImpl;
 | 
				
			||||||
@override @useResult
 | 
					@override @useResult
 | 
				
			||||||
$Res call({
 | 
					$Res call({
 | 
				
			||||||
 String id, String type, String? manualId, String? title, String? subtitle, String? caption, Map<String, dynamic>? meta, int leaseMinutes, DateTime leaseExpiresAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
					 String id, int type, String? manualId, String? title, String? subtitle, String? caption, Map<String, dynamic>? meta, int leaseMinutes, DateTime leaseExpiresAt, String accountId, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1708,7 +1708,7 @@ class __$SnPresenceActivityCopyWithImpl<$Res>
 | 
				
			|||||||
  return _then(_SnPresenceActivity(
 | 
					  return _then(_SnPresenceActivity(
 | 
				
			||||||
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,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
					as String,type: null == type ? _self.type : type // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String,manualId: freezed == manualId ? _self.manualId : manualId // ignore: cast_nullable_to_non_nullable
 | 
					as int,manualId: freezed == manualId ? _self.manualId : manualId // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
					as String?,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,subtitle: freezed == subtitle ? _self.subtitle : subtitle // ignore: cast_nullable_to_non_nullable
 | 
					as String?,subtitle: freezed == subtitle ? _self.subtitle : subtitle // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
as String?,caption: freezed == caption ? _self.caption : caption // ignore: cast_nullable_to_non_nullable
 | 
					as String?,caption: freezed == caption ? _self.caption : caption // ignore: cast_nullable_to_non_nullable
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,20 +27,21 @@ Map<String, dynamic> _$SnNotableDayToJson(_SnNotableDay instance) =>
 | 
				
			|||||||
      'holidays': instance.holidays,
 | 
					      'holidays': instance.holidays,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_SnActivity _$SnActivityFromJson(Map<String, dynamic> json) => _SnActivity(
 | 
					_SnTimelineEvent _$SnTimelineEventFromJson(Map<String, dynamic> json) =>
 | 
				
			||||||
  id: json['id'] as String,
 | 
					    _SnTimelineEvent(
 | 
				
			||||||
  type: json['type'] as String,
 | 
					      id: json['id'] as String,
 | 
				
			||||||
  resourceIdentifier: json['resource_identifier'] as String,
 | 
					      type: json['type'] as String,
 | 
				
			||||||
  data: json['data'],
 | 
					      resourceIdentifier: json['resource_identifier'] as String,
 | 
				
			||||||
  createdAt: DateTime.parse(json['created_at'] as String),
 | 
					      data: json['data'],
 | 
				
			||||||
  updatedAt: DateTime.parse(json['updated_at'] as String),
 | 
					      createdAt: DateTime.parse(json['created_at'] as String),
 | 
				
			||||||
  deletedAt:
 | 
					      updatedAt: DateTime.parse(json['updated_at'] as String),
 | 
				
			||||||
      json['deleted_at'] == null
 | 
					      deletedAt:
 | 
				
			||||||
          ? null
 | 
					          json['deleted_at'] == null
 | 
				
			||||||
          : DateTime.parse(json['deleted_at'] as String),
 | 
					              ? null
 | 
				
			||||||
);
 | 
					              : DateTime.parse(json['deleted_at'] as String),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Map<String, dynamic> _$SnActivityToJson(_SnActivity instance) =>
 | 
					Map<String, dynamic> _$SnTimelineEventToJson(_SnTimelineEvent instance) =>
 | 
				
			||||||
    <String, dynamic>{
 | 
					    <String, dynamic>{
 | 
				
			||||||
      'id': instance.id,
 | 
					      'id': instance.id,
 | 
				
			||||||
      'type': instance.type,
 | 
					      'type': instance.type,
 | 
				
			||||||
@@ -125,7 +126,7 @@ Map<String, dynamic> _$SnEventCalendarEntryToJson(
 | 
				
			|||||||
_SnPresenceActivity _$SnPresenceActivityFromJson(Map<String, dynamic> json) =>
 | 
					_SnPresenceActivity _$SnPresenceActivityFromJson(Map<String, dynamic> json) =>
 | 
				
			||||||
    _SnPresenceActivity(
 | 
					    _SnPresenceActivity(
 | 
				
			||||||
      id: json['id'] as String,
 | 
					      id: json['id'] as String,
 | 
				
			||||||
      type: json['type'] as String,
 | 
					      type: (json['type'] as num).toInt(),
 | 
				
			||||||
      manualId: json['manual_id'] as String?,
 | 
					      manualId: json['manual_id'] as String?,
 | 
				
			||||||
      title: json['title'] as String?,
 | 
					      title: json['title'] as String?,
 | 
				
			||||||
      subtitle: json['subtitle'] as String?,
 | 
					      subtitle: json['subtitle'] as String?,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@ import 'dart:convert';
 | 
				
			|||||||
import 'dart:io';
 | 
					import 'dart:io';
 | 
				
			||||||
import 'package:flutter/foundation.dart';
 | 
					import 'package:flutter/foundation.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:island/models/account.dart';
 | 
					 | 
				
			||||||
import 'package:island/models/activity.dart';
 | 
					import 'package:island/models/activity.dart';
 | 
				
			||||||
import 'package:island/pods/network.dart';
 | 
					import 'package:island/pods/network.dart';
 | 
				
			||||||
import 'package:island/talker.dart';
 | 
					import 'package:island/talker.dart';
 | 
				
			||||||
@@ -14,11 +13,11 @@ import 'package:shelf/shelf_io.dart' as shelf_io;
 | 
				
			|||||||
import 'package:shelf_web_socket/shelf_web_socket.dart';
 | 
					import 'package:shelf_web_socket/shelf_web_socket.dart';
 | 
				
			||||||
import 'package:web_socket_channel/web_socket_channel.dart';
 | 
					import 'package:web_socket_channel/web_socket_channel.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
part 'activity_rpc.g.dart';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Conditional imports for IPC server - use web stubs on web platform
 | 
					// Conditional imports for IPC server - use web stubs on web platform
 | 
				
			||||||
import 'ipc_server.dart' if (dart.library.html) 'ipc_server.web.dart';
 | 
					import 'ipc_server.dart' if (dart.library.html) 'ipc_server.web.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part 'activity_rpc.g.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const String kRpcLogPrefix = 'arRPC.websocket';
 | 
					const String kRpcLogPrefix = 'arRPC.websocket';
 | 
				
			||||||
const String kRpcIpcLogPrefix = 'arRPC.ipc';
 | 
					const String kRpcIpcLogPrefix = 'arRPC.ipc';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -125,7 +124,7 @@ class ActivityRpcServer {
 | 
				
			|||||||
        talker.log('[$kRpcLogPrefix] IPC server error: $e');
 | 
					        talker.log('[$kRpcLogPrefix] IPC server error: $e');
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      talker.log('IPC server disabled on macOS or web in production mode');
 | 
					      talker.log('IPC server disabled on macOS or web');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -326,6 +325,8 @@ class ServerStateNotifier extends StateNotifier<ServerState> {
 | 
				
			|||||||
  ServerStateNotifier(this.server)
 | 
					  ServerStateNotifier(this.server)
 | 
				
			||||||
    : super(ServerState(status: 'Server not started'));
 | 
					    : super(ServerState(status: 'Server not started'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String? get currentActivityManualId => state.currentActivityManualId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> start() async {
 | 
					  Future<void> start() async {
 | 
				
			||||||
    if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) {
 | 
					    if (!kIsWeb && !Platform.isAndroid && !Platform.isIOS) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
@@ -354,114 +355,107 @@ class ServerStateNotifier extends StateNotifier<ServerState> {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const kPresenseActivityLease = 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Providers
 | 
					// Providers
 | 
				
			||||||
final rpcServerStateProvider =
 | 
					final rpcServerStateProvider = StateNotifierProvider<
 | 
				
			||||||
    StateNotifierProvider<ServerStateNotifier, ServerState>((ref) {
 | 
					  ServerStateNotifier,
 | 
				
			||||||
      final server = ActivityRpcServer({});
 | 
					  ServerState
 | 
				
			||||||
      final notifier = ServerStateNotifier(server);
 | 
					>((ref) {
 | 
				
			||||||
      server.updateHandlers({
 | 
					  final server = ActivityRpcServer({});
 | 
				
			||||||
        'connection': (socket) {
 | 
					  final notifier = ServerStateNotifier(server);
 | 
				
			||||||
          final clientId =
 | 
					  server.updateHandlers({
 | 
				
			||||||
              socket is _WsSocketWrapper
 | 
					    'connection': (socket) {
 | 
				
			||||||
                  ? socket.clientId
 | 
					      final clientId =
 | 
				
			||||||
                  : (socket as IpcSocketWrapper).clientId;
 | 
					          socket is _WsSocketWrapper
 | 
				
			||||||
          notifier.updateStatus('Client connected (ID: $clientId)');
 | 
					              ? socket.clientId
 | 
				
			||||||
          socket.send({
 | 
					              : (socket as IpcSocketWrapper).clientId;
 | 
				
			||||||
            'cmd': 'DISPATCH',
 | 
					      notifier.updateStatus('Client connected (ID: $clientId)');
 | 
				
			||||||
            'data': {
 | 
					      socket.send({
 | 
				
			||||||
              'v': 1,
 | 
					        'cmd': 'DISPATCH',
 | 
				
			||||||
              'config': {
 | 
					        'data': {
 | 
				
			||||||
                'cdn_host': 'fake.cdn',
 | 
					          'v': 1,
 | 
				
			||||||
                'api_endpoint': '//fake.api',
 | 
					          'config': {
 | 
				
			||||||
                'environment': 'dev',
 | 
					            'cdn_host': 'fake.cdn',
 | 
				
			||||||
              },
 | 
					            'api_endpoint': '//fake.api',
 | 
				
			||||||
              'user': {
 | 
					            'environment': 'dev',
 | 
				
			||||||
                'id': 'fake_user_id',
 | 
					          },
 | 
				
			||||||
                'username': 'FakeUser',
 | 
					          'user': {
 | 
				
			||||||
                'discriminator': '0001',
 | 
					            'id': 'fake_user_id',
 | 
				
			||||||
                'avatar': null,
 | 
					            'username': 'FakeUser',
 | 
				
			||||||
                'bot': false,
 | 
					            'discriminator': '0001',
 | 
				
			||||||
              },
 | 
					            'avatar': null,
 | 
				
			||||||
            },
 | 
					            'bot': false,
 | 
				
			||||||
            'evt': 'READY',
 | 
					          },
 | 
				
			||||||
            'nonce': '12345',
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        'message': (socket, dynamic data) async {
 | 
					 | 
				
			||||||
          if (data['cmd'] == 'SET_ACTIVITY') {
 | 
					 | 
				
			||||||
            notifier.addActivity(
 | 
					 | 
				
			||||||
              'Activity: ${data['args']['activity']['details'] ?? ''}',
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            final label = data['args']['activity']['details'] ?? '';
 | 
					 | 
				
			||||||
            final appId = socket.clientId;
 | 
					 | 
				
			||||||
            final meta = data['args']['activity'];
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
              final apiClient = ref.watch(apiClientProvider);
 | 
					 | 
				
			||||||
              final currentId = notifier.state.currentActivityManualId;
 | 
					 | 
				
			||||||
              final isUpdate = currentId == appId;
 | 
					 | 
				
			||||||
              final activityData = {
 | 
					 | 
				
			||||||
                'type': 'Gaming',
 | 
					 | 
				
			||||||
                'manualId': appId,
 | 
					 | 
				
			||||||
                'title': label,
 | 
					 | 
				
			||||||
                'meta': meta,
 | 
					 | 
				
			||||||
                'leaseMinutes': 30,
 | 
					 | 
				
			||||||
              };
 | 
					 | 
				
			||||||
              if (isUpdate) {
 | 
					 | 
				
			||||||
                await apiClient.put(
 | 
					 | 
				
			||||||
                  '/pass/activities',
 | 
					 | 
				
			||||||
                  queryParameters: {'manual_id': appId},
 | 
					 | 
				
			||||||
                  data: {'leaseMinutes': 30},
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
              } else {
 | 
					 | 
				
			||||||
                await apiClient.post('/pass/activities', data: activityData);
 | 
					 | 
				
			||||||
                notifier.setCurrentActivityManualId(appId);
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
              final now = DateTime.now();
 | 
					 | 
				
			||||||
              final status = SnAccountStatus(
 | 
					 | 
				
			||||||
                id: 'local_$appId',
 | 
					 | 
				
			||||||
                attitude: 0,
 | 
					 | 
				
			||||||
                isOnline: true,
 | 
					 | 
				
			||||||
                isInvisible: false,
 | 
					 | 
				
			||||||
                isNotDisturb: false,
 | 
					 | 
				
			||||||
                isCustomized: true,
 | 
					 | 
				
			||||||
                label: label,
 | 
					 | 
				
			||||||
                meta: meta,
 | 
					 | 
				
			||||||
                clearedAt: null,
 | 
					 | 
				
			||||||
                accountId: 'me',
 | 
					 | 
				
			||||||
                createdAt: now,
 | 
					 | 
				
			||||||
                updatedAt: now,
 | 
					 | 
				
			||||||
                deletedAt: null,
 | 
					 | 
				
			||||||
              );
 | 
					 | 
				
			||||||
              ref.read(currentAccountStatusProvider.notifier).setStatus(status);
 | 
					 | 
				
			||||||
            } catch (e) {
 | 
					 | 
				
			||||||
              talker.log('Failed to set remote activity status: $e');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            socket.send({
 | 
					 | 
				
			||||||
              'cmd': 'SET_ACTIVITY',
 | 
					 | 
				
			||||||
              'data': data['args']['activity'],
 | 
					 | 
				
			||||||
              'evt': null,
 | 
					 | 
				
			||||||
              'nonce': data['nonce'],
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        'close': (socket) async {
 | 
					 | 
				
			||||||
          notifier.updateStatus('Client disconnected');
 | 
					 | 
				
			||||||
          final appId = socket.clientId;
 | 
					 | 
				
			||||||
          try {
 | 
					 | 
				
			||||||
            final apiClient = ref.watch(apiClientProvider);
 | 
					 | 
				
			||||||
            await apiClient.delete(
 | 
					 | 
				
			||||||
              '/pass/activities',
 | 
					 | 
				
			||||||
              queryParameters: {'manual_id': appId},
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            notifier.setCurrentActivityManualId(null);
 | 
					 | 
				
			||||||
            ref.read(currentAccountStatusProvider.notifier).clearStatus();
 | 
					 | 
				
			||||||
          } catch (e) {
 | 
					 | 
				
			||||||
            talker.log('Failed to unset remote activity status: $e');
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        'evt': 'READY',
 | 
				
			||||||
 | 
					        'nonce': '12345',
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
      return notifier;
 | 
					    },
 | 
				
			||||||
    });
 | 
					    'message': (socket, dynamic data) async {
 | 
				
			||||||
 | 
					      if (data['cmd'] == 'SET_ACTIVITY') {
 | 
				
			||||||
 | 
					        final activity = data['args']['activity'];
 | 
				
			||||||
 | 
					        notifier.addActivity('Activity: ${activity['details'] ?? 'Untitled'}');
 | 
				
			||||||
 | 
					        final appId = activity['application_id'] ?? socket.clientId;
 | 
				
			||||||
 | 
					        // https://discord.com/developers/docs/topics/rpc#setactivity-set-activity-argument-structure
 | 
				
			||||||
 | 
					        final type = switch (activity['type']) {
 | 
				
			||||||
 | 
					          0 => 1, // Discord Playing -> Playing
 | 
				
			||||||
 | 
					          2 => 2, // Discord Music -> Listening
 | 
				
			||||||
 | 
					          3 => 2, // Discord Watching -> Listening
 | 
				
			||||||
 | 
					          _ => 1, // Discord Competing (or null) -> Playing
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          final apiClient = ref.watch(apiClientProvider);
 | 
				
			||||||
 | 
					          final currentId = notifier.currentActivityManualId;
 | 
				
			||||||
 | 
					          final isUpdate = currentId == appId;
 | 
				
			||||||
 | 
					          final activityData = {
 | 
				
			||||||
 | 
					            'type': type,
 | 
				
			||||||
 | 
					            'manual_id': appId,
 | 
				
			||||||
 | 
					            'title': activity['name'],
 | 
				
			||||||
 | 
					            'subtitle': activity['details'],
 | 
				
			||||||
 | 
					            'caption': activity['state'],
 | 
				
			||||||
 | 
					            'meta': activity,
 | 
				
			||||||
 | 
					            'lease_minutes': kPresenseActivityLease,
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					          if (isUpdate) {
 | 
				
			||||||
 | 
					            await apiClient.put(
 | 
				
			||||||
 | 
					              '/pass/activities',
 | 
				
			||||||
 | 
					              queryParameters: {'manualId': appId},
 | 
				
			||||||
 | 
					              data: {'lease_minutes': kPresenseActivityLease},
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            await apiClient.post('/pass/activities', data: activityData);
 | 
				
			||||||
 | 
					            notifier.setCurrentActivityManualId(appId);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } catch (e) {
 | 
				
			||||||
 | 
					          talker.log('Failed to set remote activity status: $e');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        socket.send({
 | 
				
			||||||
 | 
					          'cmd': 'SET_ACTIVITY',
 | 
				
			||||||
 | 
					          'data': data['args']['activity'],
 | 
				
			||||||
 | 
					          'evt': null,
 | 
				
			||||||
 | 
					          'nonce': data['nonce'],
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    'close': (socket) async {
 | 
				
			||||||
 | 
					      notifier.updateStatus('Client disconnected');
 | 
				
			||||||
 | 
					      final appId = socket.clientId;
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        final apiClient = ref.watch(apiClientProvider);
 | 
				
			||||||
 | 
					        await apiClient.delete(
 | 
				
			||||||
 | 
					          '/pass/activities',
 | 
				
			||||||
 | 
					          queryParameters: {'manualId': appId},
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        notifier.setCurrentActivityManualId(null);
 | 
				
			||||||
 | 
					        ref.read(currentAccountStatusProvider.notifier).clearStatus();
 | 
				
			||||||
 | 
					      } catch (e) {
 | 
				
			||||||
 | 
					        talker.log('Failed to unset remote activity status: $e');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  return notifier;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final rpcServerProvider = Provider<ActivityRpcServer>((ref) {
 | 
					final rpcServerProvider = Provider<ActivityRpcServer>((ref) {
 | 
				
			||||||
  final notifier = ref.watch(rpcServerStateProvider.notifier);
 | 
					  final notifier = ref.watch(rpcServerStateProvider.notifier);
 | 
				
			||||||
@@ -474,7 +468,7 @@ Future<List<SnPresenceActivity>> presenceActivities(
 | 
				
			|||||||
  String uname,
 | 
					  String uname,
 | 
				
			||||||
) async {
 | 
					) async {
 | 
				
			||||||
  final apiClient = ref.watch(apiClientProvider);
 | 
					  final apiClient = ref.watch(apiClientProvider);
 | 
				
			||||||
  final response = await apiClient.get('/pass/accounts/$uname/activities');
 | 
					  final response = await apiClient.get('/pass/activities/$uname');
 | 
				
			||||||
  final data = response.data as List<dynamic>;
 | 
					  final data = response.data as List<dynamic>;
 | 
				
			||||||
  return data.map((json) => SnPresenceActivity.fromJson(json)).toList();
 | 
					  return data.map((json) => SnPresenceActivity.fromJson(json)).toList();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										157
									
								
								lib/pods/activity/activity_rpc.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								lib/pods/activity/activity_rpc.g.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
				
			|||||||
 | 
					// GENERATED CODE - DO NOT MODIFY BY HAND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part of 'activity_rpc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					// RiverpodGenerator
 | 
				
			||||||
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					String _$presenceActivitiesHash() =>
 | 
				
			||||||
 | 
					    r'dcea3cad01b4010c0087f5281413d83a754c2a17';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Copied from Dart SDK
 | 
				
			||||||
 | 
					class _SystemHash {
 | 
				
			||||||
 | 
					  _SystemHash._();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static int combine(int hash, int value) {
 | 
				
			||||||
 | 
					    // ignore: parameter_assignments
 | 
				
			||||||
 | 
					    hash = 0x1fffffff & (hash + value);
 | 
				
			||||||
 | 
					    // ignore: parameter_assignments
 | 
				
			||||||
 | 
					    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
 | 
				
			||||||
 | 
					    return hash ^ (hash >> 6);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static int finish(int hash) {
 | 
				
			||||||
 | 
					    // ignore: parameter_assignments
 | 
				
			||||||
 | 
					    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
 | 
				
			||||||
 | 
					    // ignore: parameter_assignments
 | 
				
			||||||
 | 
					    hash = hash ^ (hash >> 11);
 | 
				
			||||||
 | 
					    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// See also [presenceActivities].
 | 
				
			||||||
 | 
					@ProviderFor(presenceActivities)
 | 
				
			||||||
 | 
					const presenceActivitiesProvider = PresenceActivitiesFamily();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// See also [presenceActivities].
 | 
				
			||||||
 | 
					class PresenceActivitiesFamily
 | 
				
			||||||
 | 
					    extends Family<AsyncValue<List<SnPresenceActivity>>> {
 | 
				
			||||||
 | 
					  /// See also [presenceActivities].
 | 
				
			||||||
 | 
					  const PresenceActivitiesFamily();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// See also [presenceActivities].
 | 
				
			||||||
 | 
					  PresenceActivitiesProvider call(String uname) {
 | 
				
			||||||
 | 
					    return PresenceActivitiesProvider(uname);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  PresenceActivitiesProvider getProviderOverride(
 | 
				
			||||||
 | 
					    covariant PresenceActivitiesProvider provider,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    return call(provider.uname);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const Iterable<ProviderOrFamily>? _dependencies = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Iterable<ProviderOrFamily>? get dependencies => _dependencies;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
 | 
				
			||||||
 | 
					      _allTransitiveDependencies;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String? get name => r'presenceActivitiesProvider';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// See also [presenceActivities].
 | 
				
			||||||
 | 
					class PresenceActivitiesProvider
 | 
				
			||||||
 | 
					    extends AutoDisposeFutureProvider<List<SnPresenceActivity>> {
 | 
				
			||||||
 | 
					  /// See also [presenceActivities].
 | 
				
			||||||
 | 
					  PresenceActivitiesProvider(String uname)
 | 
				
			||||||
 | 
					    : this._internal(
 | 
				
			||||||
 | 
					        (ref) => presenceActivities(ref as PresenceActivitiesRef, uname),
 | 
				
			||||||
 | 
					        from: presenceActivitiesProvider,
 | 
				
			||||||
 | 
					        name: r'presenceActivitiesProvider',
 | 
				
			||||||
 | 
					        debugGetCreateSourceHash:
 | 
				
			||||||
 | 
					            const bool.fromEnvironment('dart.vm.product')
 | 
				
			||||||
 | 
					                ? null
 | 
				
			||||||
 | 
					                : _$presenceActivitiesHash,
 | 
				
			||||||
 | 
					        dependencies: PresenceActivitiesFamily._dependencies,
 | 
				
			||||||
 | 
					        allTransitiveDependencies:
 | 
				
			||||||
 | 
					            PresenceActivitiesFamily._allTransitiveDependencies,
 | 
				
			||||||
 | 
					        uname: uname,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  PresenceActivitiesProvider._internal(
 | 
				
			||||||
 | 
					    super._createNotifier, {
 | 
				
			||||||
 | 
					    required super.name,
 | 
				
			||||||
 | 
					    required super.dependencies,
 | 
				
			||||||
 | 
					    required super.allTransitiveDependencies,
 | 
				
			||||||
 | 
					    required super.debugGetCreateSourceHash,
 | 
				
			||||||
 | 
					    required super.from,
 | 
				
			||||||
 | 
					    required this.uname,
 | 
				
			||||||
 | 
					  }) : super.internal();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final String uname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Override overrideWith(
 | 
				
			||||||
 | 
					    FutureOr<List<SnPresenceActivity>> Function(PresenceActivitiesRef provider)
 | 
				
			||||||
 | 
					    create,
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    return ProviderOverride(
 | 
				
			||||||
 | 
					      origin: this,
 | 
				
			||||||
 | 
					      override: PresenceActivitiesProvider._internal(
 | 
				
			||||||
 | 
					        (ref) => create(ref as PresenceActivitiesRef),
 | 
				
			||||||
 | 
					        from: from,
 | 
				
			||||||
 | 
					        name: null,
 | 
				
			||||||
 | 
					        dependencies: null,
 | 
				
			||||||
 | 
					        allTransitiveDependencies: null,
 | 
				
			||||||
 | 
					        debugGetCreateSourceHash: null,
 | 
				
			||||||
 | 
					        uname: uname,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  AutoDisposeFutureProviderElement<List<SnPresenceActivity>> createElement() {
 | 
				
			||||||
 | 
					    return _PresenceActivitiesProviderElement(this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool operator ==(Object other) {
 | 
				
			||||||
 | 
					    return other is PresenceActivitiesProvider && other.uname == uname;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  int get hashCode {
 | 
				
			||||||
 | 
					    var hash = _SystemHash.combine(0, runtimeType.hashCode);
 | 
				
			||||||
 | 
					    hash = _SystemHash.combine(hash, uname.hashCode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return _SystemHash.finish(hash);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Deprecated('Will be removed in 3.0. Use Ref instead')
 | 
				
			||||||
 | 
					// ignore: unused_element
 | 
				
			||||||
 | 
					mixin PresenceActivitiesRef
 | 
				
			||||||
 | 
					    on AutoDisposeFutureProviderRef<List<SnPresenceActivity>> {
 | 
				
			||||||
 | 
					  /// The parameter `uname` of this provider.
 | 
				
			||||||
 | 
					  String get uname;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _PresenceActivitiesProviderElement
 | 
				
			||||||
 | 
					    extends AutoDisposeFutureProviderElement<List<SnPresenceActivity>>
 | 
				
			||||||
 | 
					    with PresenceActivitiesRef {
 | 
				
			||||||
 | 
					  _PresenceActivitiesProviderElement(super.provider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String get uname => (origin as PresenceActivitiesProvider).uname;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ignore_for_file: type=lint
 | 
				
			||||||
 | 
					// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
 | 
				
			||||||
@@ -1013,7 +1013,7 @@ class AccountProfileScreen extends HookConsumerWidget {
 | 
				
			|||||||
                      SliverToBoxAdapter(
 | 
					                      SliverToBoxAdapter(
 | 
				
			||||||
                        child: ActivityPresenceWidget(
 | 
					                        child: ActivityPresenceWidget(
 | 
				
			||||||
                          uname: name,
 | 
					                          uname: name,
 | 
				
			||||||
                        ).padding(horizontal: 4),
 | 
					                        ).padding(horizontal: 8),
 | 
				
			||||||
                      ),
 | 
					                      ),
 | 
				
			||||||
                    ],
 | 
					                    ],
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -634,7 +634,7 @@ class _DiscoveryActivityItem extends StatelessWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _ActivityListView extends HookConsumerWidget {
 | 
					class _ActivityListView extends HookConsumerWidget {
 | 
				
			||||||
  final CursorPagingData<SnActivity> data;
 | 
					  final CursorPagingData<SnTimelineEvent> data;
 | 
				
			||||||
  final int widgetCount;
 | 
					  final int widgetCount;
 | 
				
			||||||
  final Widget endItemView;
 | 
					  final Widget endItemView;
 | 
				
			||||||
  final ActivityListNotifier activitiesNotifier;
 | 
					  final ActivityListNotifier activitiesNotifier;
 | 
				
			||||||
@@ -697,13 +697,13 @@ class _ActivityListView extends HookConsumerWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@riverpod
 | 
					@riverpod
 | 
				
			||||||
class ActivityListNotifier extends _$ActivityListNotifier
 | 
					class ActivityListNotifier extends _$ActivityListNotifier
 | 
				
			||||||
    with CursorPagingNotifierMixin<SnActivity> {
 | 
					    with CursorPagingNotifierMixin<SnTimelineEvent> {
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Future<CursorPagingData<SnActivity>> build(String? filter) =>
 | 
					  Future<CursorPagingData<SnTimelineEvent>> build(String? filter) =>
 | 
				
			||||||
      fetch(cursor: null);
 | 
					      fetch(cursor: null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Future<CursorPagingData<SnActivity>> fetch({required String? cursor}) async {
 | 
					  Future<CursorPagingData<SnTimelineEvent>> fetch({required String? cursor}) async {
 | 
				
			||||||
    final client = ref.read(apiClientProvider);
 | 
					    final client = ref.read(apiClientProvider);
 | 
				
			||||||
    final take = 20;
 | 
					    final take = 20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -720,9 +720,9 @@ class ActivityListNotifier extends _$ActivityListNotifier
 | 
				
			|||||||
      queryParameters: queryParameters,
 | 
					      queryParameters: queryParameters,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final List<SnActivity> items =
 | 
					    final List<SnTimelineEvent> items =
 | 
				
			||||||
        (response.data as List)
 | 
					        (response.data as List)
 | 
				
			||||||
            .map((e) => SnActivity.fromJson(e as Map<String, dynamic>))
 | 
					            .map((e) => SnTimelineEvent.fromJson(e as Map<String, dynamic>))
 | 
				
			||||||
            .toList();
 | 
					            .toList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final hasMore = (items.firstOrNull?.type ?? 'empty') != 'empty';
 | 
					    final hasMore = (items.firstOrNull?.type ?? 'empty') != 'empty';
 | 
				
			||||||
@@ -742,7 +742,7 @@ class ActivityListNotifier extends _$ActivityListNotifier
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void updateOne(int index, SnActivity activity) {
 | 
					  void updateOne(int index, SnTimelineEvent activity) {
 | 
				
			||||||
    final currentState = state.valueOrNull;
 | 
					    final currentState = state.valueOrNull;
 | 
				
			||||||
    if (currentState == null) return;
 | 
					    if (currentState == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ part of 'explore.dart';
 | 
				
			|||||||
// **************************************************************************
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String _$activityListNotifierHash() =>
 | 
					String _$activityListNotifierHash() =>
 | 
				
			||||||
    r'167021cada54da7c8d8437eef1ffb387a92ea2e3';
 | 
					    r'a3ad3242f08139bef14a2f0fab6591ce8b3cb9f0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Copied from Dart SDK
 | 
					/// Copied from Dart SDK
 | 
				
			||||||
class _SystemHash {
 | 
					class _SystemHash {
 | 
				
			||||||
@@ -31,10 +31,11 @@ class _SystemHash {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class _$ActivityListNotifier
 | 
					abstract class _$ActivityListNotifier
 | 
				
			||||||
    extends BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnActivity>> {
 | 
					    extends
 | 
				
			||||||
 | 
					        BuildlessAutoDisposeAsyncNotifier<CursorPagingData<SnTimelineEvent>> {
 | 
				
			||||||
  late final String? filter;
 | 
					  late final String? filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FutureOr<CursorPagingData<SnActivity>> build(String? filter);
 | 
					  FutureOr<CursorPagingData<SnTimelineEvent>> build(String? filter);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// See also [ActivityListNotifier].
 | 
					/// See also [ActivityListNotifier].
 | 
				
			||||||
@@ -43,7 +44,7 @@ const activityListNotifierProvider = ActivityListNotifierFamily();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// See also [ActivityListNotifier].
 | 
					/// See also [ActivityListNotifier].
 | 
				
			||||||
class ActivityListNotifierFamily
 | 
					class ActivityListNotifierFamily
 | 
				
			||||||
    extends Family<AsyncValue<CursorPagingData<SnActivity>>> {
 | 
					    extends Family<AsyncValue<CursorPagingData<SnTimelineEvent>>> {
 | 
				
			||||||
  /// See also [ActivityListNotifier].
 | 
					  /// See also [ActivityListNotifier].
 | 
				
			||||||
  const ActivityListNotifierFamily();
 | 
					  const ActivityListNotifierFamily();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -79,7 +80,7 @@ class ActivityListNotifierProvider
 | 
				
			|||||||
    extends
 | 
					    extends
 | 
				
			||||||
        AutoDisposeAsyncNotifierProviderImpl<
 | 
					        AutoDisposeAsyncNotifierProviderImpl<
 | 
				
			||||||
          ActivityListNotifier,
 | 
					          ActivityListNotifier,
 | 
				
			||||||
          CursorPagingData<SnActivity>
 | 
					          CursorPagingData<SnTimelineEvent>
 | 
				
			||||||
        > {
 | 
					        > {
 | 
				
			||||||
  /// See also [ActivityListNotifier].
 | 
					  /// See also [ActivityListNotifier].
 | 
				
			||||||
  ActivityListNotifierProvider(String? filter)
 | 
					  ActivityListNotifierProvider(String? filter)
 | 
				
			||||||
@@ -110,7 +111,7 @@ class ActivityListNotifierProvider
 | 
				
			|||||||
  final String? filter;
 | 
					  final String? filter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  FutureOr<CursorPagingData<SnActivity>> runNotifierBuild(
 | 
					  FutureOr<CursorPagingData<SnTimelineEvent>> runNotifierBuild(
 | 
				
			||||||
    covariant ActivityListNotifier notifier,
 | 
					    covariant ActivityListNotifier notifier,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    return notifier.build(filter);
 | 
					    return notifier.build(filter);
 | 
				
			||||||
@@ -135,7 +136,7 @@ class ActivityListNotifierProvider
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  AutoDisposeAsyncNotifierProviderElement<
 | 
					  AutoDisposeAsyncNotifierProviderElement<
 | 
				
			||||||
    ActivityListNotifier,
 | 
					    ActivityListNotifier,
 | 
				
			||||||
    CursorPagingData<SnActivity>
 | 
					    CursorPagingData<SnTimelineEvent>
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
  createElement() {
 | 
					  createElement() {
 | 
				
			||||||
    return _ActivityListNotifierProviderElement(this);
 | 
					    return _ActivityListNotifierProviderElement(this);
 | 
				
			||||||
@@ -158,7 +159,7 @@ class ActivityListNotifierProvider
 | 
				
			|||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
 | 
					@Deprecated('Will be removed in 3.0. Use Ref instead')
 | 
				
			||||||
// ignore: unused_element
 | 
					// ignore: unused_element
 | 
				
			||||||
mixin ActivityListNotifierRef
 | 
					mixin ActivityListNotifierRef
 | 
				
			||||||
    on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnActivity>> {
 | 
					    on AutoDisposeAsyncNotifierProviderRef<CursorPagingData<SnTimelineEvent>> {
 | 
				
			||||||
  /// The parameter `filter` of this provider.
 | 
					  /// The parameter `filter` of this provider.
 | 
				
			||||||
  String? get filter;
 | 
					  String? get filter;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -167,7 +168,7 @@ class _ActivityListNotifierProviderElement
 | 
				
			|||||||
    extends
 | 
					    extends
 | 
				
			||||||
        AutoDisposeAsyncNotifierProviderElement<
 | 
					        AutoDisposeAsyncNotifierProviderElement<
 | 
				
			||||||
          ActivityListNotifier,
 | 
					          ActivityListNotifier,
 | 
				
			||||||
          CursorPagingData<SnActivity>
 | 
					          CursorPagingData<SnTimelineEvent>
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
    with ActivityListNotifierRef {
 | 
					    with ActivityListNotifierRef {
 | 
				
			||||||
  _ActivityListNotifierProviderElement(super.provider);
 | 
					  _ActivityListNotifierProviderElement(super.provider);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,16 @@
 | 
				
			|||||||
 | 
					import 'package:easy_localization/easy_localization.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
import 'package:island/models/activity.dart';
 | 
					 | 
				
			||||||
import 'package:island/pods/activity/activity_rpc.dart';
 | 
					import 'package:island/pods/activity/activity_rpc.dart';
 | 
				
			||||||
 | 
					import 'package:material_symbols_icons/symbols.dart';
 | 
				
			||||||
 | 
					import 'package:styled_widget/styled_widget.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const kPresenseActivityTypes = [
 | 
				
			||||||
 | 
					  'unknown',
 | 
				
			||||||
 | 
					  'presenceTypeGaming',
 | 
				
			||||||
 | 
					  'presenceTypeMusic',
 | 
				
			||||||
 | 
					  'presenceTypeWorkout',
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityPresenceWidget extends ConsumerWidget {
 | 
					class ActivityPresenceWidget extends ConsumerWidget {
 | 
				
			||||||
  final String uname;
 | 
					  final String uname;
 | 
				
			||||||
@@ -13,48 +22,64 @@ class ActivityPresenceWidget extends ConsumerWidget {
 | 
				
			|||||||
    final activitiesAsync = ref.watch(presenceActivitiesProvider(uname));
 | 
					    final activitiesAsync = ref.watch(presenceActivitiesProvider(uname));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return activitiesAsync.when(
 | 
					    return activitiesAsync.when(
 | 
				
			||||||
      data: (activities) => _buildActivitiesList(activities),
 | 
					      data:
 | 
				
			||||||
 | 
					          (activities) => Card(
 | 
				
			||||||
 | 
					            child: Column(
 | 
				
			||||||
 | 
					              crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					              spacing: 8,
 | 
				
			||||||
 | 
					              children: [
 | 
				
			||||||
 | 
					                Text(
 | 
				
			||||||
 | 
					                  'activities',
 | 
				
			||||||
 | 
					                ).tr().bold().padding(horizontal: 8, vertical: 4),
 | 
				
			||||||
 | 
					                if (activities.isEmpty)
 | 
				
			||||||
 | 
					                  Row(children: [
 | 
				
			||||||
 | 
					                    const Icon(Symbols.inbox),
 | 
				
			||||||
 | 
					                    Text('dataEmpty').tr()
 | 
				
			||||||
 | 
					                  ],).opacity(0.75),
 | 
				
			||||||
 | 
					                ...activities.map(
 | 
				
			||||||
 | 
					                  (activity) => Card(
 | 
				
			||||||
 | 
					                    elevation: 0,
 | 
				
			||||||
 | 
					                    shape: RoundedRectangleBorder(
 | 
				
			||||||
 | 
					                      side: BorderSide(color: Colors.grey.shade300, width: 1),
 | 
				
			||||||
 | 
					                      borderRadius: BorderRadius.circular(8),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    margin: EdgeInsets.zero,
 | 
				
			||||||
 | 
					                    child: ListTile(
 | 
				
			||||||
 | 
					                      title: Text(
 | 
				
			||||||
 | 
					                        (activity.title?.isEmpty ?? true)
 | 
				
			||||||
 | 
					                            ? 'Untitled Activity'
 | 
				
			||||||
 | 
					                            : activity.title!,
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                      subtitle: Column(
 | 
				
			||||||
 | 
					                        crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
 | 
					                        children: [
 | 
				
			||||||
 | 
					                          Text(kPresenseActivityTypes[activity.type]).tr(),
 | 
				
			||||||
 | 
					                          StreamBuilder(
 | 
				
			||||||
 | 
					                            stream: Stream.periodic(const Duration(seconds: 1)),
 | 
				
			||||||
 | 
					                            builder: (context, snapshot) {
 | 
				
			||||||
 | 
					                              final duration = DateTime.now().difference(activity.createdAt);
 | 
				
			||||||
 | 
					                              final hours = duration.inHours.toString().padLeft(2, '0');
 | 
				
			||||||
 | 
					                              final minutes = (duration.inMinutes % 60).toString().padLeft(2, '0');
 | 
				
			||||||
 | 
					                              final seconds = (duration.inSeconds % 60).toString().padLeft(2, '0');
 | 
				
			||||||
 | 
					                              return Text('$hours:$minutes:$seconds').textColor(Colors.green);
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                          if (activity.subtitle?.isNotEmpty ?? false)
 | 
				
			||||||
 | 
					                            Text(activity.subtitle!),
 | 
				
			||||||
 | 
					                          if (activity.caption?.isNotEmpty ?? false)
 | 
				
			||||||
 | 
					                            Text(activity.caption!),
 | 
				
			||||||
 | 
					                        ],
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              ],
 | 
				
			||||||
 | 
					            ).padding(all: 8),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
      loading: () => const Center(child: CircularProgressIndicator()),
 | 
					      loading: () => const Center(child: CircularProgressIndicator()),
 | 
				
			||||||
      error:
 | 
					      error:
 | 
				
			||||||
          (error, stack) =>
 | 
					          (error, stack) =>
 | 
				
			||||||
              Center(child: Text('Error loading activities: $error')),
 | 
					              Center(child: Text('Error loading activities: $error')),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  Widget _buildActivitiesList(List<SnPresenceActivity> activities) {
 | 
					 | 
				
			||||||
    if (activities.isEmpty) {
 | 
					 | 
				
			||||||
      return const Center(child: Text('No active activities'));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ListView.builder(
 | 
					 | 
				
			||||||
      itemCount: activities.length,
 | 
					 | 
				
			||||||
      itemBuilder: (context, index) {
 | 
					 | 
				
			||||||
        final activity = activities[index];
 | 
					 | 
				
			||||||
        return Card(
 | 
					 | 
				
			||||||
          margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
 | 
					 | 
				
			||||||
          child: ListTile(
 | 
					 | 
				
			||||||
            title: Text(activity.title ?? 'Untitled Activity'),
 | 
					 | 
				
			||||||
            subtitle: Column(
 | 
					 | 
				
			||||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
					 | 
				
			||||||
              children: [
 | 
					 | 
				
			||||||
                Text('Type: ${activity.type}'),
 | 
					 | 
				
			||||||
                if (activity.subtitle != null) Text(activity.subtitle!),
 | 
					 | 
				
			||||||
                if (activity.caption != null) Text(activity.caption!),
 | 
					 | 
				
			||||||
                Text(
 | 
					 | 
				
			||||||
                  'Expires: ${activity.leaseExpiresAt.toLocal().toString()}',
 | 
					 | 
				
			||||||
                  style: const TextStyle(fontSize: 12),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            trailing: IconButton(
 | 
					 | 
				
			||||||
              icon: const Icon(Icons.delete),
 | 
					 | 
				
			||||||
              onPressed: () {
 | 
					 | 
				
			||||||
                // TODO: Implement delete functionality
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -296,7 +296,7 @@ class CheckInWidget extends HookConsumerWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CheckInActivityWidget extends StatelessWidget {
 | 
					class CheckInActivityWidget extends StatelessWidget {
 | 
				
			||||||
  final SnActivity item;
 | 
					  final SnTimelineEvent item;
 | 
				
			||||||
  const CheckInActivityWidget({super.key, required this.item});
 | 
					  const CheckInActivityWidget({super.key, required this.item});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user