diff --git a/dialer/android/app/build.gradle b/dialer/android/app/build.gradle index eaadca1..d57b47c 100644 --- a/dialer/android/app/build.gradle +++ b/dialer/android/app/build.gradle @@ -24,7 +24,7 @@ android { applicationId = "com.icing.dialer" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + minSdk = 23 targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName diff --git a/dialer/lib/presentation/features/settings/sim/settings_sim.dart b/dialer/lib/presentation/features/settings/sim/settings_sim.dart index c33938f..6872ea1 100644 --- a/dialer/lib/presentation/features/settings/sim/settings_sim.dart +++ b/dialer/lib/presentation/features/settings/sim/settings_sim.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:sim_data_new/sim_data.dart'; class SettingsSimPage extends StatefulWidget { const SettingsSimPage({super.key}); @@ -10,13 +11,34 @@ class SettingsSimPage extends StatefulWidget { class _SettingsSimPageState extends State { int _selectedSim = 0; + SimData? _simData; + bool _isLoading = true; + String? _error; @override void initState() { super.initState(); + _loadSimCards(); _loadDefaultSim(); } + void _loadSimCards() async { + try { + final simData = await SimDataPlugin.getSimData(); + setState(() { + _simData = simData; + _isLoading = false; + _error = null; + }); + } catch (e) { + setState(() { + _isLoading = false; + _error = e.toString(); + }); + print('Error loading SIM cards: $e'); + } + } + void _loadDefaultSim() async { final prefs = await SharedPreferences.getInstance(); setState(() { @@ -41,24 +63,158 @@ class _SettingsSimPageState extends State { appBar: AppBar( title: const Text('Default SIM'), ), - body: ListView( - children: [ - RadioListTile( - title: const Text('SIM 1', style: TextStyle(color: Colors.white)), - value: 0, - groupValue: _selectedSim, - onChanged: _onSimChanged, - activeColor: Colors.blue, - ), - RadioListTile( - title: const Text('SIM 2', style: TextStyle(color: Colors.white)), - value: 1, - groupValue: _selectedSim, - onChanged: _onSimChanged, - activeColor: Colors.blue, - ), - ], - ), + body: _buildBody(), ); } + + Widget _buildBody() { + if (_isLoading) { + return const Center( + child: CircularProgressIndicator( + color: Colors.blue, + ), + ); + } + + if (_error != null) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.error_outline, + color: Colors.red, + size: 64, + ), + const SizedBox(height: 16), + Text( + 'Error loading SIM cards', + style: const TextStyle(color: Colors.white, fontSize: 18), + ), + const SizedBox(height: 8), + Text( + _error!, + style: const TextStyle(color: Colors.grey, fontSize: 14), + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: () { + setState(() { + _isLoading = true; + _error = null; + }); + _loadSimCards(); + }, + child: const Text('Retry'), + ), + const SizedBox(height: 16), + Text( + 'Fallback to default options:', + style: const TextStyle(color: Colors.grey, fontSize: 14), + ), + const SizedBox(height: 8), + _buildFallbackSimList(), + ], + ), + ); + } + + if (_simData == null || _simData!.cards.isEmpty) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.sim_card_alert, + color: Colors.orange, + size: 64, + ), + const SizedBox(height: 16), + const Text( + 'No SIM cards detected', + style: TextStyle(color: Colors.white, fontSize: 18), + ), + const SizedBox(height: 8), + const Text( + 'Using default options:', + style: TextStyle(color: Colors.grey, fontSize: 14), + ), + const SizedBox(height: 16), + _buildFallbackSimList(), + ], + ), + ); + } + + return ListView.builder( + itemCount: _simData!.cards.length, + itemBuilder: (context, index) { + final card = _simData!.cards[index]; + return RadioListTile( + title: Text( + _getSimDisplayName(card, index), + style: const TextStyle(color: Colors.white), + ), + subtitle: Text( + _getSimSubtitle(card), + style: const TextStyle(color: Colors.grey), + ), + value: card.slotIndex, + groupValue: _selectedSim, + onChanged: _onSimChanged, + activeColor: Colors.blue, + ); + }, + ); + } + + Widget _buildFallbackSimList() { + return Column( + children: [ + RadioListTile( + title: const Text('SIM 1', style: TextStyle(color: Colors.white)), + value: 0, + groupValue: _selectedSim, + onChanged: _onSimChanged, + activeColor: Colors.blue, + ), + RadioListTile( + title: const Text('SIM 2', style: TextStyle(color: Colors.white)), + value: 1, + groupValue: _selectedSim, + onChanged: _onSimChanged, + activeColor: Colors.blue, + ), + ], + ); + } + + String _getSimDisplayName(dynamic card, int index) { + if (card.displayName != null && card.displayName.isNotEmpty) { + return card.displayName; + } + if (card.carrierName != null && card.carrierName.isNotEmpty) { + return card.carrierName; + } + return 'SIM ${index + 1}'; + } + + String _getSimSubtitle(dynamic card) { + List subtitleParts = []; + + if (card.phoneNumber != null && card.phoneNumber.isNotEmpty) { + subtitleParts.add(card.phoneNumber); + } + + if (card.carrierName != null && card.carrierName.isNotEmpty) { + subtitleParts.add(card.carrierName); + } + + if (subtitleParts.isEmpty) { + subtitleParts.add('Slot ${card.slotIndex}'); + } + + return subtitleParts.join(' • '); + } } diff --git a/dialer/pubspec.yaml b/dialer/pubspec.yaml index 244050a..b90eac2 100644 --- a/dialer/pubspec.yaml +++ b/dialer/pubspec.yaml @@ -52,9 +52,10 @@ dependencies: audioplayers: ^6.1.0 cryptography: ^2.0.0 convert: ^3.0.1 - encrypt: ^5.0.3 + encrypt: ^5.0.3 uuid: ^4.5.1 provider: ^6.1.2 + sim_data_new: ^1.0.1 intl: any