From edf4ff1c5be0b77a3f38f48ecf6b6b8f6a665ae8 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sun, 25 May 2025 17:40:52 +0800 Subject: [PATCH] :bricks: Realtime call infra --- ios/Podfile.lock | 24 + .../xcshareddata/xcschemes/Runner.xcscheme | 2 + lib/models/chat.dart | 28 +- lib/models/chat.freezed.dart | 291 +++++++-- lib/models/chat.g.dart | 55 +- lib/pods/call.dart | 99 ++- lib/pods/call.g.dart | 2 +- lib/route.dart | 8 +- lib/route.gr.dart | 616 ++++++++++-------- lib/screens/account/me/event_calendar.dart | 295 +++++---- lib/screens/account/profile.dart | 7 + lib/screens/account/profile.g.dart | 2 +- lib/screens/account/relationship.dart | 3 +- lib/screens/auth/create_account.dart | 1 + lib/screens/auth/login.dart | 1 + lib/screens/chat/call.dart | 7 +- lib/screens/chat/room.dart | 8 +- lib/widgets/app_scaffold.dart | 39 +- lib/widgets/chat/call_button.dart | 112 ++++ lib/widgets/chat/call_button.g.dart | 151 +++++ lib/widgets/chat/call_overlay.dart | 53 ++ lib/widgets/chat/message_item.dart | 92 ++- lib/widgets/check_in.dart | 20 +- macos/Flutter/GeneratedPluginRegistrant.swift | 4 + macos/Podfile.lock | 24 + macos/Runner.xcodeproj/project.pbxproj | 8 - pubspec.lock | 56 ++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 6 + windows/flutter/generated_plugins.cmake | 2 + 30 files changed, 1454 insertions(+), 563 deletions(-) create mode 100644 lib/widgets/chat/call_button.dart create mode 100644 lib/widgets/chat/call_button.g.dart create mode 100644 lib/widgets/chat/call_overlay.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 69fe6ff..aaebbed 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - connectivity_plus (0.0.1): + - Flutter - croppy (0.0.1): - Flutter - device_info_plus (0.0.1): @@ -84,6 +86,9 @@ PODS: - flutter_udid (0.0.1): - Flutter - SAMKeychain + - flutter_webrtc (0.14.0): + - Flutter + - WebRTC-SDK (= 125.6422.07) - GoogleDataTransport (10.1.0): - nanopb (~> 3.30910.0) - PromisesObjC (~> 2.4) @@ -116,6 +121,10 @@ PODS: - irondash_engine_context (0.0.1): - Flutter - Kingfisher (8.3.2) + - livekit_client (2.4.7): + - Flutter + - flutter_webrtc + - WebRTC-SDK (= 125.6422.07) - media_kit_libs_ios_video (1.0.4): - Flutter - media_kit_video (0.0.1): @@ -173,8 +182,10 @@ PODS: - Flutter - wakelock_plus (0.0.1): - Flutter + - WebRTC-SDK (125.6422.07) DEPENDENCIES: + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - croppy (from `.symlinks/plugins/croppy/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) @@ -185,9 +196,11 @@ DEPENDENCIES: - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) - flutter_platform_alert (from `.symlinks/plugins/flutter_platform_alert/ios`) - flutter_udid (from `.symlinks/plugins/flutter_udid/ios`) + - flutter_webrtc (from `.symlinks/plugins/flutter_webrtc/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`) - Kingfisher (~> 8.0) + - livekit_client (from `.symlinks/plugins/livekit_client/ios`) - media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`) - media_kit_video (from `.symlinks/plugins/media_kit_video/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) @@ -219,8 +232,11 @@ SPEC REPOS: - SDWebImage - sqlite3 - SwiftyGif + - WebRTC-SDK EXTERNAL SOURCES: + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" croppy: :path: ".symlinks/plugins/croppy/ios" device_info_plus: @@ -241,10 +257,14 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_platform_alert/ios" flutter_udid: :path: ".symlinks/plugins/flutter_udid/ios" + flutter_webrtc: + :path: ".symlinks/plugins/flutter_webrtc/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" irondash_engine_context: :path: ".symlinks/plugins/irondash_engine_context/ios" + livekit_client: + :path: ".symlinks/plugins/livekit_client/ios" media_kit_libs_ios_video: :path: ".symlinks/plugins/media_kit_libs_ios_video/ios" media_kit_video: @@ -269,6 +289,7 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/wakelock_plus/ios" SPEC CHECKSUMS: + connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd croppy: 979e8ddc254f4642bffe7d52dc7193354b27ba30 device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c @@ -286,11 +307,13 @@ SPEC CHECKSUMS: flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf flutter_platform_alert: bf3b5fcd4ac14bd637e20527e9c471633071afd3 flutter_udid: f7c3884e6ec2951efe4f9de082257fc77c4d15e9 + flutter_webrtc: fd0d3bdef8766a0736dbbe2e5b7e85f1f3c52117 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486 Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5 + livekit_client: c30950bf36aa4c0244dd5551b1818cd15f90ba32 media_kit_libs_ios_video: 5a18affdb97d1f5d466dc79988b13eff6c5e2854 media_kit_video: 1746e198cb697d1ffb734b1d05ec429d1fcd1474 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 @@ -309,6 +332,7 @@ SPEC CHECKSUMS: url_launcher_ios: 694010445543906933d732453a59da0a173ae33d volume_controller: 3657a1f65bedb98fa41ff7dc5793537919f31b12 wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556 + WebRTC-SDK: dff00a3892bc570b6014e046297782084071657e PODFILE CHECKSUM: 4c3fad73fbbc9053a824d880097bda7884240991 diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 15cada4..e3773d4 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> meta, @@ -139,10 +140,35 @@ sealed class MessageSyncResponse with _$MessageSyncResponse { @freezed sealed class ChatRealtimeJoinResponse with _$ChatRealtimeJoinResponse { const factory ChatRealtimeJoinResponse({ + required String provider, + required String endpoint, required String token, - required Map config, + required String callId, + required String roomName, + required bool isAdmin, }) = _ChatRealtimeJoinResponse; factory ChatRealtimeJoinResponse.fromJson(Map json) => _$ChatRealtimeJoinResponseFromJson(json); } + +@freezed +sealed class SnRealtimeCall with _$SnRealtimeCall { + const factory SnRealtimeCall({ + required String id, + required DateTime createdAt, + required DateTime updatedAt, + required DateTime? deletedAt, + required DateTime? endedAt, + required String senderId, + required SnChatMember sender, + required String roomId, + required SnChatRoom room, + required Map upstreamConfig, + String? providerName, + String? sessionId, + }) = _SnRealtimeCall; + + factory SnRealtimeCall.fromJson(Map json) => + _$SnRealtimeCallFromJson(json); +} diff --git a/lib/models/chat.freezed.dart b/lib/models/chat.freezed.dart index ddfdf10..7df3096 100644 --- a/lib/models/chat.freezed.dart +++ b/lib/models/chat.freezed.dart @@ -271,7 +271,7 @@ $SnRealmCopyWith<$Res>? get realm { /// @nodoc mixin _$SnChatMessage { - DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String? get content; String? get nonce; Map get meta; List get membersMetioned; DateTime? get editedAt; List get attachments; List get reactions; String? get repliedMessageId; String? get forwardedMessageId; String get senderId; SnChatMember get sender; String get chatRoomId; + DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get type; String? get content; String? get nonce; Map get meta; List get membersMetioned; DateTime? get editedAt; List get attachments; List get reactions; String? get repliedMessageId; String? get forwardedMessageId; String get senderId; SnChatMember get sender; String get chatRoomId; /// Create a copy of SnChatMessage /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -284,16 +284,16 @@ $SnChatMessageCopyWith get copyWith => _$SnChatMessageCopyWithImp @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other.meta, meta)&&const DeepCollectionEquality().equals(other.membersMetioned, membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other.meta, meta)&&const DeepCollectionEquality().equals(other.membersMetioned, membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,content,nonce,const DeepCollectionEquality().hash(meta),const DeepCollectionEquality().hash(membersMetioned),editedAt,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId); +int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(meta),const DeepCollectionEquality().hash(membersMetioned),editedAt,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId); @override String toString() { - return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)'; + return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)'; } @@ -304,7 +304,7 @@ abstract mixin class $SnChatMessageCopyWith<$Res> { factory $SnChatMessageCopyWith(SnChatMessage value, $Res Function(SnChatMessage) _then) = _$SnChatMessageCopyWithImpl; @useResult $Res call({ - DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String? content, String? nonce, Map meta, List membersMetioned, DateTime? editedAt, List attachments, List reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId + DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map meta, List membersMetioned, DateTime? editedAt, List attachments, List reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId }); @@ -321,12 +321,13 @@ class _$SnChatMessageCopyWithImpl<$Res> /// Create a copy of SnChatMessage /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) { return _then(_self.copyWith( createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable as DateTime?,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,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable as String?,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable @@ -359,13 +360,14 @@ $SnChatMemberCopyWith<$Res> get sender { @JsonSerializable() class _SnChatMessage implements SnChatMessage { - const _SnChatMessage({required this.createdAt, required this.updatedAt, this.deletedAt, required this.id, this.content, this.nonce, final Map meta = const {}, final List membersMetioned = const [], this.editedAt, final List attachments = const [], final List reactions = const [], this.repliedMessageId, this.forwardedMessageId, required this.senderId, required this.sender, required this.chatRoomId}): _meta = meta,_membersMetioned = membersMetioned,_attachments = attachments,_reactions = reactions; + const _SnChatMessage({required this.createdAt, required this.updatedAt, this.deletedAt, required this.id, this.type = 'text', this.content, this.nonce, final Map meta = const {}, final List membersMetioned = const [], this.editedAt, final List attachments = const [], final List reactions = const [], this.repliedMessageId, this.forwardedMessageId, required this.senderId, required this.sender, required this.chatRoomId}): _meta = meta,_membersMetioned = membersMetioned,_attachments = attachments,_reactions = reactions; factory _SnChatMessage.fromJson(Map json) => _$SnChatMessageFromJson(json); @override final DateTime createdAt; @override final DateTime updatedAt; @override final DateTime? deletedAt; @override final String id; +@override@JsonKey() final String type; @override final String? content; @override final String? nonce; final Map _meta; @@ -416,16 +418,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other._meta, _meta)&&const DeepCollectionEquality().equals(other._membersMetioned, _membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.type, type) || other.type == type)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other._meta, _meta)&&const DeepCollectionEquality().equals(other._membersMetioned, _membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,content,nonce,const DeepCollectionEquality().hash(_meta),const DeepCollectionEquality().hash(_membersMetioned),editedAt,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId); +int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,type,content,nonce,const DeepCollectionEquality().hash(_meta),const DeepCollectionEquality().hash(_membersMetioned),editedAt,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactions),repliedMessageId,forwardedMessageId,senderId,sender,chatRoomId); @override String toString() { - return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)'; + return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, type: $type, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, forwardedMessageId: $forwardedMessageId, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)'; } @@ -436,7 +438,7 @@ abstract mixin class _$SnChatMessageCopyWith<$Res> implements $SnChatMessageCopy factory _$SnChatMessageCopyWith(_SnChatMessage value, $Res Function(_SnChatMessage) _then) = __$SnChatMessageCopyWithImpl; @override @useResult $Res call({ - DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String? content, String? nonce, Map meta, List membersMetioned, DateTime? editedAt, List attachments, List reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId + DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String type, String? content, String? nonce, Map meta, List membersMetioned, DateTime? editedAt, List attachments, List reactions, String? repliedMessageId, String? forwardedMessageId, String senderId, SnChatMember sender, String chatRoomId }); @@ -453,12 +455,13 @@ class __$SnChatMessageCopyWithImpl<$Res> /// Create a copy of SnChatMessage /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? type = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? forwardedMessageId = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) { return _then(_SnChatMessage( createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable as DateTime?,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,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable as String?,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable @@ -1339,7 +1342,7 @@ as DateTime, /// @nodoc mixin _$ChatRealtimeJoinResponse { - String get token; Map get config; + String get provider; String get endpoint; String get token; String get callId; String get roomName; bool get isAdmin; /// Create a copy of ChatRealtimeJoinResponse /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -1352,16 +1355,16 @@ $ChatRealtimeJoinResponseCopyWith get copyWith => _$Ch @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is ChatRealtimeJoinResponse&&(identical(other.token, token) || other.token == token)&&const DeepCollectionEquality().equals(other.config, config)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is ChatRealtimeJoinResponse&&(identical(other.provider, provider) || other.provider == provider)&&(identical(other.endpoint, endpoint) || other.endpoint == endpoint)&&(identical(other.token, token) || other.token == token)&&(identical(other.callId, callId) || other.callId == callId)&&(identical(other.roomName, roomName) || other.roomName == roomName)&&(identical(other.isAdmin, isAdmin) || other.isAdmin == isAdmin)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,token,const DeepCollectionEquality().hash(config)); +int get hashCode => Object.hash(runtimeType,provider,endpoint,token,callId,roomName,isAdmin); @override String toString() { - return 'ChatRealtimeJoinResponse(token: $token, config: $config)'; + return 'ChatRealtimeJoinResponse(provider: $provider, endpoint: $endpoint, token: $token, callId: $callId, roomName: $roomName, isAdmin: $isAdmin)'; } @@ -1372,7 +1375,7 @@ abstract mixin class $ChatRealtimeJoinResponseCopyWith<$Res> { factory $ChatRealtimeJoinResponseCopyWith(ChatRealtimeJoinResponse value, $Res Function(ChatRealtimeJoinResponse) _then) = _$ChatRealtimeJoinResponseCopyWithImpl; @useResult $Res call({ - String token, Map config + String provider, String endpoint, String token, String callId, String roomName, bool isAdmin }); @@ -1389,11 +1392,15 @@ class _$ChatRealtimeJoinResponseCopyWithImpl<$Res> /// Create a copy of ChatRealtimeJoinResponse /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? token = null,Object? config = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? provider = null,Object? endpoint = null,Object? token = null,Object? callId = null,Object? roomName = null,Object? isAdmin = null,}) { return _then(_self.copyWith( -token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable -as String,config: null == config ? _self.config : config // ignore: cast_nullable_to_non_nullable -as Map, +provider: null == provider ? _self.provider : provider // ignore: cast_nullable_to_non_nullable +as String,endpoint: null == endpoint ? _self.endpoint : endpoint // ignore: cast_nullable_to_non_nullable +as String,token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable +as String,callId: null == callId ? _self.callId : callId // ignore: cast_nullable_to_non_nullable +as String,roomName: null == roomName ? _self.roomName : roomName // ignore: cast_nullable_to_non_nullable +as String,isAdmin: null == isAdmin ? _self.isAdmin : isAdmin // ignore: cast_nullable_to_non_nullable +as bool, )); } @@ -1404,17 +1411,15 @@ as Map, @JsonSerializable() class _ChatRealtimeJoinResponse implements ChatRealtimeJoinResponse { - const _ChatRealtimeJoinResponse({required this.token, required final Map config}): _config = config; + const _ChatRealtimeJoinResponse({required this.provider, required this.endpoint, required this.token, required this.callId, required this.roomName, required this.isAdmin}); factory _ChatRealtimeJoinResponse.fromJson(Map json) => _$ChatRealtimeJoinResponseFromJson(json); +@override final String provider; +@override final String endpoint; @override final String token; - final Map _config; -@override Map get config { - if (_config is EqualUnmodifiableMapView) return _config; - // ignore: implicit_dynamic_type - return EqualUnmodifiableMapView(_config); -} - +@override final String callId; +@override final String roomName; +@override final bool isAdmin; /// Create a copy of ChatRealtimeJoinResponse /// with the given fields replaced by the non-null parameter values. @@ -1429,16 +1434,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _ChatRealtimeJoinResponse&&(identical(other.token, token) || other.token == token)&&const DeepCollectionEquality().equals(other._config, _config)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ChatRealtimeJoinResponse&&(identical(other.provider, provider) || other.provider == provider)&&(identical(other.endpoint, endpoint) || other.endpoint == endpoint)&&(identical(other.token, token) || other.token == token)&&(identical(other.callId, callId) || other.callId == callId)&&(identical(other.roomName, roomName) || other.roomName == roomName)&&(identical(other.isAdmin, isAdmin) || other.isAdmin == isAdmin)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,token,const DeepCollectionEquality().hash(_config)); +int get hashCode => Object.hash(runtimeType,provider,endpoint,token,callId,roomName,isAdmin); @override String toString() { - return 'ChatRealtimeJoinResponse(token: $token, config: $config)'; + return 'ChatRealtimeJoinResponse(provider: $provider, endpoint: $endpoint, token: $token, callId: $callId, roomName: $roomName, isAdmin: $isAdmin)'; } @@ -1449,7 +1454,7 @@ abstract mixin class _$ChatRealtimeJoinResponseCopyWith<$Res> implements $ChatRe factory _$ChatRealtimeJoinResponseCopyWith(_ChatRealtimeJoinResponse value, $Res Function(_ChatRealtimeJoinResponse) _then) = __$ChatRealtimeJoinResponseCopyWithImpl; @override @useResult $Res call({ - String token, Map config + String provider, String endpoint, String token, String callId, String roomName, bool isAdmin }); @@ -1466,15 +1471,227 @@ class __$ChatRealtimeJoinResponseCopyWithImpl<$Res> /// Create a copy of ChatRealtimeJoinResponse /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? token = null,Object? config = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? provider = null,Object? endpoint = null,Object? token = null,Object? callId = null,Object? roomName = null,Object? isAdmin = null,}) { return _then(_ChatRealtimeJoinResponse( -token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable -as String,config: null == config ? _self._config : config // ignore: cast_nullable_to_non_nullable -as Map, +provider: null == provider ? _self.provider : provider // ignore: cast_nullable_to_non_nullable +as String,endpoint: null == endpoint ? _self.endpoint : endpoint // ignore: cast_nullable_to_non_nullable +as String,token: null == token ? _self.token : token // ignore: cast_nullable_to_non_nullable +as String,callId: null == callId ? _self.callId : callId // ignore: cast_nullable_to_non_nullable +as String,roomName: null == roomName ? _self.roomName : roomName // ignore: cast_nullable_to_non_nullable +as String,isAdmin: null == isAdmin ? _self.isAdmin : isAdmin // ignore: cast_nullable_to_non_nullable +as bool, )); } } + +/// @nodoc +mixin _$SnRealtimeCall { + + String get id; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; DateTime? get endedAt; String get senderId; SnChatMember get sender; String get roomId; SnChatRoom get room; Map get upstreamConfig; String? get providerName; String? get sessionId; +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$SnRealtimeCallCopyWith get copyWith => _$SnRealtimeCallCopyWithImpl(this as SnRealtimeCall, _$identity); + + /// Serializes this SnRealtimeCall to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is SnRealtimeCall&&(identical(other.id, id) || other.id == id)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.roomId, roomId) || other.roomId == roomId)&&(identical(other.room, room) || other.room == room)&&const DeepCollectionEquality().equals(other.upstreamConfig, upstreamConfig)&&(identical(other.providerName, providerName) || other.providerName == providerName)&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,createdAt,updatedAt,deletedAt,endedAt,senderId,sender,roomId,room,const DeepCollectionEquality().hash(upstreamConfig),providerName,sessionId); + +@override +String toString() { + return 'SnRealtimeCall(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, endedAt: $endedAt, senderId: $senderId, sender: $sender, roomId: $roomId, room: $room, upstreamConfig: $upstreamConfig, providerName: $providerName, sessionId: $sessionId)'; +} + + +} + +/// @nodoc +abstract mixin class $SnRealtimeCallCopyWith<$Res> { + factory $SnRealtimeCallCopyWith(SnRealtimeCall value, $Res Function(SnRealtimeCall) _then) = _$SnRealtimeCallCopyWithImpl; +@useResult +$Res call({ + String id, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, DateTime? endedAt, String senderId, SnChatMember sender, String roomId, SnChatRoom room, Map upstreamConfig, String? providerName, String? sessionId +}); + + +$SnChatMemberCopyWith<$Res> get sender;$SnChatRoomCopyWith<$Res> get room; + +} +/// @nodoc +class _$SnRealtimeCallCopyWithImpl<$Res> + implements $SnRealtimeCallCopyWith<$Res> { + _$SnRealtimeCallCopyWithImpl(this._self, this._then); + + final SnRealtimeCall _self; + final $Res Function(SnRealtimeCall) _then; + +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? endedAt = freezed,Object? senderId = null,Object? sender = null,Object? roomId = null,Object? room = null,Object? upstreamConfig = null,Object? providerName = freezed,Object? sessionId = freezed,}) { + return _then(_self.copyWith( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable +as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable +as SnChatMember,roomId: null == roomId ? _self.roomId : roomId // ignore: cast_nullable_to_non_nullable +as String,room: null == room ? _self.room : room // ignore: cast_nullable_to_non_nullable +as SnChatRoom,upstreamConfig: null == upstreamConfig ? _self.upstreamConfig : upstreamConfig // ignore: cast_nullable_to_non_nullable +as Map,providerName: freezed == providerName ? _self.providerName : providerName // ignore: cast_nullable_to_non_nullable +as String?,sessionId: freezed == sessionId ? _self.sessionId : sessionId // ignore: cast_nullable_to_non_nullable +as String?, + )); +} +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnChatMemberCopyWith<$Res> get sender { + + return $SnChatMemberCopyWith<$Res>(_self.sender, (value) { + return _then(_self.copyWith(sender: value)); + }); +}/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnChatRoomCopyWith<$Res> get room { + + return $SnChatRoomCopyWith<$Res>(_self.room, (value) { + return _then(_self.copyWith(room: value)); + }); +} +} + + +/// @nodoc +@JsonSerializable() + +class _SnRealtimeCall implements SnRealtimeCall { + const _SnRealtimeCall({required this.id, required this.createdAt, required this.updatedAt, required this.deletedAt, required this.endedAt, required this.senderId, required this.sender, required this.roomId, required this.room, required final Map upstreamConfig, this.providerName, this.sessionId}): _upstreamConfig = upstreamConfig; + factory _SnRealtimeCall.fromJson(Map json) => _$SnRealtimeCallFromJson(json); + +@override final String id; +@override final DateTime createdAt; +@override final DateTime updatedAt; +@override final DateTime? deletedAt; +@override final DateTime? endedAt; +@override final String senderId; +@override final SnChatMember sender; +@override final String roomId; +@override final SnChatRoom room; + final Map _upstreamConfig; +@override Map get upstreamConfig { + if (_upstreamConfig is EqualUnmodifiableMapView) return _upstreamConfig; + // ignore: implicit_dynamic_type + return EqualUnmodifiableMapView(_upstreamConfig); +} + +@override final String? providerName; +@override final String? sessionId; + +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$SnRealtimeCallCopyWith<_SnRealtimeCall> get copyWith => __$SnRealtimeCallCopyWithImpl<_SnRealtimeCall>(this, _$identity); + +@override +Map toJson() { + return _$SnRealtimeCallToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnRealtimeCall&&(identical(other.id, id) || other.id == id)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.endedAt, endedAt) || other.endedAt == endedAt)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.roomId, roomId) || other.roomId == roomId)&&(identical(other.room, room) || other.room == room)&&const DeepCollectionEquality().equals(other._upstreamConfig, _upstreamConfig)&&(identical(other.providerName, providerName) || other.providerName == providerName)&&(identical(other.sessionId, sessionId) || other.sessionId == sessionId)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,createdAt,updatedAt,deletedAt,endedAt,senderId,sender,roomId,room,const DeepCollectionEquality().hash(_upstreamConfig),providerName,sessionId); + +@override +String toString() { + return 'SnRealtimeCall(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, endedAt: $endedAt, senderId: $senderId, sender: $sender, roomId: $roomId, room: $room, upstreamConfig: $upstreamConfig, providerName: $providerName, sessionId: $sessionId)'; +} + + +} + +/// @nodoc +abstract mixin class _$SnRealtimeCallCopyWith<$Res> implements $SnRealtimeCallCopyWith<$Res> { + factory _$SnRealtimeCallCopyWith(_SnRealtimeCall value, $Res Function(_SnRealtimeCall) _then) = __$SnRealtimeCallCopyWithImpl; +@override @useResult +$Res call({ + String id, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, DateTime? endedAt, String senderId, SnChatMember sender, String roomId, SnChatRoom room, Map upstreamConfig, String? providerName, String? sessionId +}); + + +@override $SnChatMemberCopyWith<$Res> get sender;@override $SnChatRoomCopyWith<$Res> get room; + +} +/// @nodoc +class __$SnRealtimeCallCopyWithImpl<$Res> + implements _$SnRealtimeCallCopyWith<$Res> { + __$SnRealtimeCallCopyWithImpl(this._self, this._then); + + final _SnRealtimeCall _self; + final $Res Function(_SnRealtimeCall) _then; + +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? endedAt = freezed,Object? senderId = null,Object? sender = null,Object? roomId = null,Object? room = null,Object? upstreamConfig = null,Object? providerName = freezed,Object? sessionId = freezed,}) { + return _then(_SnRealtimeCall( +id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as String,createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable +as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable +as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,endedAt: freezed == endedAt ? _self.endedAt : endedAt // ignore: cast_nullable_to_non_nullable +as DateTime?,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable +as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable +as SnChatMember,roomId: null == roomId ? _self.roomId : roomId // ignore: cast_nullable_to_non_nullable +as String,room: null == room ? _self.room : room // ignore: cast_nullable_to_non_nullable +as SnChatRoom,upstreamConfig: null == upstreamConfig ? _self._upstreamConfig : upstreamConfig // ignore: cast_nullable_to_non_nullable +as Map,providerName: freezed == providerName ? _self.providerName : providerName // ignore: cast_nullable_to_non_nullable +as String?,sessionId: freezed == sessionId ? _self.sessionId : sessionId // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnChatMemberCopyWith<$Res> get sender { + + return $SnChatMemberCopyWith<$Res>(_self.sender, (value) { + return _then(_self.copyWith(sender: value)); + }); +}/// Create a copy of SnRealtimeCall +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$SnChatRoomCopyWith<$Res> get room { + + return $SnChatRoomCopyWith<$Res>(_self.room, (value) { + return _then(_self.copyWith(room: value)); + }); +} +} + // dart format on diff --git a/lib/models/chat.g.dart b/lib/models/chat.g.dart index 4498aa9..b8ef225 100644 --- a/lib/models/chat.g.dart +++ b/lib/models/chat.g.dart @@ -67,6 +67,7 @@ _SnChatMessage _$SnChatMessageFromJson(Map json) => ? null : DateTime.parse(json['deleted_at'] as String), id: json['id'] as String, + type: json['type'] as String? ?? 'text', content: json['content'] as String?, nonce: json['nonce'] as String?, meta: json['meta'] as Map? ?? const {}, @@ -102,6 +103,7 @@ Map _$SnChatMessageToJson(_SnChatMessage instance) => 'updated_at': instance.updatedAt.toIso8601String(), 'deleted_at': instance.deletedAt?.toIso8601String(), 'id': instance.id, + 'type': instance.type, 'content': instance.content, 'nonce': instance.nonce, 'meta': instance.meta, @@ -241,10 +243,59 @@ Map _$MessageSyncResponseToJson( _ChatRealtimeJoinResponse _$ChatRealtimeJoinResponseFromJson( Map json, ) => _ChatRealtimeJoinResponse( + provider: json['provider'] as String, + endpoint: json['endpoint'] as String, token: json['token'] as String, - config: json['config'] as Map, + callId: json['call_id'] as String, + roomName: json['room_name'] as String, + isAdmin: json['is_admin'] as bool, ); Map _$ChatRealtimeJoinResponseToJson( _ChatRealtimeJoinResponse instance, -) => {'token': instance.token, 'config': instance.config}; +) => { + 'provider': instance.provider, + 'endpoint': instance.endpoint, + 'token': instance.token, + 'call_id': instance.callId, + 'room_name': instance.roomName, + 'is_admin': instance.isAdmin, +}; + +_SnRealtimeCall _$SnRealtimeCallFromJson(Map json) => + _SnRealtimeCall( + id: json['id'] as String, + createdAt: DateTime.parse(json['created_at'] as String), + updatedAt: DateTime.parse(json['updated_at'] as String), + deletedAt: + json['deleted_at'] == null + ? null + : DateTime.parse(json['deleted_at'] as String), + endedAt: + json['ended_at'] == null + ? null + : DateTime.parse(json['ended_at'] as String), + senderId: json['sender_id'] as String, + sender: SnChatMember.fromJson(json['sender'] as Map), + roomId: json['room_id'] as String, + room: SnChatRoom.fromJson(json['room'] as Map), + upstreamConfig: json['upstream_config'] as Map, + providerName: json['provider_name'] as String?, + sessionId: json['session_id'] as String?, + ); + +Map _$SnRealtimeCallToJson(_SnRealtimeCall instance) => + { + 'id': instance.id, + 'created_at': instance.createdAt.toIso8601String(), + 'updated_at': instance.updatedAt.toIso8601String(), + 'deleted_at': instance.deletedAt?.toIso8601String(), + 'ended_at': instance.endedAt?.toIso8601String(), + 'sender_id': instance.senderId, + 'sender': instance.sender.toJson(), + 'room_id': instance.roomId, + 'room': instance.room.toJson(), + 'upstream_config': instance.upstreamConfig, + 'provider_name': instance.providerName, + 'session_id': instance.sessionId, + }; diff --git a/lib/pods/call.dart b/lib/pods/call.dart index 4ff95ec..b8ba3df 100644 --- a/lib/pods/call.dart +++ b/lib/pods/call.dart @@ -1,7 +1,6 @@ -import 'package:flutter_webrtc/flutter_webrtc.dart'; +import 'package:livekit_client/livekit_client.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:dio/dio.dart'; import 'package:island/pods/network.dart'; part 'call.g.dart'; @@ -18,61 +17,40 @@ sealed class CallState with _$CallState { @riverpod class CallNotifier extends _$CallNotifier { - RTCPeerConnection? _peerConnection; - MediaStream? _localStream; - final _localRenderer = RTCVideoRenderer(); + Room? _room; + LocalParticipant? _localParticipant; + LocalAudioTrack? _localAudioTrack; @override CallState build() { return const CallState(isMuted: false, isConnected: false); } - Future initialize() async { - try { - await _localRenderer.initialize(); - - // Get user media (audio) - _localStream = await navigator.mediaDevices.getUserMedia({ - 'audio': true, - 'video': false, - }); - - // Create peer connection - _peerConnection = await createPeerConnection({ - 'iceServers': [ - {'urls': 'stun:stun.l.google.com:19302'}, - // Add your Cloudflare TURN servers here - ], - }); - - // Add local stream to peer connection - _localStream!.getTracks().forEach((track) { - _peerConnection!.addTrack(track, _localStream!); - }); - - // Handle incoming tracks - _peerConnection!.onTrack = (RTCTrackEvent event) { - if (event.track.kind == 'audio') { - // Handle remote audio track - } - }; - - state = state.copyWith(isConnected: true); - } catch (e) { - state = state.copyWith(error: e.toString()); - } - } - - Future createSession() async { + Future joinRoom(String roomId) async { try { final apiClient = ref.read(apiClientProvider); - final response = await apiClient.post( - 'YOUR_CLOUDFLARE_CALLS_ENDPOINT/sessions', - options: Options(headers: {'Content-Type': 'application/json'}), - ); + final response = await apiClient.get('/chat/realtime/$roomId/join'); + if (response.statusCode == 200 && response.data != null) { + final data = response.data; + final String endpoint = data['endpoint']; + final String token = data['token']; + // Connect to LiveKit + _room = Room(); + await _room!.connect(endpoint, token); + _localParticipant = _room!.localParticipant; + // Create local audio track and publish + _localAudioTrack = await LocalAudioTrack.create(); + await _localParticipant!.publishAudioTrack(_localAudioTrack!); - if (response.statusCode == 200) { - // Handle session creation + // Listen for connection updates + _room!.addListener(() { + state = state.copyWith( + isConnected: _room!.connectionState == ConnectionState.connected, + ); + }); + state = state.copyWith(isConnected: true); + } else { + state = state.copyWith(error: 'Failed to join room'); } } catch (e) { state = state.copyWith(error: e.toString()); @@ -80,15 +58,26 @@ class CallNotifier extends _$CallNotifier { } void toggleMute() { - state = state.copyWith(isMuted: !state.isMuted); - _localStream?.getAudioTracks().forEach((track) { - track.enabled = !state.isMuted; - }); + final newMuted = !state.isMuted; + state = state.copyWith(isMuted: newMuted); + if (_localAudioTrack != null) { + if (newMuted) { + _localAudioTrack!.mute(); + } else { + _localAudioTrack!.unmute(); + } + } + } + + Future disconnect() async { + if (_room != null) { + await _room!.disconnect(); + state = state.copyWith(isConnected: false); + } } void dispose() { - _localStream?.dispose(); - _peerConnection?.dispose(); - _localRenderer.dispose(); + _localAudioTrack?.dispose(); + _room?.dispose(); } } diff --git a/lib/pods/call.g.dart b/lib/pods/call.g.dart index baf747f..2c2c3c0 100644 --- a/lib/pods/call.g.dart +++ b/lib/pods/call.g.dart @@ -6,7 +6,7 @@ part of 'call.dart'; // RiverpodGenerator // ************************************************************************** -String _$callNotifierHash() => r'a910dfa778c42888f8b8e5ab199b25ce8a74392b'; +String _$callNotifierHash() => r'c39e8d88673113bde0b14eb16cd9d86fa549e42c'; /// See also [CallNotifier]. @ProviderFor(CallNotifier) diff --git a/lib/route.dart b/lib/route.dart index 78e612d..25cbe08 100644 --- a/lib/route.dart +++ b/lib/route.dart @@ -8,15 +8,15 @@ class AppRouter extends RootStackRouter { @override List get routes => [ - RedirectRoute(path: '/', redirectTo: '/explore'), AutoRoute( page: ExploreShellRoute.page, - path: '/explore', + path: '/', children: [ AutoRoute(page: ExploreRoute.page, path: ''), AutoRoute(page: PostComposeRoute.page, path: 'posts/compose'), AutoRoute(page: PostDetailRoute.page, path: 'posts/:id'), AutoRoute(page: PostEditRoute.page, path: 'posts/:id/edit'), + AutoRoute(page: PublisherProfileRoute.page, path: 'publishers/:name'), ], ), AutoRoute( @@ -28,12 +28,11 @@ class AppRouter extends RootStackRouter { AutoRoute(page: WalletRoute.page, path: 'wallet'), AutoRoute(page: RelationshipRoute.page, path: 'relationships'), AutoRoute(page: AccountProfileRoute.page, path: ':name'), - AutoRoute(page: PublisherProfileRoute.page, path: ':name/calendar'), - AutoRoute(page: MyselfEventCalendarRoute.page, path: 'me/calendar'), AutoRoute(page: UpdateProfileRoute.page, path: 'me/update'), AutoRoute(page: AccountSettingsRoute.page, path: 'settings'), ], ), + AutoRoute(page: EventCalanderRoute.page, path: '/account/:name/calendar'), AutoRoute(page: RealmListRoute.page, path: '/realms'), AutoRoute( page: ChatShellRoute.page, @@ -41,6 +40,7 @@ class AppRouter extends RootStackRouter { children: [ AutoRoute(page: ChatListRoute.page, path: ''), AutoRoute(page: ChatRoomRoute.page, path: ':id'), + AutoRoute(page: CallRoute.page, path: ':id/call'), AutoRoute(page: NewChatRoute.page, path: 'new'), AutoRoute(page: EditChatRoute.page, path: ':id/edit'), AutoRoute(page: ChatDetailRoute.page, path: ':id/detail'), diff --git a/lib/route.gr.dart b/lib/route.gr.dart index 37d873d..4ff5bbd 100644 --- a/lib/route.gr.dart +++ b/lib/route.gr.dart @@ -9,44 +9,45 @@ // coverage:ignore-file // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:auto_route/auto_route.dart' as _i26; -import 'package:flutter/foundation.dart' as _i28; -import 'package:flutter/material.dart' as _i27; -import 'package:island/models/post.dart' as _i29; -import 'package:island/route.dart' as _i30; +import 'package:auto_route/auto_route.dart' as _i27; +import 'package:flutter/foundation.dart' as _i29; +import 'package:flutter/material.dart' as _i28; +import 'package:island/models/post.dart' as _i30; +import 'package:island/route.dart' as _i31; import 'package:island/screens/account.dart' as _i2; -import 'package:island/screens/account/me/event_calendar.dart' as _i15; +import 'package:island/screens/account/me/event_calendar.dart' as _i14; import 'package:island/screens/account/me/settings.dart' as _i3; -import 'package:island/screens/account/me/update.dart' as _i24; +import 'package:island/screens/account/me/update.dart' as _i25; import 'package:island/screens/account/profile.dart' as _i1; -import 'package:island/screens/account/relationship.dart' as _i21; -import 'package:island/screens/auth/create_account.dart' as _i7; -import 'package:island/screens/auth/login.dart' as _i14; -import 'package:island/screens/auth/tabs.dart' as _i23; -import 'package:island/screens/chat/chat.dart' as _i5; -import 'package:island/screens/chat/room.dart' as _i6; -import 'package:island/screens/chat/room_detail.dart' as _i4; -import 'package:island/screens/creators/hub.dart' as _i8; -import 'package:island/screens/creators/publishers.dart' as _i9; -import 'package:island/screens/creators/stickers/pack_detail.dart' as _i12; -import 'package:island/screens/creators/stickers/stickers.dart' as _i11; -import 'package:island/screens/explore.dart' as _i13; -import 'package:island/screens/notification.dart' as _i16; -import 'package:island/screens/posts/compose.dart' as _i17; -import 'package:island/screens/posts/detail.dart' as _i18; -import 'package:island/screens/posts/pub_profile.dart' as _i19; -import 'package:island/screens/realm/detail.dart' as _i20; -import 'package:island/screens/realm/realms.dart' as _i10; -import 'package:island/screens/settings.dart' as _i22; -import 'package:island/screens/wallet.dart' as _i25; +import 'package:island/screens/account/relationship.dart' as _i22; +import 'package:island/screens/auth/create_account.dart' as _i8; +import 'package:island/screens/auth/login.dart' as _i16; +import 'package:island/screens/auth/tabs.dart' as _i24; +import 'package:island/screens/chat/call.dart' as _i4; +import 'package:island/screens/chat/chat.dart' as _i6; +import 'package:island/screens/chat/room.dart' as _i7; +import 'package:island/screens/chat/room_detail.dart' as _i5; +import 'package:island/screens/creators/hub.dart' as _i9; +import 'package:island/screens/creators/publishers.dart' as _i10; +import 'package:island/screens/creators/stickers/pack_detail.dart' as _i13; +import 'package:island/screens/creators/stickers/stickers.dart' as _i12; +import 'package:island/screens/explore.dart' as _i15; +import 'package:island/screens/notification.dart' as _i17; +import 'package:island/screens/posts/compose.dart' as _i18; +import 'package:island/screens/posts/detail.dart' as _i19; +import 'package:island/screens/posts/pub_profile.dart' as _i20; +import 'package:island/screens/realm/detail.dart' as _i21; +import 'package:island/screens/realm/realms.dart' as _i11; +import 'package:island/screens/settings.dart' as _i23; +import 'package:island/screens/wallet.dart' as _i26; /// generated route for /// [_i1.AccountProfileScreen] -class AccountProfileRoute extends _i26.PageRouteInfo { +class AccountProfileRoute extends _i27.PageRouteInfo { AccountProfileRoute({ - _i27.Key? key, + _i28.Key? key, required String name, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( AccountProfileRoute.name, args: AccountProfileRouteArgs(key: key, name: name), @@ -56,7 +57,7 @@ class AccountProfileRoute extends _i26.PageRouteInfo { static const String name = 'AccountProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -72,7 +73,7 @@ class AccountProfileRoute extends _i26.PageRouteInfo { class AccountProfileRouteArgs { const AccountProfileRouteArgs({this.key, required this.name}); - final _i27.Key? key; + final _i28.Key? key; final String name; @@ -84,11 +85,11 @@ class AccountProfileRouteArgs { /// generated route for /// [_i2.AccountScreen] -class AccountRoute extends _i26.PageRouteInfo { +class AccountRoute extends _i27.PageRouteInfo { AccountRoute({ - _i28.Key? key, + _i29.Key? key, bool isAside = false, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( AccountRoute.name, args: AccountRouteArgs(key: key, isAside: isAside), @@ -97,7 +98,7 @@ class AccountRoute extends _i26.PageRouteInfo { static const String name = 'AccountRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs( @@ -111,7 +112,7 @@ class AccountRoute extends _i26.PageRouteInfo { class AccountRouteArgs { const AccountRouteArgs({this.key, this.isAside = false}); - final _i28.Key? key; + final _i29.Key? key; final bool isAside; @@ -123,13 +124,13 @@ class AccountRouteArgs { /// generated route for /// [_i3.AccountSettingsScreen] -class AccountSettingsRoute extends _i26.PageRouteInfo { - const AccountSettingsRoute({List<_i26.PageRouteInfo>? children}) +class AccountSettingsRoute extends _i27.PageRouteInfo { + const AccountSettingsRoute({List<_i27.PageRouteInfo>? children}) : super(AccountSettingsRoute.name, initialChildren: children); static const String name = 'AccountSettingsRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { return const _i3.AccountSettingsScreen(); @@ -139,13 +140,13 @@ class AccountSettingsRoute extends _i26.PageRouteInfo { /// generated route for /// [_i2.AccountShellScreen] -class AccountShellRoute extends _i26.PageRouteInfo { - const AccountShellRoute({List<_i26.PageRouteInfo>? children}) +class AccountShellRoute extends _i27.PageRouteInfo { + const AccountShellRoute({List<_i27.PageRouteInfo>? children}) : super(AccountShellRoute.name, initialChildren: children); static const String name = 'AccountShellRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { return const _i2.AccountShellScreen(); @@ -154,12 +155,53 @@ class AccountShellRoute extends _i26.PageRouteInfo { } /// generated route for -/// [_i4.ChatDetailScreen] -class ChatDetailRoute extends _i26.PageRouteInfo { +/// [_i4.CallScreen] +class CallRoute extends _i27.PageRouteInfo { + CallRoute({ + _i28.Key? key, + required String roomId, + List<_i27.PageRouteInfo>? children, + }) : super( + CallRoute.name, + args: CallRouteArgs(key: key, roomId: roomId), + rawPathParams: {'id': roomId}, + initialChildren: children, + ); + + static const String name = 'CallRoute'; + + static _i27.PageInfo page = _i27.PageInfo( + name, + builder: (data) { + final pathParams = data.inheritedPathParams; + final args = data.argsAs( + orElse: () => CallRouteArgs(roomId: pathParams.getString('id')), + ); + return _i4.CallScreen(key: args.key, roomId: args.roomId); + }, + ); +} + +class CallRouteArgs { + const CallRouteArgs({this.key, required this.roomId}); + + final _i28.Key? key; + + final String roomId; + + @override + String toString() { + return 'CallRouteArgs{key: $key, roomId: $roomId}'; + } +} + +/// generated route for +/// [_i5.ChatDetailScreen] +class ChatDetailRoute extends _i27.PageRouteInfo { ChatDetailRoute({ - _i27.Key? key, + _i28.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( ChatDetailRoute.name, args: ChatDetailRouteArgs(key: key, id: id), @@ -169,14 +211,14 @@ class ChatDetailRoute extends _i26.PageRouteInfo { static const String name = 'ChatDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => ChatDetailRouteArgs(id: pathParams.getString('id')), ); - return _i4.ChatDetailScreen(key: args.key, id: args.id); + return _i5.ChatDetailScreen(key: args.key, id: args.id); }, ); } @@ -184,7 +226,7 @@ class ChatDetailRoute extends _i26.PageRouteInfo { class ChatDetailRouteArgs { const ChatDetailRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i28.Key? key; final String id; @@ -195,12 +237,12 @@ class ChatDetailRouteArgs { } /// generated route for -/// [_i5.ChatListScreen] -class ChatListRoute extends _i26.PageRouteInfo { +/// [_i6.ChatListScreen] +class ChatListRoute extends _i27.PageRouteInfo { ChatListRoute({ - _i27.Key? key, + _i28.Key? key, bool isAside = false, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( ChatListRoute.name, args: ChatListRouteArgs(key: key, isAside: isAside), @@ -209,13 +251,13 @@ class ChatListRoute extends _i26.PageRouteInfo { static const String name = 'ChatListRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const ChatListRouteArgs(), ); - return _i5.ChatListScreen(key: args.key, isAside: args.isAside); + return _i6.ChatListScreen(key: args.key, isAside: args.isAside); }, ); } @@ -223,7 +265,7 @@ class ChatListRoute extends _i26.PageRouteInfo { class ChatListRouteArgs { const ChatListRouteArgs({this.key, this.isAside = false}); - final _i27.Key? key; + final _i28.Key? key; final bool isAside; @@ -234,12 +276,12 @@ class ChatListRouteArgs { } /// generated route for -/// [_i6.ChatRoomScreen] -class ChatRoomRoute extends _i26.PageRouteInfo { +/// [_i7.ChatRoomScreen] +class ChatRoomRoute extends _i27.PageRouteInfo { ChatRoomRoute({ - _i27.Key? key, + _i28.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( ChatRoomRoute.name, args: ChatRoomRouteArgs(key: key, id: id), @@ -249,14 +291,14 @@ class ChatRoomRoute extends _i26.PageRouteInfo { static const String name = 'ChatRoomRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => ChatRoomRouteArgs(id: pathParams.getString('id')), ); - return _i6.ChatRoomScreen(key: args.key, id: args.id); + return _i7.ChatRoomScreen(key: args.key, id: args.id); }, ); } @@ -264,7 +306,7 @@ class ChatRoomRoute extends _i26.PageRouteInfo { class ChatRoomRouteArgs { const ChatRoomRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i28.Key? key; final String id; @@ -275,44 +317,44 @@ class ChatRoomRouteArgs { } /// generated route for -/// [_i5.ChatShellScreen] -class ChatShellRoute extends _i26.PageRouteInfo { - const ChatShellRoute({List<_i26.PageRouteInfo>? children}) +/// [_i6.ChatShellScreen] +class ChatShellRoute extends _i27.PageRouteInfo { + const ChatShellRoute({List<_i27.PageRouteInfo>? children}) : super(ChatShellRoute.name, initialChildren: children); static const String name = 'ChatShellRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i5.ChatShellScreen(); + return const _i6.ChatShellScreen(); }, ); } /// generated route for -/// [_i7.CreateAccountScreen] -class CreateAccountRoute extends _i26.PageRouteInfo { - const CreateAccountRoute({List<_i26.PageRouteInfo>? children}) +/// [_i8.CreateAccountScreen] +class CreateAccountRoute extends _i27.PageRouteInfo { + const CreateAccountRoute({List<_i27.PageRouteInfo>? children}) : super(CreateAccountRoute.name, initialChildren: children); static const String name = 'CreateAccountRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i7.CreateAccountScreen(); + return const _i8.CreateAccountScreen(); }, ); } /// generated route for -/// [_i8.CreatorHubScreen] -class CreatorHubRoute extends _i26.PageRouteInfo { +/// [_i9.CreatorHubScreen] +class CreatorHubRoute extends _i27.PageRouteInfo { CreatorHubRoute({ - _i27.Key? key, + _i28.Key? key, bool isAside = false, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( CreatorHubRoute.name, args: CreatorHubRouteArgs(key: key, isAside: isAside), @@ -321,13 +363,13 @@ class CreatorHubRoute extends _i26.PageRouteInfo { static const String name = 'CreatorHubRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const CreatorHubRouteArgs(), ); - return _i8.CreatorHubScreen(key: args.key, isAside: args.isAside); + return _i9.CreatorHubScreen(key: args.key, isAside: args.isAside); }, ); } @@ -335,7 +377,7 @@ class CreatorHubRoute extends _i26.PageRouteInfo { class CreatorHubRouteArgs { const CreatorHubRouteArgs({this.key, this.isAside = false}); - final _i27.Key? key; + final _i28.Key? key; final bool isAside; @@ -346,25 +388,25 @@ class CreatorHubRouteArgs { } /// generated route for -/// [_i8.CreatorHubShellScreen] -class CreatorHubShellRoute extends _i26.PageRouteInfo { - const CreatorHubShellRoute({List<_i26.PageRouteInfo>? children}) +/// [_i9.CreatorHubShellScreen] +class CreatorHubShellRoute extends _i27.PageRouteInfo { + const CreatorHubShellRoute({List<_i27.PageRouteInfo>? children}) : super(CreatorHubShellRoute.name, initialChildren: children); static const String name = 'CreatorHubShellRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i8.CreatorHubShellScreen(); + return const _i9.CreatorHubShellScreen(); }, ); } /// generated route for -/// [_i5.EditChatScreen] -class EditChatRoute extends _i26.PageRouteInfo { - EditChatRoute({_i27.Key? key, String? id, List<_i26.PageRouteInfo>? children}) +/// [_i6.EditChatScreen] +class EditChatRoute extends _i27.PageRouteInfo { + EditChatRoute({_i28.Key? key, String? id, List<_i27.PageRouteInfo>? children}) : super( EditChatRoute.name, args: EditChatRouteArgs(key: key, id: id), @@ -374,14 +416,14 @@ class EditChatRoute extends _i26.PageRouteInfo { static const String name = 'EditChatRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => EditChatRouteArgs(id: pathParams.optString('id')), ); - return _i5.EditChatScreen(key: args.key, id: args.id); + return _i6.EditChatScreen(key: args.key, id: args.id); }, ); } @@ -389,7 +431,7 @@ class EditChatRoute extends _i26.PageRouteInfo { class EditChatRouteArgs { const EditChatRouteArgs({this.key, this.id}); - final _i27.Key? key; + final _i28.Key? key; final String? id; @@ -400,12 +442,12 @@ class EditChatRouteArgs { } /// generated route for -/// [_i9.EditPublisherScreen] -class EditPublisherRoute extends _i26.PageRouteInfo { +/// [_i10.EditPublisherScreen] +class EditPublisherRoute extends _i27.PageRouteInfo { EditPublisherRoute({ - _i27.Key? key, + _i28.Key? key, String? name, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( EditPublisherRoute.name, args: EditPublisherRouteArgs(key: key, name: name), @@ -415,14 +457,14 @@ class EditPublisherRoute extends _i26.PageRouteInfo { static const String name = 'EditPublisherRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => EditPublisherRouteArgs(name: pathParams.optString('id')), ); - return _i9.EditPublisherScreen(key: args.key, name: args.name); + return _i10.EditPublisherScreen(key: args.key, name: args.name); }, ); } @@ -430,7 +472,7 @@ class EditPublisherRoute extends _i26.PageRouteInfo { class EditPublisherRouteArgs { const EditPublisherRouteArgs({this.key, this.name}); - final _i27.Key? key; + final _i28.Key? key; final String? name; @@ -441,12 +483,12 @@ class EditPublisherRouteArgs { } /// generated route for -/// [_i10.EditRealmScreen] -class EditRealmRoute extends _i26.PageRouteInfo { +/// [_i11.EditRealmScreen] +class EditRealmRoute extends _i27.PageRouteInfo { EditRealmRoute({ - _i27.Key? key, + _i28.Key? key, String? slug, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( EditRealmRoute.name, args: EditRealmRouteArgs(key: key, slug: slug), @@ -456,14 +498,14 @@ class EditRealmRoute extends _i26.PageRouteInfo { static const String name = 'EditRealmRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => EditRealmRouteArgs(slug: pathParams.optString('slug')), ); - return _i10.EditRealmScreen(key: args.key, slug: args.slug); + return _i11.EditRealmScreen(key: args.key, slug: args.slug); }, ); } @@ -471,7 +513,7 @@ class EditRealmRoute extends _i26.PageRouteInfo { class EditRealmRouteArgs { const EditRealmRouteArgs({this.key, this.slug}); - final _i27.Key? key; + final _i28.Key? key; final String? slug; @@ -482,14 +524,14 @@ class EditRealmRouteArgs { } /// generated route for -/// [_i11.EditStickerPacksScreen] +/// [_i12.EditStickerPacksScreen] class EditStickerPacksRoute - extends _i26.PageRouteInfo { + extends _i27.PageRouteInfo { EditStickerPacksRoute({ - _i27.Key? key, + _i28.Key? key, required String pubName, String? packId, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( EditStickerPacksRoute.name, args: EditStickerPacksRouteArgs( @@ -503,7 +545,7 @@ class EditStickerPacksRoute static const String name = 'EditStickerPacksRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -513,7 +555,7 @@ class EditStickerPacksRoute packId: pathParams.optString('packId'), ), ); - return _i11.EditStickerPacksScreen( + return _i12.EditStickerPacksScreen( key: args.key, pubName: args.pubName, packId: args.packId, @@ -529,7 +571,7 @@ class EditStickerPacksRouteArgs { this.packId, }); - final _i27.Key? key; + final _i28.Key? key; final String pubName; @@ -542,13 +584,13 @@ class EditStickerPacksRouteArgs { } /// generated route for -/// [_i12.EditStickersScreen] -class EditStickersRoute extends _i26.PageRouteInfo { +/// [_i13.EditStickersScreen] +class EditStickersRoute extends _i27.PageRouteInfo { EditStickersRoute({ - _i27.Key? key, + _i28.Key? key, required String packId, required String? id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( EditStickersRoute.name, args: EditStickersRouteArgs(key: key, packId: packId, id: id), @@ -558,7 +600,7 @@ class EditStickersRoute extends _i26.PageRouteInfo { static const String name = 'EditStickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -568,7 +610,7 @@ class EditStickersRoute extends _i26.PageRouteInfo { id: pathParams.optString('id'), ), ); - return _i12.EditStickersScreen( + return _i13.EditStickersScreen( key: args.key, packId: args.packId, id: args.id, @@ -584,7 +626,7 @@ class EditStickersRouteArgs { required this.id, }); - final _i27.Key? key; + final _i28.Key? key; final String packId; @@ -597,12 +639,54 @@ class EditStickersRouteArgs { } /// generated route for -/// [_i13.ExploreScreen] -class ExploreRoute extends _i26.PageRouteInfo { +/// [_i14.EventCalanderScreen] +class EventCalanderRoute extends _i27.PageRouteInfo { + EventCalanderRoute({ + _i28.Key? key, + required String name, + List<_i27.PageRouteInfo>? children, + }) : super( + EventCalanderRoute.name, + args: EventCalanderRouteArgs(key: key, name: name), + rawPathParams: {'name': name}, + initialChildren: children, + ); + + static const String name = 'EventCalanderRoute'; + + static _i27.PageInfo page = _i27.PageInfo( + name, + builder: (data) { + final pathParams = data.inheritedPathParams; + final args = data.argsAs( + orElse: () => + EventCalanderRouteArgs(name: pathParams.getString('name')), + ); + return _i14.EventCalanderScreen(key: args.key, name: args.name); + }, + ); +} + +class EventCalanderRouteArgs { + const EventCalanderRouteArgs({this.key, required this.name}); + + final _i28.Key? key; + + final String name; + + @override + String toString() { + return 'EventCalanderRouteArgs{key: $key, name: $name}'; + } +} + +/// generated route for +/// [_i15.ExploreScreen] +class ExploreRoute extends _i27.PageRouteInfo { ExploreRoute({ - _i27.Key? key, + _i28.Key? key, bool isAside = false, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( ExploreRoute.name, args: ExploreRouteArgs(key: key, isAside: isAside), @@ -611,13 +695,13 @@ class ExploreRoute extends _i26.PageRouteInfo { static const String name = 'ExploreRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const ExploreRouteArgs(), ); - return _i13.ExploreScreen(key: args.key, isAside: args.isAside); + return _i15.ExploreScreen(key: args.key, isAside: args.isAside); }, ); } @@ -625,7 +709,7 @@ class ExploreRoute extends _i26.PageRouteInfo { class ExploreRouteArgs { const ExploreRouteArgs({this.key, this.isAside = false}); - final _i27.Key? key; + final _i28.Key? key; final bool isAside; @@ -636,109 +720,93 @@ class ExploreRouteArgs { } /// generated route for -/// [_i13.ExploreShellScreen] -class ExploreShellRoute extends _i26.PageRouteInfo { - const ExploreShellRoute({List<_i26.PageRouteInfo>? children}) +/// [_i15.ExploreShellScreen] +class ExploreShellRoute extends _i27.PageRouteInfo { + const ExploreShellRoute({List<_i27.PageRouteInfo>? children}) : super(ExploreShellRoute.name, initialChildren: children); static const String name = 'ExploreShellRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i13.ExploreShellScreen(); + return const _i15.ExploreShellScreen(); }, ); } /// generated route for -/// [_i14.LoginScreen] -class LoginRoute extends _i26.PageRouteInfo { - const LoginRoute({List<_i26.PageRouteInfo>? children}) +/// [_i16.LoginScreen] +class LoginRoute extends _i27.PageRouteInfo { + const LoginRoute({List<_i27.PageRouteInfo>? children}) : super(LoginRoute.name, initialChildren: children); static const String name = 'LoginRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i14.LoginScreen(); + return const _i16.LoginScreen(); }, ); } /// generated route for -/// [_i15.MyselfEventCalendarScreen] -class MyselfEventCalendarRoute extends _i26.PageRouteInfo { - const MyselfEventCalendarRoute({List<_i26.PageRouteInfo>? children}) - : super(MyselfEventCalendarRoute.name, initialChildren: children); - - static const String name = 'MyselfEventCalendarRoute'; - - static _i26.PageInfo page = _i26.PageInfo( - name, - builder: (data) { - return const _i15.MyselfEventCalendarScreen(); - }, - ); -} - -/// generated route for -/// [_i5.NewChatScreen] -class NewChatRoute extends _i26.PageRouteInfo { - const NewChatRoute({List<_i26.PageRouteInfo>? children}) +/// [_i6.NewChatScreen] +class NewChatRoute extends _i27.PageRouteInfo { + const NewChatRoute({List<_i27.PageRouteInfo>? children}) : super(NewChatRoute.name, initialChildren: children); static const String name = 'NewChatRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i5.NewChatScreen(); + return const _i6.NewChatScreen(); }, ); } /// generated route for -/// [_i9.NewPublisherScreen] -class NewPublisherRoute extends _i26.PageRouteInfo { - const NewPublisherRoute({List<_i26.PageRouteInfo>? children}) +/// [_i10.NewPublisherScreen] +class NewPublisherRoute extends _i27.PageRouteInfo { + const NewPublisherRoute({List<_i27.PageRouteInfo>? children}) : super(NewPublisherRoute.name, initialChildren: children); static const String name = 'NewPublisherRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i9.NewPublisherScreen(); + return const _i10.NewPublisherScreen(); }, ); } /// generated route for -/// [_i10.NewRealmScreen] -class NewRealmRoute extends _i26.PageRouteInfo { - const NewRealmRoute({List<_i26.PageRouteInfo>? children}) +/// [_i11.NewRealmScreen] +class NewRealmRoute extends _i27.PageRouteInfo { + const NewRealmRoute({List<_i27.PageRouteInfo>? children}) : super(NewRealmRoute.name, initialChildren: children); static const String name = 'NewRealmRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i10.NewRealmScreen(); + return const _i11.NewRealmScreen(); }, ); } /// generated route for -/// [_i11.NewStickerPacksScreen] +/// [_i12.NewStickerPacksScreen] class NewStickerPacksRoute - extends _i26.PageRouteInfo { + extends _i27.PageRouteInfo { NewStickerPacksRoute({ - _i27.Key? key, + _i28.Key? key, required String pubName, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( NewStickerPacksRoute.name, args: NewStickerPacksRouteArgs(key: key, pubName: pubName), @@ -748,7 +816,7 @@ class NewStickerPacksRoute static const String name = 'NewStickerPacksRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -756,7 +824,7 @@ class NewStickerPacksRoute orElse: () => NewStickerPacksRouteArgs(pubName: pathParams.getString('name')), ); - return _i11.NewStickerPacksScreen(key: args.key, pubName: args.pubName); + return _i12.NewStickerPacksScreen(key: args.key, pubName: args.pubName); }, ); } @@ -764,7 +832,7 @@ class NewStickerPacksRoute class NewStickerPacksRouteArgs { const NewStickerPacksRouteArgs({this.key, required this.pubName}); - final _i27.Key? key; + final _i28.Key? key; final String pubName; @@ -775,12 +843,12 @@ class NewStickerPacksRouteArgs { } /// generated route for -/// [_i12.NewStickersScreen] -class NewStickersRoute extends _i26.PageRouteInfo { +/// [_i13.NewStickersScreen] +class NewStickersRoute extends _i27.PageRouteInfo { NewStickersRoute({ - _i27.Key? key, + _i28.Key? key, required String packId, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( NewStickersRoute.name, args: NewStickersRouteArgs(key: key, packId: packId), @@ -790,7 +858,7 @@ class NewStickersRoute extends _i26.PageRouteInfo { static const String name = 'NewStickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -798,7 +866,7 @@ class NewStickersRoute extends _i26.PageRouteInfo { orElse: () => NewStickersRouteArgs(packId: pathParams.getString('packId')), ); - return _i12.NewStickersScreen(key: args.key, packId: args.packId); + return _i13.NewStickersScreen(key: args.key, packId: args.packId); }, ); } @@ -806,7 +874,7 @@ class NewStickersRoute extends _i26.PageRouteInfo { class NewStickersRouteArgs { const NewStickersRouteArgs({this.key, required this.packId}); - final _i27.Key? key; + final _i28.Key? key; final String packId; @@ -817,28 +885,28 @@ class NewStickersRouteArgs { } /// generated route for -/// [_i16.NotificationScreen] -class NotificationRoute extends _i26.PageRouteInfo { - const NotificationRoute({List<_i26.PageRouteInfo>? children}) +/// [_i17.NotificationScreen] +class NotificationRoute extends _i27.PageRouteInfo { + const NotificationRoute({List<_i27.PageRouteInfo>? children}) : super(NotificationRoute.name, initialChildren: children); static const String name = 'NotificationRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i16.NotificationScreen(); + return const _i17.NotificationScreen(); }, ); } /// generated route for -/// [_i17.PostComposeScreen] -class PostComposeRoute extends _i26.PageRouteInfo { +/// [_i18.PostComposeScreen] +class PostComposeRoute extends _i27.PageRouteInfo { PostComposeRoute({ - _i27.Key? key, - _i29.SnPost? originalPost, - List<_i26.PageRouteInfo>? children, + _i28.Key? key, + _i30.SnPost? originalPost, + List<_i27.PageRouteInfo>? children, }) : super( PostComposeRoute.name, args: PostComposeRouteArgs(key: key, originalPost: originalPost), @@ -847,13 +915,13 @@ class PostComposeRoute extends _i26.PageRouteInfo { static const String name = 'PostComposeRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs( orElse: () => const PostComposeRouteArgs(), ); - return _i17.PostComposeScreen( + return _i18.PostComposeScreen( key: args.key, originalPost: args.originalPost, ); @@ -864,9 +932,9 @@ class PostComposeRoute extends _i26.PageRouteInfo { class PostComposeRouteArgs { const PostComposeRouteArgs({this.key, this.originalPost}); - final _i27.Key? key; + final _i28.Key? key; - final _i29.SnPost? originalPost; + final _i30.SnPost? originalPost; @override String toString() { @@ -875,12 +943,12 @@ class PostComposeRouteArgs { } /// generated route for -/// [_i18.PostDetailScreen] -class PostDetailRoute extends _i26.PageRouteInfo { +/// [_i19.PostDetailScreen] +class PostDetailRoute extends _i27.PageRouteInfo { PostDetailRoute({ - _i27.Key? key, + _i28.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( PostDetailRoute.name, args: PostDetailRouteArgs(key: key, id: id), @@ -890,14 +958,14 @@ class PostDetailRoute extends _i26.PageRouteInfo { static const String name = 'PostDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => PostDetailRouteArgs(id: pathParams.getString('id')), ); - return _i18.PostDetailScreen(key: args.key, id: args.id); + return _i19.PostDetailScreen(key: args.key, id: args.id); }, ); } @@ -905,7 +973,7 @@ class PostDetailRoute extends _i26.PageRouteInfo { class PostDetailRouteArgs { const PostDetailRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i28.Key? key; final String id; @@ -916,12 +984,12 @@ class PostDetailRouteArgs { } /// generated route for -/// [_i17.PostEditScreen] -class PostEditRoute extends _i26.PageRouteInfo { +/// [_i18.PostEditScreen] +class PostEditRoute extends _i27.PageRouteInfo { PostEditRoute({ - _i27.Key? key, + _i28.Key? key, required String id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( PostEditRoute.name, args: PostEditRouteArgs(key: key, id: id), @@ -931,14 +999,14 @@ class PostEditRoute extends _i26.PageRouteInfo { static const String name = 'PostEditRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => PostEditRouteArgs(id: pathParams.getString('id')), ); - return _i17.PostEditScreen(key: args.key, id: args.id); + return _i18.PostEditScreen(key: args.key, id: args.id); }, ); } @@ -946,7 +1014,7 @@ class PostEditRoute extends _i26.PageRouteInfo { class PostEditRouteArgs { const PostEditRouteArgs({this.key, required this.id}); - final _i27.Key? key; + final _i28.Key? key; final String id; @@ -957,13 +1025,13 @@ class PostEditRouteArgs { } /// generated route for -/// [_i19.PublisherProfileScreen] +/// [_i20.PublisherProfileScreen] class PublisherProfileRoute - extends _i26.PageRouteInfo { + extends _i27.PageRouteInfo { PublisherProfileRoute({ - _i27.Key? key, + _i28.Key? key, required String name, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( PublisherProfileRoute.name, args: PublisherProfileRouteArgs(key: key, name: name), @@ -973,7 +1041,7 @@ class PublisherProfileRoute static const String name = 'PublisherProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -981,7 +1049,7 @@ class PublisherProfileRoute orElse: () => PublisherProfileRouteArgs(name: pathParams.getString('name')), ); - return _i19.PublisherProfileScreen(key: args.key, name: args.name); + return _i20.PublisherProfileScreen(key: args.key, name: args.name); }, ); } @@ -989,7 +1057,7 @@ class PublisherProfileRoute class PublisherProfileRouteArgs { const PublisherProfileRouteArgs({this.key, required this.name}); - final _i27.Key? key; + final _i28.Key? key; final String name; @@ -1000,12 +1068,12 @@ class PublisherProfileRouteArgs { } /// generated route for -/// [_i20.RealmDetailScreen] -class RealmDetailRoute extends _i26.PageRouteInfo { +/// [_i21.RealmDetailScreen] +class RealmDetailRoute extends _i27.PageRouteInfo { RealmDetailRoute({ - _i27.Key? key, + _i28.Key? key, required String slug, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( RealmDetailRoute.name, args: RealmDetailRouteArgs(key: key, slug: slug), @@ -1015,14 +1083,14 @@ class RealmDetailRoute extends _i26.PageRouteInfo { static const String name = 'RealmDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => RealmDetailRouteArgs(slug: pathParams.getString('slug')), ); - return _i20.RealmDetailScreen(key: args.key, slug: args.slug); + return _i21.RealmDetailScreen(key: args.key, slug: args.slug); }, ); } @@ -1030,7 +1098,7 @@ class RealmDetailRoute extends _i26.PageRouteInfo { class RealmDetailRouteArgs { const RealmDetailRouteArgs({this.key, required this.slug}); - final _i27.Key? key; + final _i28.Key? key; final String slug; @@ -1041,62 +1109,62 @@ class RealmDetailRouteArgs { } /// generated route for -/// [_i10.RealmListScreen] -class RealmListRoute extends _i26.PageRouteInfo { - const RealmListRoute({List<_i26.PageRouteInfo>? children}) +/// [_i11.RealmListScreen] +class RealmListRoute extends _i27.PageRouteInfo { + const RealmListRoute({List<_i27.PageRouteInfo>? children}) : super(RealmListRoute.name, initialChildren: children); static const String name = 'RealmListRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i10.RealmListScreen(); + return const _i11.RealmListScreen(); }, ); } /// generated route for -/// [_i21.RelationshipScreen] -class RelationshipRoute extends _i26.PageRouteInfo { - const RelationshipRoute({List<_i26.PageRouteInfo>? children}) +/// [_i22.RelationshipScreen] +class RelationshipRoute extends _i27.PageRouteInfo { + const RelationshipRoute({List<_i27.PageRouteInfo>? children}) : super(RelationshipRoute.name, initialChildren: children); static const String name = 'RelationshipRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i21.RelationshipScreen(); + return const _i22.RelationshipScreen(); }, ); } /// generated route for -/// [_i22.SettingsScreen] -class SettingsRoute extends _i26.PageRouteInfo { - const SettingsRoute({List<_i26.PageRouteInfo>? children}) +/// [_i23.SettingsScreen] +class SettingsRoute extends _i27.PageRouteInfo { + const SettingsRoute({List<_i27.PageRouteInfo>? children}) : super(SettingsRoute.name, initialChildren: children); static const String name = 'SettingsRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i22.SettingsScreen(); + return const _i23.SettingsScreen(); }, ); } /// generated route for -/// [_i12.StickerPackDetailScreen] +/// [_i13.StickerPackDetailScreen] class StickerPackDetailRoute - extends _i26.PageRouteInfo { + extends _i27.PageRouteInfo { StickerPackDetailRoute({ - _i27.Key? key, + _i28.Key? key, required String pubName, required String id, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( StickerPackDetailRoute.name, args: StickerPackDetailRouteArgs(key: key, pubName: pubName, id: id), @@ -1106,7 +1174,7 @@ class StickerPackDetailRoute static const String name = 'StickerPackDetailRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; @@ -1116,7 +1184,7 @@ class StickerPackDetailRoute id: pathParams.getString('packId'), ), ); - return _i12.StickerPackDetailScreen( + return _i13.StickerPackDetailScreen( key: args.key, pubName: args.pubName, id: args.id, @@ -1132,7 +1200,7 @@ class StickerPackDetailRouteArgs { required this.id, }); - final _i27.Key? key; + final _i28.Key? key; final String pubName; @@ -1145,12 +1213,12 @@ class StickerPackDetailRouteArgs { } /// generated route for -/// [_i11.StickersScreen] -class StickersRoute extends _i26.PageRouteInfo { +/// [_i12.StickersScreen] +class StickersRoute extends _i27.PageRouteInfo { StickersRoute({ - _i27.Key? key, + _i28.Key? key, required String pubName, - List<_i26.PageRouteInfo>? children, + List<_i27.PageRouteInfo>? children, }) : super( StickersRoute.name, args: StickersRouteArgs(key: key, pubName: pubName), @@ -1160,14 +1228,14 @@ class StickersRoute extends _i26.PageRouteInfo { static const String name = 'StickersRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final pathParams = data.inheritedPathParams; final args = data.argsAs( orElse: () => StickersRouteArgs(pubName: pathParams.getString('name')), ); - return _i11.StickersScreen(key: args.key, pubName: args.pubName); + return _i12.StickersScreen(key: args.key, pubName: args.pubName); }, ); } @@ -1175,7 +1243,7 @@ class StickersRoute extends _i26.PageRouteInfo { class StickersRouteArgs { const StickersRouteArgs({this.key, required this.pubName}); - final _i27.Key? key; + final _i28.Key? key; final String pubName; @@ -1186,14 +1254,14 @@ class StickersRouteArgs { } /// generated route for -/// [_i23.TabsNavigationWidget] +/// [_i24.TabsNavigationWidget] class TabsNavigationWidget - extends _i26.PageRouteInfo { + extends _i27.PageRouteInfo { TabsNavigationWidget({ - _i27.Key? key, - required _i27.Widget child, - required _i30.AppRouter router, - List<_i26.PageRouteInfo>? children, + _i28.Key? key, + required _i28.Widget child, + required _i31.AppRouter router, + List<_i27.PageRouteInfo>? children, }) : super( TabsNavigationWidget.name, args: TabsNavigationWidgetArgs(key: key, child: child, router: router), @@ -1202,11 +1270,11 @@ class TabsNavigationWidget static const String name = 'TabsNavigationWidget'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { final args = data.argsAs(); - return _i23.TabsNavigationWidget( + return _i24.TabsNavigationWidget( key: args.key, child: args.child, router: args.router, @@ -1222,11 +1290,11 @@ class TabsNavigationWidgetArgs { required this.router, }); - final _i27.Key? key; + final _i28.Key? key; - final _i27.Widget child; + final _i28.Widget child; - final _i30.AppRouter router; + final _i31.AppRouter router; @override String toString() { @@ -1235,33 +1303,33 @@ class TabsNavigationWidgetArgs { } /// generated route for -/// [_i24.UpdateProfileScreen] -class UpdateProfileRoute extends _i26.PageRouteInfo { - const UpdateProfileRoute({List<_i26.PageRouteInfo>? children}) +/// [_i25.UpdateProfileScreen] +class UpdateProfileRoute extends _i27.PageRouteInfo { + const UpdateProfileRoute({List<_i27.PageRouteInfo>? children}) : super(UpdateProfileRoute.name, initialChildren: children); static const String name = 'UpdateProfileRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i24.UpdateProfileScreen(); + return const _i25.UpdateProfileScreen(); }, ); } /// generated route for -/// [_i25.WalletScreen] -class WalletRoute extends _i26.PageRouteInfo { - const WalletRoute({List<_i26.PageRouteInfo>? children}) +/// [_i26.WalletScreen] +class WalletRoute extends _i27.PageRouteInfo { + const WalletRoute({List<_i27.PageRouteInfo>? children}) : super(WalletRoute.name, initialChildren: children); static const String name = 'WalletRoute'; - static _i26.PageInfo page = _i26.PageInfo( + static _i27.PageInfo page = _i27.PageInfo( name, builder: (data) { - return const _i25.WalletScreen(); + return const _i26.WalletScreen(); }, ); } diff --git a/lib/screens/account/me/event_calendar.dart b/lib/screens/account/me/event_calendar.dart index 378a169..8b1f93d 100644 --- a/lib/screens/account/me/event_calendar.dart +++ b/lib/screens/account/me/event_calendar.dart @@ -7,7 +7,9 @@ import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/models/activity.dart'; import 'package:island/pods/network.dart'; +import 'package:island/screens/account/profile.dart'; import 'package:island/widgets/app_scaffold.dart'; +import 'package:island/widgets/content/cloud_files.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:styled_widget/styled_widget.dart'; @@ -39,8 +41,9 @@ Future> accountEventCalendar( } @RoutePage() -class MyselfEventCalendarScreen extends HookConsumerWidget { - const MyselfEventCalendarScreen({super.key}); +class EventCalanderScreen extends HookConsumerWidget { + final String name; + const EventCalanderScreen({super.key, @PathParam("name") required this.name}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -49,150 +52,180 @@ class MyselfEventCalendarScreen extends HookConsumerWidget { final selectedDay = useState(DateTime.now()); + final user = ref.watch(accountProvider(name)); final events = ref.watch( accountEventCalendarProvider( EventCalendarQuery( - uname: 'me', + uname: name, year: selectedYear.value, month: selectedMonth.value, ), ), ); + final content = Column( + children: [ + TableCalendar( + locale: EasyLocalization.of(context)!.locale.toString(), + firstDay: DateTime.now().add(Duration(days: -3650)), + lastDay: DateTime.now().add(Duration(days: 3650)), + focusedDay: DateTime.utc( + selectedYear.value, + selectedMonth.value, + DateTime.now().day, + ), + calendarFormat: CalendarFormat.month, + selectedDayPredicate: (day) { + return isSameDay(selectedDay.value, day); + }, + onDaySelected: (value, _) { + selectedDay.value = value; + }, + onPageChanged: (focusedDay) { + selectedMonth.value = focusedDay.month; + selectedYear.value = focusedDay.year; + }, + eventLoader: (day) { + return events.value + ?.where((e) => isSameDay(e.date, day)) + .expand((e) => [...e.statuses, e.checkInResult]) + .where((e) => e != null) + .toList() ?? + []; + }, + calendarBuilders: CalendarBuilders( + dowBuilder: (context, day) { + final text = DateFormat.EEEEE().format(day); + return Center(child: Text(text)); + }, + markerBuilder: (context, day, events) { + var checkInResult = + events.whereType().firstOrNull; + if (checkInResult != null) { + return Positioned( + top: 32, + child: Text( + ['大凶', '凶', '中平', '吉', '大吉'][checkInResult.level], + style: TextStyle( + fontSize: 9, + color: + isSameDay(selectedDay.value, day) + ? Theme.of(context).colorScheme.onPrimaryContainer + : isSameDay(DateTime.now(), day) + ? Theme.of( + context, + ).colorScheme.onSecondaryContainer + : Theme.of(context).colorScheme.onSurface, + ), + ), + ); + } + return null; + }, + ), + ), + const Divider(height: 1).padding(top: 8), + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: Builder( + builder: (context) { + final event = + events.value + ?.where((e) => isSameDay(e.date, selectedDay.value)) + .firstOrNull; + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text(DateFormat.EEEE().format(selectedDay.value)) + .fontSize(16) + .bold() + .textColor( + Theme.of(context).colorScheme.onSecondaryContainer, + ), + Text(DateFormat.yMd().format(selectedDay.value)) + .fontSize(12) + .textColor( + Theme.of(context).colorScheme.onSecondaryContainer, + ), + const Gap(16), + if (event?.checkInResult != null) + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + 'checkInResultLevel${event!.checkInResult!.level}', + ).tr().fontSize(16).bold(), + for (final tip in event.checkInResult!.tips) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 8, + children: [ + Icon( + Symbols.circle, + size: 12, + fill: 1, + ).padding(top: 4, right: 4), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(tip.title).bold(), + Text(tip.content), + ], + ), + ), + ], + ).padding(top: 8), + ], + ), + if (event?.checkInResult == null && + (event?.statuses.isEmpty ?? true)) + Text('eventCalanderEmpty').tr(), + ], + ).padding(vertical: 24, horizontal: 24); + }, + ), + ), + if (name != 'me' && user.hasValue) + Container( + decoration: BoxDecoration( + border: Border.all( + width: 1 / MediaQuery.of(context).devicePixelRatio, + color: Theme.of(context).dividerColor, + ), + borderRadius: BorderRadius.all(Radius.circular(8)), + ), + margin: EdgeInsets.all(16), + child: Card( + margin: EdgeInsets.zero, + elevation: 0, + color: Colors.transparent, + child: ListTile( + leading: ProfilePictureWidget( + fileId: user.value!.profile.pictureId, + ), + title: Text(user.value!.nick).bold(), + subtitle: Text('@${user.value!.name}'), + ), + ), + ), + ], + ); + return AppScaffold( + noBackground: false, appBar: AppBar( leading: const PageBackButton(), title: Text('eventCalander').tr(), ), body: SingleChildScrollView( - child: Column( - children: [ - TableCalendar( - locale: EasyLocalization.of(context)!.locale.toString(), - firstDay: DateTime.now().add(Duration(days: -3650)), - lastDay: DateTime.now().add(Duration(days: 3650)), - focusedDay: DateTime.utc( - selectedYear.value, - selectedMonth.value, - DateTime.now().day, - ), - calendarFormat: CalendarFormat.month, - selectedDayPredicate: (day) { - return isSameDay(selectedDay.value, day); - }, - onDaySelected: (value, _) { - selectedDay.value = value; - }, - onPageChanged: (focusedDay) { - selectedMonth.value = focusedDay.month; - selectedYear.value = focusedDay.year; - }, - eventLoader: (day) { - return events.value - ?.where((e) => isSameDay(e.date, day)) - .expand((e) => [...e.statuses, e.checkInResult]) - .where((e) => e != null) - .toList() ?? - []; - }, - calendarBuilders: CalendarBuilders( - dowBuilder: (context, day) { - final text = DateFormat.EEEEE().format(day); - return Center(child: Text(text)); - }, - markerBuilder: (context, day, events) { - var checkInResult = - events.whereType().firstOrNull; - if (checkInResult != null) { - return Positioned( - top: 32, - child: Text( - ['大凶', '凶', '中平', '吉', '大吉'][checkInResult.level], - style: TextStyle( - fontSize: 9, - color: - isSameDay(selectedDay.value, day) - ? Theme.of( - context, - ).colorScheme.onPrimaryContainer - : isSameDay(DateTime.now(), day) - ? Theme.of( - context, - ).colorScheme.onSecondaryContainer - : Theme.of(context).colorScheme.onSurface, - ), - ), - ); - } - return null; - }, - ), - ), - const Divider(height: 1).padding(top: 8), - AnimatedSwitcher( - duration: const Duration(milliseconds: 300), - child: Builder( - builder: (context) { - final event = - events.value - ?.where((e) => isSameDay(e.date, selectedDay.value)) - .firstOrNull; - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text(DateFormat.EEEE().format(selectedDay.value)) - .fontSize(16) - .bold() - .textColor( - Theme.of(context).colorScheme.onSecondaryContainer, - ), - Text(DateFormat.yMd().format(selectedDay.value)) - .fontSize(12) - .textColor( - Theme.of(context).colorScheme.onSecondaryContainer, - ), - const Gap(16), - if (event?.checkInResult != null) - Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - 'checkInResultLevel${event!.checkInResult!.level}', - ).tr().fontSize(16).bold(), - for (final tip in event.checkInResult!.tips) - Row( - crossAxisAlignment: CrossAxisAlignment.start, - spacing: 8, - children: [ - Icon( - Symbols.circle, - size: 12, - fill: 1, - ).padding(top: 4, right: 4), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text(tip.title).bold(), - Text(tip.content), - ], - ), - ), - ], - ).padding(top: 8), - ], - ), - if (event?.checkInResult == null && - (event?.statuses.isEmpty ?? true)) - Text('eventCalanderEmpty').tr(), - ], - ).padding(vertical: 24, horizontal: 24); - }, - ), - ), - ], - ), + child: + MediaQuery.of(context).size.width > 480 + ? ConstrainedBox( + constraints: BoxConstraints(maxWidth: 480), + child: Card(margin: EdgeInsets.all(16), child: content), + ).center() + : content, ), ); } diff --git a/lib/screens/account/profile.dart b/lib/screens/account/profile.dart index 183bea5..e0f0608 100644 --- a/lib/screens/account/profile.dart +++ b/lib/screens/account/profile.dart @@ -5,6 +5,7 @@ import 'package:gap/gap.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/models/user.dart'; import 'package:island/pods/network.dart'; +import 'package:island/pods/userinfo.dart'; import 'package:island/widgets/account/badge.dart'; import 'package:island/widgets/account/leveling_progress.dart'; import 'package:island/widgets/account/status.dart'; @@ -17,6 +18,12 @@ part 'profile.g.dart'; @riverpod Future account(Ref ref, String uname) async { + if (uname == 'me') { + final userInfo = ref.watch(userInfoProvider); + if (userInfo.hasValue && userInfo.value != null) { + return userInfo.value!; + } + } final apiClient = ref.watch(apiClientProvider); final resp = await apiClient.get("/accounts/$uname"); return SnAccount.fromJson(resp.data); diff --git a/lib/screens/account/profile.g.dart b/lib/screens/account/profile.g.dart index efe824b..df0f91d 100644 --- a/lib/screens/account/profile.g.dart +++ b/lib/screens/account/profile.g.dart @@ -6,7 +6,7 @@ part of 'profile.dart'; // RiverpodGenerator // ************************************************************************** -String _$accountHash() => r'39003ef3250181b9290e0562329c7801d4841941'; +String _$accountHash() => r'd2b0579617e6264452d98f47f695a9cdf45b24ec'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/screens/account/relationship.dart b/lib/screens/account/relationship.dart index 2d67e67..99bc7df 100644 --- a/lib/screens/account/relationship.dart +++ b/lib/screens/account/relationship.dart @@ -96,8 +96,7 @@ class RelationshipListTile extends StatelessWidget { relationship.status == 0 && relationship.relatedId == currentUserId; final isWaiting = relationship.status == 0 && relationship.accountId == currentUserId; - final isEstablished = - relationship.status >= 100 || relationship.status <= -100; + final isEstablished = relationship.status == 1 || relationship.status == 2; return ListTile( contentPadding: const EdgeInsets.only(left: 16, right: 12), diff --git a/lib/screens/auth/create_account.dart b/lib/screens/auth/create_account.dart index 8ce47ed..d6d41a0 100644 --- a/lib/screens/auth/create_account.dart +++ b/lib/screens/auth/create_account.dart @@ -75,6 +75,7 @@ class CreateAccountScreen extends HookConsumerWidget { } return AppScaffold( + noBackground: false, appBar: AppBar( leading: const PageBackButton(), title: Text('createAccount').tr(), diff --git a/lib/screens/auth/login.dart b/lib/screens/auth/login.dart index b86f4c6..34543a6 100644 --- a/lib/screens/auth/login.dart +++ b/lib/screens/auth/login.dart @@ -41,6 +41,7 @@ class LoginScreen extends HookConsumerWidget { final factors = useState>([]); final factorPicked = useState(null); return AppScaffold( + noBackground: false, appBar: AppBar( leading: const PageBackButton(), title: Text('login').tr(), diff --git a/lib/screens/chat/call.dart b/lib/screens/chat/call.dart index 7bc1141..a131dc5 100644 --- a/lib/screens/chat/call.dart +++ b/lib/screens/chat/call.dart @@ -1,10 +1,13 @@ +import 'package:auto_route/annotations.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:island/pods/call.dart'; +@RoutePage() class CallScreen extends HookConsumerWidget { - const CallScreen({super.key}); + final String roomId; + const CallScreen({super.key, @PathParam('id') required this.roomId}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -12,7 +15,7 @@ class CallScreen extends HookConsumerWidget { final callNotifier = ref.read(callNotifierProvider.notifier); useEffect(() { - callNotifier.initialize(); + callNotifier.joinRoom(roomId); return null; }, []); diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index 2827d5c..7a937e1 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -33,6 +33,7 @@ import 'package:material_symbols_icons/symbols.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:super_clipboard/super_clipboard.dart'; import 'chat.dart'; +import 'package:island/widgets/chat/call_button.dart'; part 'room.g.dart'; @@ -514,12 +515,7 @@ class ChatRoomScreen extends HookConsumerWidget { ), ), actions: [ - IconButton( - icon: const Icon(Symbols.video_call), - onPressed: () { - showInfoAlert('Oops', 'Not implemented yet...'); - }, - ), + AudioCallButton(roomId: id), IconButton( icon: const Icon(Icons.more_vert), onPressed: () { diff --git a/lib/widgets/app_scaffold.dart b/lib/widgets/app_scaffold.dart index 8155cd3..73fa9ea 100644 --- a/lib/widgets/app_scaffold.dart +++ b/lib/widgets/app_scaffold.dart @@ -13,6 +13,8 @@ import 'package:island/services/responsive.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; import 'package:path_provider/path_provider.dart'; import 'package:styled_widget/styled_widget.dart'; +import 'package:island/widgets/chat/call_overlay.dart'; +import 'package:island/pods/call.dart'; class WindowScaffold extends HookConsumerWidget { final Widget child; @@ -150,11 +152,16 @@ class AppScaffold extends StatelessWidget { noBackground ? Colors.transparent : Theme.of(context).scaffoldBackgroundColor, - body: SizedBox.expand( - child: - noBackground - ? content - : AppBackground(isRoot: true, child: content), + body: Stack( + children: [ + SizedBox.expand( + child: + noBackground + ? content + : AppBackground(isRoot: true, child: content), + ), + const _GlobalCallOverlay(), + ], ), appBar: appBar, bottomNavigationBar: bottomNavigationBar, @@ -192,6 +199,28 @@ class PageBackButton extends StatelessWidget { const kAppBackgroundImagePath = 'island_app_background'; +/// Global call overlay bar (appears when in a call but not on the call screen) +class _GlobalCallOverlay extends HookConsumerWidget { + const _GlobalCallOverlay(); + @override + Widget build(BuildContext context, WidgetRef ref) { + final callState = ref.watch(callNotifierProvider); + // Find current route name + final modalRoute = ModalRoute.of(context); + final isOnCallScreen = modalRoute?.settings.name?.contains('call') ?? false; + // You may want to store roomId in callState for more robust navigation + final roomId = + (modalRoute?.settings.arguments is Map && + (modalRoute!.settings.arguments as Map).containsKey('roomId')) + ? (modalRoute.settings.arguments as Map)['roomId'] as String + : null; + if (callState.isConnected && !isOnCallScreen && roomId != null) { + return CallOverlayBar(roomId: roomId); + } + return const SizedBox.shrink(); + } +} + final backgroundImageFileProvider = FutureProvider((ref) async { if (kIsWeb) return null; final dir = await getApplicationSupportDirectory(); diff --git a/lib/widgets/chat/call_button.dart b/lib/widgets/chat/call_button.dart new file mode 100644 index 0000000..ec53c64 --- /dev/null +++ b/lib/widgets/chat/call_button.dart @@ -0,0 +1,112 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:island/models/chat.dart'; +import 'package:island/pods/call.dart'; +import 'package:island/pods/network.dart'; +import 'package:island/route.gr.dart'; +import 'package:island/widgets/alert.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'call_button.g.dart'; + +@riverpod +Future ongoingCall(Ref ref, String roomId) async { + try { + final apiClient = ref.watch(apiClientProvider); + final resp = await apiClient.get('/chat/realtime/$roomId'); + return SnRealtimeCall.fromJson(resp.data); + } catch (e) { + if (e is DioException && e.response?.statusCode == 404) { + return null; + } + showErrorAlert(e); + return null; + } +} + +class AudioCallButton extends HookConsumerWidget { + final String roomId; + const AudioCallButton({super.key, required this.roomId}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final ongoingCall = ref.watch(ongoingCallProvider(roomId)); + final callState = ref.watch(callNotifierProvider); + final callNotifier = ref.read(callNotifierProvider.notifier); + final isLoading = useState(false); + final apiClient = ref.watch(apiClientProvider); + + Future handleJoin() async { + isLoading.value = true; + try { + await apiClient.post('/chat/realtime/$roomId'); + if (context.mounted) { + context.router.push(CallRoute(roomId: roomId)); + } + } catch (e) { + showErrorAlert(e); + } finally { + isLoading.value = false; + } + } + + Future handleEnd() async { + isLoading.value = true; + try { + await apiClient.delete('/chat/realtime/$roomId'); + callNotifier.dispose(); // Clean up call resources + } catch (e) { + showErrorAlert(e); + } finally { + isLoading.value = false; + } + } + + if (isLoading.value) { + return IconButton( + icon: SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Theme.of(context).appBarTheme.foregroundColor!, + padding: EdgeInsets.all(4), + ), + ), + onPressed: null, + ); + } + + if (callState.isConnected) { + // Show end call button if in call + return IconButton( + icon: const Icon(Icons.call_end), + tooltip: 'End Call', + onPressed: handleEnd, + ); + } + + if (ongoingCall.value != null) { + // There is an ongoing call, offer to join it directly + return IconButton( + icon: const Icon(Icons.call), + tooltip: 'Join Ongoing Call', + onPressed: () { + if (context.mounted) { + context.router.push(CallRoute(roomId: roomId)); + } + }, + ); + } + + // Show join/start call button + return IconButton( + icon: const Icon(Icons.call), + tooltip: 'Start/Join Call', + onPressed: handleJoin, + ); + } +} diff --git a/lib/widgets/chat/call_button.g.dart b/lib/widgets/chat/call_button.g.dart new file mode 100644 index 0000000..73c8727 --- /dev/null +++ b/lib/widgets/chat/call_button.g.dart @@ -0,0 +1,151 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'call_button.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$ongoingCallHash() => r'd8a942e6695a7da702daeaa452464c16761ef6e7'; + +/// 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 [ongoingCall]. +@ProviderFor(ongoingCall) +const ongoingCallProvider = OngoingCallFamily(); + +/// See also [ongoingCall]. +class OngoingCallFamily extends Family> { + /// See also [ongoingCall]. + const OngoingCallFamily(); + + /// See also [ongoingCall]. + OngoingCallProvider call(String roomId) { + return OngoingCallProvider(roomId); + } + + @override + OngoingCallProvider getProviderOverride( + covariant OngoingCallProvider provider, + ) { + return call(provider.roomId); + } + + static const Iterable? _dependencies = null; + + @override + Iterable? get dependencies => _dependencies; + + static const Iterable? _allTransitiveDependencies = null; + + @override + Iterable? get allTransitiveDependencies => + _allTransitiveDependencies; + + @override + String? get name => r'ongoingCallProvider'; +} + +/// See also [ongoingCall]. +class OngoingCallProvider extends AutoDisposeFutureProvider { + /// See also [ongoingCall]. + OngoingCallProvider(String roomId) + : this._internal( + (ref) => ongoingCall(ref as OngoingCallRef, roomId), + from: ongoingCallProvider, + name: r'ongoingCallProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') + ? null + : _$ongoingCallHash, + dependencies: OngoingCallFamily._dependencies, + allTransitiveDependencies: OngoingCallFamily._allTransitiveDependencies, + roomId: roomId, + ); + + OngoingCallProvider._internal( + super._createNotifier, { + required super.name, + required super.dependencies, + required super.allTransitiveDependencies, + required super.debugGetCreateSourceHash, + required super.from, + required this.roomId, + }) : super.internal(); + + final String roomId; + + @override + Override overrideWith( + FutureOr Function(OngoingCallRef provider) create, + ) { + return ProviderOverride( + origin: this, + override: OngoingCallProvider._internal( + (ref) => create(ref as OngoingCallRef), + from: from, + name: null, + dependencies: null, + allTransitiveDependencies: null, + debugGetCreateSourceHash: null, + roomId: roomId, + ), + ); + } + + @override + AutoDisposeFutureProviderElement createElement() { + return _OngoingCallProviderElement(this); + } + + @override + bool operator ==(Object other) { + return other is OngoingCallProvider && other.roomId == roomId; + } + + @override + int get hashCode { + var hash = _SystemHash.combine(0, runtimeType.hashCode); + hash = _SystemHash.combine(hash, roomId.hashCode); + + return _SystemHash.finish(hash); + } +} + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +mixin OngoingCallRef on AutoDisposeFutureProviderRef { + /// The parameter `roomId` of this provider. + String get roomId; +} + +class _OngoingCallProviderElement + extends AutoDisposeFutureProviderElement + with OngoingCallRef { + _OngoingCallProviderElement(super.provider); + + @override + String get roomId => (origin as OngoingCallProvider).roomId; +} + +// 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 diff --git a/lib/widgets/chat/call_overlay.dart b/lib/widgets/chat/call_overlay.dart new file mode 100644 index 0000000..7addb25 --- /dev/null +++ b/lib/widgets/chat/call_overlay.dart @@ -0,0 +1,53 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:island/pods/call.dart'; +import 'package:island/route.gr.dart'; + +/// A floating bar that appears when user is in a call but not on the call screen. +class CallOverlayBar extends HookConsumerWidget { + final String roomId; + const CallOverlayBar({super.key, required this.roomId}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final callState = ref.watch(callNotifierProvider); + // Only show if connected and not on the call screen + if (!callState.isConnected) return const SizedBox.shrink(); + + return Positioned( + left: 16, + right: 16, + bottom: 32, + child: GestureDetector( + onTap: () { + context.router.push(CallRoute(roomId: roomId)); + }, + child: Material( + elevation: 8, + borderRadius: BorderRadius.circular(24), + color: Theme.of(context).colorScheme.primary, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Icon(Icons.call, color: Colors.white), + const SizedBox(width: 12), + const Text( + 'In call', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16), + ), + ], + ), + const Icon(Icons.arrow_forward_ios, color: Colors.white, size: 18), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/chat/message_item.dart b/lib/widgets/chat/message_item.dart index 6e32352..53bca01 100644 --- a/lib/widgets/chat/message_item.dart +++ b/lib/widgets/chat/message_item.dart @@ -46,10 +46,6 @@ class MessageItem extends HookConsumerWidget { isCurrentUser ? Theme.of(context).colorScheme.primaryContainer.withOpacity(0.5) : Theme.of(context).colorScheme.surfaceContainer; - final linkColor = Color.alphaBlend( - Theme.of(context).colorScheme.primary, - containerColor, - ); final hasBackground = ref.watch(backgroundImageFileProvider).valueOrNull != null; @@ -196,16 +192,8 @@ class MessageItem extends HookConsumerWidget { textColor: textColor, isReply: false, ).padding(vertical: 4), - if (remoteMessage.content?.isNotEmpty ?? false) - MarkdownTextContent( - content: remoteMessage.content!, - isSelectable: true, - linkStyle: TextStyle(color: linkColor), - textStyle: TextStyle( - color: textColor, - fontSize: 14, - ), - ), + if (_MessageItemContent.hasContent(remoteMessage)) + _MessageItemContent(item: remoteMessage), if (remoteMessage.attachments.isNotEmpty) LayoutBuilder( builder: (context, constraints) { @@ -360,7 +348,10 @@ class MessageQuoteWidget extends HookConsumerWidget { : message.toRemoteMessage().forwardedMessageId!, ), builder: (context, snapshot) { - if (snapshot.hasData) { + final remoteMessage = + snapshot.hasData ? snapshot.data!.toRemoteMessage() : null; + + if (remoteMessage != null) { return ClipRRect( borderRadius: BorderRadius.all(Radius.circular(8)), child: Container( @@ -378,7 +369,7 @@ class MessageQuoteWidget extends HookConsumerWidget { children: [ Icon(Symbols.reply, size: 16, color: textColor), Text( - 'Replying to ${snapshot.data!.toRemoteMessage().sender.account.nick}', + 'Replying to ${remoteMessage.sender.account.nick}', ).textColor(textColor).bold(), ], ).padding(right: 8) @@ -389,16 +380,12 @@ class MessageQuoteWidget extends HookConsumerWidget { children: [ Icon(Symbols.forward, size: 16, color: textColor), Text( - 'Forwarded from ${snapshot.data!.toRemoteMessage().sender.account.nick}', + 'Forwarded from ${remoteMessage.sender.account.nick}', ).textColor(textColor).bold(), ], ).padding(right: 8), - if (snapshot.data!.toRemoteMessage().content?.isNotEmpty ?? - false) - Text( - snapshot.data!.toRemoteMessage().content!, - style: TextStyle(color: textColor), - ), + if (_MessageItemContent.hasContent(remoteMessage)) + _MessageItemContent(item: remoteMessage), ], ), ), @@ -410,3 +397,62 @@ class MessageQuoteWidget extends HookConsumerWidget { ); } } + +class _MessageItemContent extends StatelessWidget { + final SnChatMessage item; + const _MessageItemContent({required this.item}); + + @override + Widget build(BuildContext context) { + switch (item.type) { + case 'call.start': + case 'call.ended': + return _MessageContentCall( + isEnded: item.type == 'call.ended', + duration: item.meta['duration']?.toDouble(), + ); + case 'text': + default: + return MarkdownTextContent(content: item.content!); + } + } + + static bool hasContent(SnChatMessage item) { + return item.type == 'text' && (item.content?.isNotEmpty ?? false); + } +} + +class _MessageContentCall extends StatelessWidget { + final bool isEnded; + final double? duration; + const _MessageContentCall({required this.isEnded, this.duration}); + + @override + Widget build(BuildContext context) { + String formatDuration(Duration duration) { + final hours = duration.inHours; + final minutes = duration.inMinutes.remainder(60); + final seconds = duration.inSeconds.remainder(60); + return '${hours == 0 ? '' : '$hours hours '}' + '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}'; + } + + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + isEnded ? Symbols.call_end : Symbols.phone_in_talk, + size: 16, + color: Theme.of(context).colorScheme.primary, + ), + Gap(4), + Text( + isEnded + ? 'Call ended after ${formatDuration(Duration(seconds: duration!.toInt()))}' + : 'Call started', + style: TextStyle(color: Theme.of(context).colorScheme.primary), + ), + ], + ); + } +} diff --git a/lib/widgets/check_in.dart b/lib/widgets/check_in.dart index 376ba4c..1a7a026 100644 --- a/lib/widgets/check_in.dart +++ b/lib/widgets/check_in.dart @@ -42,11 +42,16 @@ class CheckInWidget extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final todayResult = ref.watch(checkInResultTodayProvider); - Future checkIn() async { + Future checkIn({String? captchatTk}) async { final client = ref.read(apiClientProvider); try { - await client.post('/accounts/me/check-in'); + await client.post( + '/accounts/me/check-in', + data: captchatTk == null ? null : jsonEncode(captchatTk), + ); ref.invalidate(checkInResultTodayProvider); + final userNotifier = ref.read(userInfoProvider.notifier); + userNotifier.fetchUser(); } catch (err) { if (err is DioException) { if (err.response?.statusCode == 423 && context.mounted) { @@ -54,14 +59,7 @@ class CheckInWidget extends HookConsumerWidget { context, ).push(MaterialPageRoute(builder: (context) => CaptchaScreen())); if (captchaTk == null) return; - await client.post( - '/accounts/me/check-in', - data: jsonEncode(captchaTk), - ); - ref.invalidate(checkInResultTodayProvider); - final userNotifier = ref.read(userInfoProvider.notifier); - userNotifier.fetchUser(); - return; + return await checkIn(captchatTk: captchaTk); } } showErrorAlert(err); @@ -139,7 +137,7 @@ class CheckInWidget extends HookConsumerWidget { if (todayResult.valueOrNull == null) { checkIn(); } else { - context.router.push(MyselfEventCalendarRoute()); + context.router.push(EventCalanderRoute(name: 'me')); } }, icon: AnimatedSwitcher( diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index c06bb17..6d39abf 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import bitsdojo_window_macos +import connectivity_plus import device_info_plus import file_picker import file_selector_macos @@ -16,6 +17,7 @@ import flutter_platform_alert import flutter_udid import flutter_webrtc import irondash_engine_context +import livekit_client import media_kit_libs_macos_video import media_kit_video import package_info_plus @@ -30,6 +32,7 @@ import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) @@ -40,6 +43,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterUdidPlugin.register(with: registry.registrar(forPlugin: "FlutterUdidPlugin")) FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) + LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin")) MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin")) MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 0a5d414..af02618 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,6 +1,8 @@ PODS: - bitsdojo_window_macos (0.0.1): - FlutterMacOS + - connectivity_plus (0.0.1): + - FlutterMacOS - croppy (0.0.1): - FlutterMacOS - device_info_plus (0.0.1): @@ -50,6 +52,9 @@ PODS: - flutter_udid (0.0.1): - FlutterMacOS - SAMKeychain + - flutter_webrtc (0.14.0): + - FlutterMacOS + - WebRTC-SDK (= 125.6422.07) - FlutterMacOS (1.0.0) - GoogleDataTransport (10.1.0): - nanopb (~> 3.30910.0) @@ -80,6 +85,10 @@ PODS: - GoogleUtilities/Privacy - irondash_engine_context (0.0.1): - FlutterMacOS + - livekit_client (2.4.7): + - flutter_webrtc + - FlutterMacOS + - WebRTC-SDK (= 125.6422.07) - media_kit_libs_macos_video (1.0.4): - FlutterMacOS - media_kit_video (0.0.1): @@ -133,9 +142,11 @@ PODS: - FlutterMacOS - wakelock_plus (0.0.1): - FlutterMacOS + - WebRTC-SDK (125.6422.07) DEPENDENCIES: - bitsdojo_window_macos (from `Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos`) + - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) - croppy (from `Flutter/ephemeral/.symlinks/plugins/croppy/macos`) - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - file_picker (from `Flutter/ephemeral/.symlinks/plugins/file_picker/macos`) @@ -145,8 +156,10 @@ DEPENDENCIES: - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`) - flutter_platform_alert (from `Flutter/ephemeral/.symlinks/plugins/flutter_platform_alert/macos`) - flutter_udid (from `Flutter/ephemeral/.symlinks/plugins/flutter_udid/macos`) + - flutter_webrtc (from `Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) + - livekit_client (from `Flutter/ephemeral/.symlinks/plugins/livekit_client/macos`) - media_kit_libs_macos_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos`) - media_kit_video (from `Flutter/ephemeral/.symlinks/plugins/media_kit_video/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) @@ -173,10 +186,13 @@ SPEC REPOS: - PromisesObjC - SAMKeychain - sqlite3 + - WebRTC-SDK EXTERNAL SOURCES: bitsdojo_window_macos: :path: Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos + connectivity_plus: + :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos croppy: :path: Flutter/ephemeral/.symlinks/plugins/croppy/macos device_info_plus: @@ -195,10 +211,14 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/flutter_platform_alert/macos flutter_udid: :path: Flutter/ephemeral/.symlinks/plugins/flutter_udid/macos + flutter_webrtc: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_webrtc/macos FlutterMacOS: :path: Flutter/ephemeral irondash_engine_context: :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos + livekit_client: + :path: Flutter/ephemeral/.symlinks/plugins/livekit_client/macos media_kit_libs_macos_video: :path: Flutter/ephemeral/.symlinks/plugins/media_kit_libs_macos_video/macos media_kit_video: @@ -224,6 +244,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: bitsdojo_window_macos: 7959fb0ca65a3ccda30095c181ecb856fae48ea9 + connectivity_plus: 4adf20a405e25b42b9c9f87feff8f4b6fde18a4e croppy: d9bfc8c02f3cd1851f669a421df298a474b78f43 device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 file_picker: 7584aae6fa07a041af2b36a2655122d42f578c1a @@ -238,10 +259,12 @@ SPEC CHECKSUMS: flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d flutter_platform_alert: 8fa7a7c21f95b26d08b4a3891936ca27e375f284 flutter_udid: d26e455e8c06174e6aff476e147defc6cae38495 + flutter_webrtc: a7eeb54859e672228c28f4b48b1fb61561976ea3 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba + livekit_client: c5fc13c397f17de76534280744ddd8c232915057 media_kit_libs_macos_video: 85a23e549b5f480e72cae3e5634b5514bc692f65 media_kit_video: fa6564e3799a0a28bff39442334817088b7ca758 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 @@ -258,6 +281,7 @@ SPEC CHECKSUMS: url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673 volume_controller: 5c068e6d085c80dadd33fc2c918d2114b775b3dd wakelock_plus: 21ddc249ac4b8d018838dbdabd65c5976c308497 + WebRTC-SDK: dff00a3892bc570b6014e046297782084071657e PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 5d12d5b..f3ee99a 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -384,14 +384,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; @@ -427,14 +423,10 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); - outputPaths = ( - ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; diff --git a/pubspec.lock b/pubspec.lock index de5f888..d3a99fa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -313,6 +313,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + connectivity_plus: + dependency: transitive + description: + name: connectivity_plus + sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" convert: dependency: transitive description: @@ -1149,6 +1165,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.1" + livekit_client: + dependency: "direct main" + description: + name: livekit_client + sha256: dc8fe8295353a6f4c96915a49faece4ede2334d2b2bdf5ed4b985e07507bdf09 + url: "https://pub.dev" + source: hosted + version: "2.4.7" logging: dependency: transitive description: @@ -1285,6 +1309,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + mime_type: + dependency: transitive + description: + name: mime_type + sha256: d652b613e84dac1af28030a9fba82c0999be05b98163f9e18a0849c6e63838bb + url: "https://pub.dev" + source: hosted + version: "1.0.1" modal_bottom_sheet: dependency: "direct main" description: @@ -1301,6 +1333,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" octo_image: dependency: transitive description: @@ -1453,6 +1493,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.2" + protobuf: + dependency: transitive + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" provider: dependency: transitive description: @@ -1581,6 +1629,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + sdp_transform: + dependency: transitive + description: + name: sdp_transform + sha256: "73e412a5279a5c2de74001535208e20fff88f225c9a4571af0f7146202755e45" + url: "https://pub.dev" + source: hosted + version: "0.3.2" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index cb23c46..43cb549 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -102,6 +102,7 @@ dependencies: super_sliver_list: ^0.4.1 super_clipboard: ^0.9.0-dev.6 flutter_webrtc: ^0.14.1 + livekit_client: ^2.4.7 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 47678b9..811aae6 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +26,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); FirebaseCorePluginCApiRegisterWithRegistrar( @@ -38,6 +42,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("FlutterWebRTCPlugin")); IrondashEngineContextPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("IrondashEngineContextPluginCApi")); + LiveKitPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("LiveKitPlugin")); MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi")); MediaKitVideoPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index c298702..85523a4 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_windows + connectivity_plus file_selector_windows firebase_core flutter_inappwebview_windows @@ -11,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_udid flutter_webrtc irondash_engine_context + livekit_client media_kit_libs_windows_video media_kit_video sqlite3_flutter_libs