feat(mobile): iOS background sync ()

* first run of getting background sync working in iOS

* got background sync calling into flutter

* added background task

* added necessary sync files

* fixed some names and added more implementations

* got as far as Hive.initFlutter

* brute force got to await Hive.initFlutter

* lots of print statements to figure out where execution is failing, and its failing at the root asset bundle in the localization.dart service

* first time working, got plugins registered

* removed broken cleanup code

* refactored

* linters

* now can pass user settings

* background service plugin uses app background processing instead of fetch

* renamed backgroundFetch to backgroundProcessing to make it clearer

* don't use max delay

* adds fetch back in

* fixes require charging default values and backup controller page

* fixes background fetch

* fixes ios not importing photos

* guarded path provider ios

* lint

* adds max tries for heartbeat to work in iOS

* fail after seconds

* timeout instead of fail after seconds

* removes release lock from system stop

* restores checkLockReleasedWithHeartbeat to Future<void>

* removes max tries from acquire lock

* fixes lock timeout with iOS

* restored for loop

* adds comments, made the AppRefresh task only run while not requiring network or charge

* fixed compile issue

* now both are registered and added better comments. also added ability for task to cancel itself

* added the podfile and pubspec

* added backup diagnostics to IOS and removed iOS ignored backup options and fixed network connectivity always required

* Added Alex's dev team

* styled debug list item, fixed refresh task not set bug, fixed enable / disable background service on platform channel

---------

Co-authored-by: Marty Fuhry <marty@fuhry.farm>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
martyfuhry 2023-02-20 00:59:50 -05:00 committed by GitHub
parent 2cf42e867c
commit 87fea29e32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 926 additions and 284 deletions
mobile/lib/modules/backup/views

View file

