diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 59e9a5295f..9ca6a73832 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -9762,5 +9762,9 @@ "example": "1.5h, 2.0h" } } + }, + "deviceDoesNotSupportWifiSwitchingToBle": "Device does not support WiFi sync, switching to Bluetooth", + "@deviceDoesNotSupportWifiSwitchingToBle": { + "description": "Message shown when WiFi sync fails because device hardware does not support WiFi, automatically falling back to Bluetooth transfer" } -} +} \ No newline at end of file diff --git a/app/lib/l10n/app_localizations.dart b/app/lib/l10n/app_localizations.dart index 815f724249..42dacf4897 100644 --- a/app/lib/l10n/app_localizations.dart +++ b/app/lib/l10n/app_localizations.dart @@ -14516,6 +14516,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Large time gaps detected ({gaps})'** String largeTimeGapsDetected(String gaps); + + /// Message shown when WiFi sync fails because device hardware does not support WiFi, automatically falling back to Bluetooth transfer + /// + /// In en, this message translates to: + /// **'Device does not support WiFi sync, switching to Bluetooth'** + String get deviceDoesNotSupportWifiSwitchingToBle; } class _AppLocalizationsDelegate extends LocalizationsDelegate { diff --git a/app/lib/l10n/app_localizations_ar.dart b/app/lib/l10n/app_localizations_ar.dart index f2f99d0543..ce71a5d0aa 100644 --- a/app/lib/l10n/app_localizations_ar.dart +++ b/app/lib/l10n/app_localizations_ar.dart @@ -7731,4 +7731,7 @@ class AppLocalizationsAr extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'تم اكتشاف فجوات زمنية كبيرة ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_bg.dart b/app/lib/l10n/app_localizations_bg.dart index b222b9b47d..27a7495118 100644 --- a/app/lib/l10n/app_localizations_bg.dart +++ b/app/lib/l10n/app_localizations_bg.dart @@ -7818,4 +7818,7 @@ class AppLocalizationsBg extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Открити са големи времеви разлики ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ca.dart b/app/lib/l10n/app_localizations_ca.dart index 6455b9647e..d29c40c04f 100644 --- a/app/lib/l10n/app_localizations_ca.dart +++ b/app/lib/l10n/app_localizations_ca.dart @@ -7834,4 +7834,7 @@ class AppLocalizationsCa extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'S\'han detectat grans intervals de temps ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_cs.dart b/app/lib/l10n/app_localizations_cs.dart index b309ad29d9..d4db22e387 100644 --- a/app/lib/l10n/app_localizations_cs.dart +++ b/app/lib/l10n/app_localizations_cs.dart @@ -7781,4 +7781,7 @@ class AppLocalizationsCs extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Zjištěny velké časové mezery ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_da.dart b/app/lib/l10n/app_localizations_da.dart index 958d275d73..551336a8cd 100644 --- a/app/lib/l10n/app_localizations_da.dart +++ b/app/lib/l10n/app_localizations_da.dart @@ -7770,4 +7770,7 @@ class AppLocalizationsDa extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Store tidsgab opdaget ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_de.dart b/app/lib/l10n/app_localizations_de.dart index dc33315d95..d9d549faa0 100644 --- a/app/lib/l10n/app_localizations_de.dart +++ b/app/lib/l10n/app_localizations_de.dart @@ -7852,4 +7852,7 @@ class AppLocalizationsDe extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Große Zeitlücken erkannt ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_el.dart b/app/lib/l10n/app_localizations_el.dart index 8ee78ae4f8..4342e88cf3 100644 --- a/app/lib/l10n/app_localizations_el.dart +++ b/app/lib/l10n/app_localizations_el.dart @@ -7843,4 +7843,7 @@ class AppLocalizationsEl extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Εντοπίστηκαν μεγάλα χρονικά κενά ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_en.dart b/app/lib/l10n/app_localizations_en.dart index 0685aa0dda..3f725e4b83 100644 --- a/app/lib/l10n/app_localizations_en.dart +++ b/app/lib/l10n/app_localizations_en.dart @@ -7784,4 +7784,7 @@ class AppLocalizationsEn extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Large time gaps detected ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_es.dart b/app/lib/l10n/app_localizations_es.dart index 9e4d40ab5a..f87d0348a8 100644 --- a/app/lib/l10n/app_localizations_es.dart +++ b/app/lib/l10n/app_localizations_es.dart @@ -7800,4 +7800,7 @@ class AppLocalizationsEs extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Se detectaron brechas de tiempo grandes ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_et.dart b/app/lib/l10n/app_localizations_et.dart index 283f12aa17..3a47c72947 100644 --- a/app/lib/l10n/app_localizations_et.dart +++ b/app/lib/l10n/app_localizations_et.dart @@ -7786,4 +7786,7 @@ class AppLocalizationsEt extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Tuvastati suured ajavahed ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_fi.dart b/app/lib/l10n/app_localizations_fi.dart index 835376e908..29c69a6a55 100644 --- a/app/lib/l10n/app_localizations_fi.dart +++ b/app/lib/l10n/app_localizations_fi.dart @@ -7785,4 +7785,7 @@ class AppLocalizationsFi extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Havaittu suuria aikavälejä ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_fr.dart b/app/lib/l10n/app_localizations_fr.dart index ba6aca6f9e..0e2b80e285 100644 --- a/app/lib/l10n/app_localizations_fr.dart +++ b/app/lib/l10n/app_localizations_fr.dart @@ -7858,4 +7858,7 @@ class AppLocalizationsFr extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Grands écarts de temps détectés ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_hi.dart b/app/lib/l10n/app_localizations_hi.dart index 804288af9a..e23eaf481b 100644 --- a/app/lib/l10n/app_localizations_hi.dart +++ b/app/lib/l10n/app_localizations_hi.dart @@ -7766,4 +7766,7 @@ class AppLocalizationsHi extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'बड़े समय अंतराल पाए गए ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_hu.dart b/app/lib/l10n/app_localizations_hu.dart index 2ae3d4de63..cdc7886805 100644 --- a/app/lib/l10n/app_localizations_hu.dart +++ b/app/lib/l10n/app_localizations_hu.dart @@ -7823,4 +7823,7 @@ class AppLocalizationsHu extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Nagy időeltérések észlelve ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_id.dart b/app/lib/l10n/app_localizations_id.dart index fc1b0bb714..c578229938 100644 --- a/app/lib/l10n/app_localizations_id.dart +++ b/app/lib/l10n/app_localizations_id.dart @@ -7798,4 +7798,7 @@ class AppLocalizationsId extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Terdeteksi jeda waktu besar ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_it.dart b/app/lib/l10n/app_localizations_it.dart index 3e28bffd8e..f4b3aa793e 100644 --- a/app/lib/l10n/app_localizations_it.dart +++ b/app/lib/l10n/app_localizations_it.dart @@ -7835,4 +7835,7 @@ class AppLocalizationsIt extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Rilevati grandi divari temporali ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ja.dart b/app/lib/l10n/app_localizations_ja.dart index 6143c378b2..055b5e79be 100644 --- a/app/lib/l10n/app_localizations_ja.dart +++ b/app/lib/l10n/app_localizations_ja.dart @@ -7653,4 +7653,7 @@ class AppLocalizationsJa extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return '大きな時間差が検出されました ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ko.dart b/app/lib/l10n/app_localizations_ko.dart index 2ba368a9ec..f377413499 100644 --- a/app/lib/l10n/app_localizations_ko.dart +++ b/app/lib/l10n/app_localizations_ko.dart @@ -7655,4 +7655,7 @@ class AppLocalizationsKo extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return '큰 시간 간격들이 감지되었습니다 ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_lt.dart b/app/lib/l10n/app_localizations_lt.dart index 9783a0381c..63fdea6f31 100644 --- a/app/lib/l10n/app_localizations_lt.dart +++ b/app/lib/l10n/app_localizations_lt.dart @@ -7791,4 +7791,7 @@ class AppLocalizationsLt extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Aptikti dideli laiko tarpai ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_lv.dart b/app/lib/l10n/app_localizations_lv.dart index 59cc213b3c..b1ae4e4929 100644 --- a/app/lib/l10n/app_localizations_lv.dart +++ b/app/lib/l10n/app_localizations_lv.dart @@ -7804,4 +7804,7 @@ class AppLocalizationsLv extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Konstatētas lielas laika starpības ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ms.dart b/app/lib/l10n/app_localizations_ms.dart index 6f7ecf6438..37702098de 100644 --- a/app/lib/l10n/app_localizations_ms.dart +++ b/app/lib/l10n/app_localizations_ms.dart @@ -7809,4 +7809,7 @@ class AppLocalizationsMs extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Jurang masa besar dikesan ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_nl.dart b/app/lib/l10n/app_localizations_nl.dart index 84db5b6778..e2f8f1f53c 100644 --- a/app/lib/l10n/app_localizations_nl.dart +++ b/app/lib/l10n/app_localizations_nl.dart @@ -7811,4 +7811,7 @@ class AppLocalizationsNl extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Grote tijdsverschillen gedetecteerd ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_no.dart b/app/lib/l10n/app_localizations_no.dart index 82ecc6761b..f064874517 100644 --- a/app/lib/l10n/app_localizations_no.dart +++ b/app/lib/l10n/app_localizations_no.dart @@ -7782,4 +7782,7 @@ class AppLocalizationsNo extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Store tidsluker oppdaget ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_pl.dart b/app/lib/l10n/app_localizations_pl.dart index e27e1d525f..822112cc65 100644 --- a/app/lib/l10n/app_localizations_pl.dart +++ b/app/lib/l10n/app_localizations_pl.dart @@ -7804,4 +7804,7 @@ class AppLocalizationsPl extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Wykryto duże przerwy czasowe ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_pt.dart b/app/lib/l10n/app_localizations_pt.dart index dc786d5a0a..1e3fd537e3 100644 --- a/app/lib/l10n/app_localizations_pt.dart +++ b/app/lib/l10n/app_localizations_pt.dart @@ -7786,4 +7786,7 @@ class AppLocalizationsPt extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Grandes intervalos de tempo detetados ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ro.dart b/app/lib/l10n/app_localizations_ro.dart index c5d7aae178..9ba4a2b5f3 100644 --- a/app/lib/l10n/app_localizations_ro.dart +++ b/app/lib/l10n/app_localizations_ro.dart @@ -7824,4 +7824,7 @@ class AppLocalizationsRo extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Au fost detectate diferențe mari de timp ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_ru.dart b/app/lib/l10n/app_localizations_ru.dart index bf34248e29..8481b08053 100644 --- a/app/lib/l10n/app_localizations_ru.dart +++ b/app/lib/l10n/app_localizations_ru.dart @@ -7811,4 +7811,7 @@ class AppLocalizationsRu extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Обнаружены большие временные разрывы ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_sk.dart b/app/lib/l10n/app_localizations_sk.dart index 5f97c82e1c..b1bd857478 100644 --- a/app/lib/l10n/app_localizations_sk.dart +++ b/app/lib/l10n/app_localizations_sk.dart @@ -7776,4 +7776,7 @@ class AppLocalizationsSk extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Zistené veľké časové medzery ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_sv.dart b/app/lib/l10n/app_localizations_sv.dart index 2650059a1c..adb3e939fa 100644 --- a/app/lib/l10n/app_localizations_sv.dart +++ b/app/lib/l10n/app_localizations_sv.dart @@ -7792,4 +7792,7 @@ class AppLocalizationsSv extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Stora tidsgap upptäckta ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_th.dart b/app/lib/l10n/app_localizations_th.dart index 3320e1c658..f7fb9ea741 100644 --- a/app/lib/l10n/app_localizations_th.dart +++ b/app/lib/l10n/app_localizations_th.dart @@ -7749,4 +7749,7 @@ class AppLocalizationsTh extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'ตรวจพบช่วงเวลาห่างมากหลายช่วง ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_tr.dart b/app/lib/l10n/app_localizations_tr.dart index 119c19f508..bc778b30d9 100644 --- a/app/lib/l10n/app_localizations_tr.dart +++ b/app/lib/l10n/app_localizations_tr.dart @@ -7799,4 +7799,7 @@ class AppLocalizationsTr extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Büyük zaman farkları tespit edildi ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_uk.dart b/app/lib/l10n/app_localizations_uk.dart index 9d632bdfee..7a9ff29ea6 100644 --- a/app/lib/l10n/app_localizations_uk.dart +++ b/app/lib/l10n/app_localizations_uk.dart @@ -7798,4 +7798,7 @@ class AppLocalizationsUk extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Виявлено великі часові розриви ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_vi.dart b/app/lib/l10n/app_localizations_vi.dart index d2b0e05325..3b266ce916 100644 --- a/app/lib/l10n/app_localizations_vi.dart +++ b/app/lib/l10n/app_localizations_vi.dart @@ -7789,4 +7789,7 @@ class AppLocalizationsVi extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return 'Phát hiện các khoảng cách thời gian lớn ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/l10n/app_localizations_zh.dart b/app/lib/l10n/app_localizations_zh.dart index f2954045e0..55bd4c0baf 100644 --- a/app/lib/l10n/app_localizations_zh.dart +++ b/app/lib/l10n/app_localizations_zh.dart @@ -7643,4 +7643,7 @@ class AppLocalizationsZh extends AppLocalizations { String largeTimeGapsDetected(String gaps) { return '检测到多个较大时间间隔 ($gaps)'; } + + @override + String get deviceDoesNotSupportWifiSwitchingToBle => 'Device does not support WiFi sync, switching to Bluetooth'; } diff --git a/app/lib/pages/conversations/wal_item_detail/wal_item_detail_page.dart b/app/lib/pages/conversations/wal_item_detail/wal_item_detail_page.dart index 22659b6bd0..9cc8e03efc 100644 --- a/app/lib/pages/conversations/wal_item_detail/wal_item_detail_page.dart +++ b/app/lib/pages/conversations/wal_item_detail/wal_item_detail_page.dart @@ -10,8 +10,10 @@ import 'package:omi/models/playback_state.dart'; import 'package:omi/pages/conversations/sync_widgets/fast_transfer_suggestion_dialog.dart'; import 'package:omi/pages/conversations/sync_widgets/location_permission_dialog.dart'; import 'package:omi/providers/sync_provider.dart'; +import 'package:omi/services/devices/wifi_sync_error.dart'; import 'package:omi/services/services.dart'; import 'package:omi/services/wals.dart'; +import 'package:omi/services/wifi/wifi_network_service.dart'; import 'package:omi/ui/molecules/omi_confirm_dialog.dart'; import 'package:omi/pages/conversations/sync_widgets/wifi_connection_sheet.dart'; import 'package:omi/utils/device.dart'; @@ -535,7 +537,18 @@ class _WalItemDetailPageState extends State { final preferredMethod = SharedPreferencesUtil().preferredSyncMethod; final wifiSupported = await ServiceManager.instance().wal.getSyncs().sdcard.isWifiSyncSupported(); - if (preferredMethod == 'ble' && wifiSupported && widget.wal.storage == WalStorage.sdcard) { + bool wifiHardwareAvailable = false; + if (wifiSupported && widget.wal.storage == WalStorage.sdcard) { + wifiHardwareAvailable = await _checkWifiHardwareAvailable(); + if (!wifiHardwareAvailable && preferredMethod == 'wifi') { + SharedPreferencesUtil().preferredSyncMethod = 'ble'; + if (mounted) { + _showSnackBar(context.l10n.deviceDoesNotSupportWifiSwitchingToBle, Colors.orange); + } + } + } + + if (preferredMethod == 'ble' && wifiHardwareAvailable && widget.wal.storage == WalStorage.sdcard) { if (!mounted) return; final result = await FastTransferSuggestionDialog.show(context); if (result == null) return; @@ -550,7 +563,7 @@ class _WalItemDetailPageState extends State { final currentMethod = SharedPreferencesUtil().preferredSyncMethod; if (Platform.isIOS && widget.wal.storage == WalStorage.sdcard) { - if (currentMethod == 'wifi' && wifiSupported) { + if (currentMethod == 'wifi' && wifiHardwareAvailable) { if (!mounted) return; final hasPermission = await LocationPermissionHelper.checkAndRequest(context); if (!hasPermission) { @@ -564,13 +577,12 @@ class _WalItemDetailPageState extends State { try { final syncProvider = context.read(); final currentMethod = SharedPreferencesUtil().preferredSyncMethod; - final wifiSupported = await ServiceManager.instance().wal.getSyncs().sdcard.isWifiSyncSupported(); // Show WiFi connection sheet if using WiFi for SD card transfer - if (currentMethod == 'wifi' && wifiSupported && widget.wal.storage == WalStorage.sdcard && mounted) { + if (currentMethod == 'wifi' && wifiHardwareAvailable && widget.wal.storage == WalStorage.sdcard && mounted) { WifiConnectionListenerBridge? listener; - final controller = await WifiConnectionSheet.show( + final sheetController = await WifiConnectionSheet.show( context, deviceName: 'Omi', onCancel: () { @@ -583,7 +595,7 @@ class _WalItemDetailPageState extends State { }, ); - listener = WifiConnectionListenerBridge(controller); + listener = WifiConnectionListenerBridge(sheetController); await syncProvider.transferWalToPhone(widget.wal, connectionListener: listener); } else { await syncProvider.transferWalToPhone(widget.wal); @@ -600,6 +612,33 @@ class _WalItemDetailPageState extends State { } } + Future _checkWifiHardwareAvailable() async { + try { + final connection = await ServiceManager.instance().device.ensureConnection(widget.wal.device); + if (connection == null) { + return true; + } + + final ssid = WifiNetworkService.generateSsid(widget.wal.device); + final password = WifiNetworkService.generatePassword(widget.wal.device); + + final result = await connection.setupWifiSync(ssid, password); + + if (!result.success && result.errorCode == WifiSyncErrorCode.wifiHardwareNotAvailable) { + return false; + } + + if (result.success) { + await connection.stopWifiSync(); + } + + return true; + } catch (e) { + debugPrint('Error checking WiFi hardware: $e'); + return true; + } + } + void _handleCancelTransfer() { final syncProvider = context.read(); syncProvider.cancelSync(); diff --git a/app/lib/services/devices/wifi_sync_error.dart b/app/lib/services/devices/wifi_sync_error.dart index 87e2b7e8bf..a795be794c 100644 --- a/app/lib/services/devices/wifi_sync_error.dart +++ b/app/lib/services/devices/wifi_sync_error.dart @@ -4,6 +4,7 @@ enum WifiSyncErrorCode { invalidSetupLength(0x02), ssidLengthInvalid(0x03), passwordLengthInvalid(0x04), + sessionAlreadyRunning(0x05), wifiHardwareNotAvailable(0xFE), unknownCommand(0xFF); @@ -29,6 +30,8 @@ enum WifiSyncErrorCode { return 'Device name must be 1-32 characters'; case WifiSyncErrorCode.passwordLengthInvalid: return 'Password must be 8-63 characters'; + case WifiSyncErrorCode.sessionAlreadyRunning: + return 'Previous sync session is still running'; case WifiSyncErrorCode.wifiHardwareNotAvailable: return 'Your device does not support WiFi sync'; case WifiSyncErrorCode.unknownCommand: diff --git a/app/lib/services/wals/sdcard_wal_sync.dart b/app/lib/services/wals/sdcard_wal_sync.dart index f02b0cdeac..23305ff037 100644 --- a/app/lib/services/wals/sdcard_wal_sync.dart +++ b/app/lib/services/wals/sdcard_wal_sync.dart @@ -204,7 +204,12 @@ class SDCardWalSyncImpl implements SDCardWalSync { @override Future start() async { + final syncingWal = _wals.where((w) => w.isSyncing).firstOrNull; _wals = await _getMissingWals(); + // Re-add the syncing WAL if it was lost + if (syncingWal != null && !_wals.any((w) => w.id == syncingWal.id)) { + _wals = [syncingWal, ..._wals]; + } listener.onWalUpdated(); } @@ -621,7 +626,12 @@ class SDCardWalSyncImpl implements SDCardWalSync { @override void setDevice(BtDevice? device) async { _device = device; + final syncingWal = _wals.where((w) => w.isSyncing).firstOrNull; _wals = await _getMissingWals(); + // Re-add the syncing WAL if it was lost + if (syncingWal != null && !_wals.any((w) => w.id == syncingWal.id)) { + _wals = [syncingWal, ..._wals]; + } listener.onWalUpdated(); } @@ -760,7 +770,16 @@ class SDCardWalSyncImpl implements SDCardWalSync { connectionListener?.onEnablingDeviceWifi(); debugPrint("SDCardWalSync WiFi: Step 1 - Configuring device AP with SSID: $ssid"); - final setupResult = await connection.setupWifiSync(ssid, password); + var setupResult = await connection.setupWifiSync(ssid, password); + + // If a previous session is still running, stop it and retry + if (!setupResult.success && setupResult.errorCode == WifiSyncErrorCode.sessionAlreadyRunning) { + debugPrint("SDCardWalSync WiFi: Previous session running, stopping it first..."); + await connection.stopWifiSync(); + await Future.delayed(const Duration(seconds: 1)); + setupResult = await connection.setupWifiSync(ssid, password); + } + if (!setupResult.success) { _resetSyncState(); final errorMessage = setupResult.errorMessage ?? 'Failed to setup WiFi on device'; @@ -789,6 +808,10 @@ class SDCardWalSyncImpl implements SDCardWalSync { // Notify: Connecting to device connectionListener?.onConnectingToDevice(); + // Wait for device to set up its WiFi AP before phone tries to connect + debugPrint("SDCardWalSync WiFi: Step 3 - Waiting for device AP to become available..."); + await Future.delayed(const Duration(seconds: 3)); + debugPrint("SDCardWalSync WiFi: Step 4 - Connecting phone to device WiFi AP"); final wifiResult = await wifiNetwork.connectToAp(ssid, password: password); if (!wifiResult.success) {