✨ 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