Skip to content

Commit

Permalink
feat: get token with each login + handle token config for push notifi…
Browse files Browse the repository at this point in the history
…cation reconnection
  • Loading branch information
Oliver-Zimmerman committed Feb 7, 2025
1 parent 349ff02 commit a7f43df
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 19 deletions.
26 changes: 19 additions & 7 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -276,7 +277,7 @@ Future<void> main() async {
await AppInitializer().initialize();
}

final credentialConfig = await txClientViewModel.getCredentialConfig();
final config = await txClientViewModel.getConfig();
runApp(
BackgroundDetector(
onLifecycleEvent: (AppLifecycleState state) => {
Expand All @@ -286,7 +287,14 @@ Future<void> 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 is CredentialConfig)
{
txClientViewModel.login(config),
}
else if (config is TokenConfig)
{
txClientViewModel.loginWithToken(config),
},
},
}
else if (state == AppLifecycleState.paused)
Expand Down Expand Up @@ -319,9 +327,13 @@ Future<void> handlePush(Map<dynamic, dynamic> 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');
}
Expand Down
25 changes: 23 additions & 2 deletions lib/model/profile_model.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import 'dart:io';

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 {
Expand All @@ -7,6 +12,7 @@ class Profile {
final String sipPassword;
final String sipCallerIDName;
final String sipCallerIDNumber;
final String? notificationToken;

Profile({
required this.isTokenLogin,
Expand All @@ -15,6 +21,7 @@ class Profile {
this.sipPassword = '',
this.sipCallerIDName = '',
this.sipCallerIDNumber = '',
this.notificationToken = '',
});

factory Profile.fromJson(Map<String, dynamic> json) {
Expand All @@ -25,6 +32,7 @@ class Profile {
sipPassword: json['sipPassword'] as String? ?? '',
sipCallerIDName: json['sipCallerIDName'] as String? ?? '',
sipCallerIDNumber: json['sipCallerIDNumber'] as String? ?? '',
notificationToken: json['notificationToken'] as String? ?? '',
);
}

Expand All @@ -36,15 +44,27 @@ class Profile {
'sipPassword': sipPassword,
'sipCallerIDName': sipCallerIDName,
'sipCallerIDNumber': sipCallerIDNumber,
'notificationToken': notificationToken,
};
}

Config toTelnyxConfig() {
Future<String?> getNotificationTokenForPlatform() async {
var token;
if (defaultTargetPlatform == TargetPlatform.android) {
token = (await FirebaseMessaging.instance.getToken())!;
} else if (Platform.isIOS) {
token = await FlutterCallkitIncoming.getDevicePushTokenVoIP();
}
return token;
}

Future<Config> toTelnyxConfig() async {
if (isTokenLogin) {
return TokenConfig(
sipToken: token,
sipCallerIDName: sipCallerIDName,
sipCallerIDNumber: sipCallerIDNumber,
notificationToken: await getNotificationTokenForPlatform() ?? '',
debug: false,
);
} else {
Expand All @@ -53,8 +73,9 @@ class Profile {
sipPassword: sipPassword,
sipCallerIDName: sipCallerIDName,
sipCallerIDNumber: sipCallerIDNumber,
notificationToken: await getNotificationTokenForPlatform() ?? '',
debug: false,
);
}
}
}
}
37 changes: 36 additions & 1 deletion lib/view/telnyx_client_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,22 @@ class TelnyxClientViewModel with ChangeNotifier {

bool waitingForInvite = false;

Future<CredentialConfig> getCredentialConfig() async {
Future<Config?> getConfig() async {
final config = await _getCredentialConfig();
if (config != null) {
return config;
} else {
return await _getTokenConfig();
}
}

Future<CredentialConfig?> _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 &&
Expand All @@ -368,6 +378,7 @@ class TelnyxClientViewModel with ChangeNotifier {
sipCallerIDNumber: sipNumber,
sipUser: sipUser,
sipPassword: sipPassword,
notificationToken: notificationToken,
debug: true,
);
} else {
Expand All @@ -381,6 +392,30 @@ class TelnyxClientViewModel with ChangeNotifier {
}
}

Future<TokenConfig?> _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 TokenConfig(
sipCallerIDName: 'Flutter Voice',
sipCallerIDNumber: '',
sipToken: '',
debug: true,
);
}
}

Future<void> accept({bool acceptFromNotification = false}) async {
if (callState == CallStateStatus.ongoingCall) {
return;
Expand Down
15 changes: 6 additions & 9 deletions lib/view/widgets/login/login_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,13 @@ class _LoginControlsState extends State<LoginControls> {
width: double.infinity,
child: ElevatedButton(
onPressed: selectedProfile != null
? () {
? () async {
final viewModel = context.read<TelnyxClientViewModel>();
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,
Expand Down

0 comments on commit a7f43df

Please sign in to comment.