diff --git a/lib/main.dart b/lib/main.dart index 1aa1819..d2809fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,6 +19,7 @@ import 'package:telnyx_webrtc/telnyx_client.dart'; import 'package:telnyx_webrtc/model/telnyx_message.dart'; import 'package:telnyx_webrtc/model/socket_method.dart'; import 'package:telnyx_flutter_webrtc/utils/theme.dart'; +import 'package:telnyx_webrtc/config/telnyx_config.dart'; final logger = Logger(); final txClientViewModel = TelnyxClientViewModel(); @@ -227,11 +228,11 @@ Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { logger.i('iOS notification token :: $token'); } - final credentialConfig = await txClientViewModel.getCredentialConfig(); + final config = await txClientViewModel.getConfig(); telnyxClient.handlePushNotification( pushMetaData, - credentialConfig, - null, + config is CredentialConfig ? config : null, + config is TokenConfig ? config : null, ); break; case Event.actionDidUpdateDevicePushTokenVoip: @@ -276,7 +277,7 @@ Future main() async { await AppInitializer().initialize(); } - final credentialConfig = await txClientViewModel.getCredentialConfig(); + final config = await txClientViewModel.getConfig(); runApp( BackgroundDetector( onLifecycleEvent: (AppLifecycleState state) => { @@ -286,7 +287,14 @@ Future main() async { // Check if we are from push, if we are do nothing, reconnection will happen there in handlePush. Otherwise connect if (!txClientViewModel.callFromPush) { - txClientViewModel.login(credentialConfig), + if (config != null && config is CredentialConfig) + { + txClientViewModel.login(config), + } + else if (config != null && config is TokenConfig) + { + txClientViewModel.loginWithToken(config), + }, }, } else if (state == AppLifecycleState.paused) @@ -319,9 +327,13 @@ Future handlePush(Map data) async { pushMetaData = PushMetaData.fromJson(data); logger.i('iOS notification token :: $token'); } - final credentialConfig = await txClientViewModel.getCredentialConfig(); + final config = await txClientViewModel.getConfig(); txClientViewModel - ..handlePushNotification(pushMetaData!, credentialConfig, null) + ..handlePushNotification( + pushMetaData!, + config is CredentialConfig ? config : null, + config is TokenConfig ? config : null, + ) ..observeResponses(); logger.i('actionCallIncoming :: Received Incoming Call! Handle Push'); } diff --git a/lib/model/profile_model.dart b/lib/model/profile_model.dart index 6f1e221..8264ab2 100644 --- a/lib/model/profile_model.dart +++ b/lib/model/profile_model.dart @@ -1,3 +1,9 @@ +import 'dart:io'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_callkit_incoming/flutter_callkit_incoming.dart'; import 'package:telnyx_webrtc/config/telnyx_config.dart'; class Profile { @@ -7,6 +13,7 @@ class Profile { final String sipPassword; final String sipCallerIDName; final String sipCallerIDNumber; + final String? notificationToken; Profile({ required this.isTokenLogin, @@ -15,6 +22,7 @@ class Profile { this.sipPassword = '', this.sipCallerIDName = '', this.sipCallerIDNumber = '', + this.notificationToken = '', }); factory Profile.fromJson(Map json) { @@ -25,6 +33,7 @@ class Profile { sipPassword: json['sipPassword'] as String? ?? '', sipCallerIDName: json['sipCallerIDName'] as String? ?? '', sipCallerIDNumber: json['sipCallerIDNumber'] as String? ?? '', + notificationToken: json['notificationToken'] as String? ?? '', ); } @@ -36,15 +45,31 @@ class Profile { 'sipPassword': sipPassword, 'sipCallerIDName': sipCallerIDName, 'sipCallerIDNumber': sipCallerIDNumber, + 'notificationToken': notificationToken, }; } - Config toTelnyxConfig() { + Future getNotificationTokenForPlatform() async { + var token; + if (defaultTargetPlatform == TargetPlatform.android) { + // If no apps are initialized, initialize one now. + if (Firebase.apps.isEmpty) { + await Firebase.initializeApp(); + } + token = (await FirebaseMessaging.instance.getToken())!; + } else if (Platform.isIOS) { + token = await FlutterCallkitIncoming.getDevicePushTokenVoIP(); + } + return token; + } + + Future toTelnyxConfig() async { if (isTokenLogin) { return TokenConfig( sipToken: token, sipCallerIDName: sipCallerIDName, sipCallerIDNumber: sipCallerIDNumber, + notificationToken: await getNotificationTokenForPlatform() ?? '', debug: false, ); } else { @@ -53,8 +78,9 @@ class Profile { sipPassword: sipPassword, sipCallerIDName: sipCallerIDName, sipCallerIDNumber: sipCallerIDNumber, + notificationToken: await getNotificationTokenForPlatform() ?? '', debug: false, ); } } -} \ No newline at end of file +} diff --git a/lib/view/telnyx_client_view_model.dart b/lib/view/telnyx_client_view_model.dart index 93ac919..1c95ee0 100644 --- a/lib/view/telnyx_client_view_model.dart +++ b/lib/view/telnyx_client_view_model.dart @@ -353,12 +353,22 @@ class TelnyxClientViewModel with ChangeNotifier { bool waitingForInvite = false; - Future getCredentialConfig() async { + Future getConfig() async { + final config = await _getCredentialConfig(); + if (config != null) { + return config; + } else { + return await _getTokenConfig(); + } + } + + Future _getCredentialConfig() async { final prefs = await SharedPreferences.getInstance(); final sipUser = prefs.getString('sipUser'); final sipPassword = prefs.getString('sipPassword'); final sipName = prefs.getString('sipName'); final sipNumber = prefs.getString('sipNumber'); + final notificationToken = prefs.getString('notificationToken'); if (sipUser != null && sipPassword != null && sipName != null && @@ -368,16 +378,30 @@ class TelnyxClientViewModel with ChangeNotifier { sipCallerIDNumber: sipNumber, sipUser: sipUser, sipPassword: sipPassword, + notificationToken: notificationToken, debug: true, ); } else { - return CredentialConfig( - sipCallerIDName: 'Flutter Voice', - sipCallerIDNumber: '', - sipUser: MOCK_USER, - sipPassword: MOCK_PASSWORD, + return null; + } + } + + Future _getTokenConfig() async { + final prefs = await SharedPreferences.getInstance(); + final token = prefs.getString('token'); + final sipName = prefs.getString('sipName'); + final sipNumber = prefs.getString('sipNumber'); + final notificationToken = prefs.getString('notificationToken'); + if (token != null && sipName != null && sipNumber != null) { + return TokenConfig( + sipCallerIDName: sipName, + sipCallerIDNumber: sipNumber, + sipToken: token, + notificationToken: notificationToken, debug: true, ); + } else { + return null; } } diff --git a/lib/view/widgets/login/login_controls.dart b/lib/view/widgets/login/login_controls.dart index 592742f..77c3ecc 100644 --- a/lib/view/widgets/login/login_controls.dart +++ b/lib/view/widgets/login/login_controls.dart @@ -53,16 +53,13 @@ class _LoginControlsState extends State { width: double.infinity, child: ElevatedButton( onPressed: selectedProfile != null - ? () { + ? () async { final viewModel = context.read(); - if (selectedProfile.isTokenLogin) { - viewModel.loginWithToken( - selectedProfile.toTelnyxConfig() as TokenConfig, - ); - } else { - viewModel.login( - selectedProfile.toTelnyxConfig() as CredentialConfig, - ); + final config = await selectedProfile.toTelnyxConfig(); + if (config is TokenConfig) { + viewModel.loginWithToken(config); + } else if (config is CredentialConfig) { + viewModel.login(config); } } : null,