@ -7,6 +7,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/backup/providers/error_backup_list.provider.dart';
import 'package:immich_mobile/modules/backup/ui/current_backup_asset_info_box.dart';
import 'package:immich_mobile/modules/backup/ui/ios_debug_info_tile.dart';
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
@ -195,7 +196,7 @@ class BackupControllerPage extends HookConsumerWidget {
);
}
ListTile buildBackgroundBackupController() {
Widget buildBackgroundBackupController() {
final bool isBackgroundEnabled = backupState.backgroundBackup;
final bool isWifiRequired = backupState.backupRequireWifi;
final bool isChargingRequired = backupState.backupRequireCharging;
@ -240,118 +241,126 @@ class BackupControllerPage extends HookConsumerWidget {
final triggerDelay =
useState(backupDelayToSliderValue(backupState.backupTriggerDelay));
return ListTile(
isThreeLine: true,
leading: isBackgroundEnabled
? Icon(
Icons.cloud_sync_rounded,
color: activeColor,
)
: const Icon(Icons.cloud_sync_rounded),
title: Text(
isBackgroundEnabled
? "backup_controller_page_background_is_on"
: "backup_controller_page_background_is_off",
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
).tr(),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isBackgroundEnabled)
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child:
const Text("backup_controller_page_background_description")
.tr(),
),
if (isBackgroundEnabled)
SwitchListTile(
title:
const Text("backup_controller_page_background_wifi").tr(),
secondary: Icon(
Icons.wifi,
color: isWifiRequired ? activeColor : null,
),
dense: true,
activeColor: activeColor,
value: isWifiRequired,
onChanged: hasExclusiveAccess
? (isChecked) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
requireWifi: isChecked,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
)
: null,
),
if (isBackgroundEnabled)
SwitchListTile(
title: const Text("backup_controller_page_background_charging")
.tr(),
secondary: Icon(
Icons.charging_station,
color: isChargingRequired ? activeColor : null,
),
dense: true,
activeColor: activeColor,
value: isChargingRequired,
onChanged: hasExclusiveAccess
? (isChecked) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
requireCharging: isChecked,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
)
: null,
),
if (isBackgroundEnabled)
ListTile(
isThreeLine: false,
dense: true,
enabled: hasExclusiveAccess,
title: const Text(
'backup_controller_page_background_delay',
style: TextStyle(
fontWeight: FontWeight.bold,
return Column(
children: [
ListTile(
isThreeLine: true,
leading: isBackgroundEnabled
? Icon(
Icons.cloud_sync_rounded,
color: activeColor,
)
: const Icon(Icons.cloud_sync_rounded),
title: Text(
isBackgroundEnabled
? "backup_controller_page_background_is_on"
: "backup_controller_page_background_is_off",
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
).tr(),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isBackgroundEnabled)
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child:
const Text("backup_controller_page_background_description")
.tr(),
),
).tr(args: [formatBackupDelaySliderValue(triggerDelay.value)]),
subtitle: Slider(
value: triggerDelay.value,
onChanged: hasExclusiveAccess
? (double v) => triggerDelay.value = v
: null,
onChangeEnd: (double v) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
triggerDelay: backupDelayToMilliseconds(v),
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
if (isBackgroundEnabled && Platform.isAndroid)
SwitchListTile(
title:
const Text("backup_controller_page_background_wifi").tr(),
secondary: Icon(
Icons.wifi,
color: isWifiRequired ? activeColor : null,
),
dense: true,
activeColor: activeColor,
value: isWifiRequired,
onChanged: hasExclusiveAccess
? (isChecked) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
requireWifi: isChecked,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
)
: null,
),
if (isBackgroundEnabled)
SwitchListTile(
title: const Text("backup_controller_page_background_charging")
.tr(),
secondary: Icon(
Icons.charging_station,
color: isChargingRequired ? activeColor : null,
),
dense: true,
activeColor: activeColor,
value: isChargingRequired,
onChanged: hasExclusiveAccess
? (isChecked) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
requireCharging: isChecked,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
)
: null,
),
if (isBackgroundEnabled && Platform.isAndroid)
ListTile(
isThreeLine: false,
dense: true,
enabled: hasExclusiveAccess,
title: const Text(
'backup_controller_page_background_delay',
style: TextStyle(
fontWeight: FontWeight.bold,
),
max: 3.0,
divisions: 3,
label: formatBackupDelaySliderValue(triggerDelay.value),
activeColor: Theme.of(context).primaryColor,
).tr(args: [formatBackupDelaySliderValue(triggerDelay.value)]),
subtitle: Slider(
value: triggerDelay.value,
onChanged: hasExclusiveAccess
? (double v) => triggerDelay.value = v
: null,
onChangeEnd: (double v) => ref
.read(backupProvider.notifier)
.configureBackgroundBackup(
triggerDelay: backupDelayToMilliseconds(v),
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
),
max: 3.0,
divisions: 3,
label: formatBackupDelaySliderValue(triggerDelay.value),
activeColor: Theme.of(context).primaryColor,
),
),
ElevatedButton(
onPressed: () =>
ref.read(backupProvider.notifier).configureBackgroundBackup(
enabled: !isBackgroundEnabled,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
),
child: Text(
isBackgroundEnabled
? "backup_controller_page_background_turn_off"
: "backup_controller_page_background_turn_on",
style:
const TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
).tr(),
),
),
ElevatedButton(
onPressed: () =>
ref.read(backupProvider.notifier).configureBackgroundBackup(
enabled: !isBackgroundEnabled,
onError: showErrorToUser,
onBatteryInfo: showBatteryOptimizationInfoToUser,
),
child: Text(
isBackgroundEnabled
? "backup_controller_page_background_turn_off"
: "backup_controller_page_background_turn_on",
style:
const TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
).tr(),
],
),
],
),
),
if (isBackgroundEnabled)
IosDebugInfoTile(
key: ValueKey(isChargingRequired),
),
],
);
}
@ -592,8 +601,8 @@ class BackupControllerPage extends HookConsumerWidget {
),
const Divider(),
buildAutoBackupController(),
if (Platform.isAndroid) const Divider(),
if (Platform.isAndroid) buildBackgroundBackupController(),
const Divider(),
buildBackgroundBackupController(),
const Divider(),
buildStorageInformation(),
const Divider(),