mirror of
https://github.com/immich-app/immich.git
synced 2025-01-27 22:22:45 +01:00
feat(mobile): darken screen on backup page (#11623)
* feat: keep screen active on backup * show dialog * improve dialog and use shared timer * get rid of confirmation dialog * fix timer logic * fix: set timeout to 60 seconds * fix: revert unwanted change * fix: properly hide status bar * remove unwanted change * fix: properly restore status bar when waking up * clean up --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
501485d0b1
commit
b1587a5dee
1 changed files with 131 additions and 61 deletions
|
@ -1,9 +1,11 @@
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
|
@ -29,6 +31,9 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||||
BackUpState backupState = ref.watch(backupProvider);
|
BackUpState backupState = ref.watch(backupProvider);
|
||||||
final hasAnyAlbum = backupState.selectedBackupAlbums.isNotEmpty;
|
final hasAnyAlbum = backupState.selectedBackupAlbums.isNotEmpty;
|
||||||
final didGetBackupInfo = useState(false);
|
final didGetBackupInfo = useState(false);
|
||||||
|
final isScreenDarkened = useState(false);
|
||||||
|
final darkenScreenTimer = useRef<Timer?>(null);
|
||||||
|
|
||||||
bool hasExclusiveAccess =
|
bool hasExclusiveAccess =
|
||||||
backupState.backupProgress != BackUpProgressEnum.inBackground;
|
backupState.backupProgress != BackUpProgressEnum.inBackground;
|
||||||
bool shouldBackup = backupState.allUniqueAssets.length -
|
bool shouldBackup = backupState.allUniqueAssets.length -
|
||||||
|
@ -38,6 +43,25 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||||
? false
|
? false
|
||||||
: true;
|
: true;
|
||||||
|
|
||||||
|
void startScreenDarkenTimer() {
|
||||||
|
darkenScreenTimer.value = Timer(const Duration(seconds: 30), () {
|
||||||
|
isScreenDarkened.value = true;
|
||||||
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopScreenDarkenTimer() {
|
||||||
|
isScreenDarkened.value = false;
|
||||||
|
darkenScreenTimer.value?.cancel();
|
||||||
|
SystemChrome.setEnabledSystemUIMode(
|
||||||
|
SystemUiMode.manual,
|
||||||
|
overlays: [
|
||||||
|
SystemUiOverlay.top,
|
||||||
|
SystemUiOverlay.bottom,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
// Update the background settings information just to make sure we
|
// Update the background settings information just to make sure we
|
||||||
|
@ -52,8 +76,11 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||||
.stopListenToEvent('on_upload_success');
|
.stopListenToEvent('on_upload_success');
|
||||||
|
|
||||||
WakelockPlus.enable();
|
WakelockPlus.enable();
|
||||||
|
|
||||||
return () {
|
return () {
|
||||||
WakelockPlus.disable();
|
WakelockPlus.disable();
|
||||||
|
darkenScreenTimer.value?.cancel();
|
||||||
|
isScreenDarkened.value = false;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
|
@ -71,6 +98,19 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||||
[backupState.backupProgress],
|
[backupState.backupProgress],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() {
|
||||||
|
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
|
||||||
|
startScreenDarkenTimer();
|
||||||
|
} else {
|
||||||
|
stopScreenDarkenTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
[backupState.backupProgress],
|
||||||
|
);
|
||||||
|
|
||||||
Widget buildSelectedAlbumName() {
|
Widget buildSelectedAlbumName() {
|
||||||
var text = "backup_controller_page_backup_selected".tr();
|
var text = "backup_controller_page_backup_selected".tr();
|
||||||
var albums = ref.watch(backupProvider).selectedBackupAlbums;
|
var albums = ref.watch(backupProvider).selectedBackupAlbums;
|
||||||
|
@ -257,72 +297,102 @@ class BackupControllerPage extends HookConsumerWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return GestureDetector(
|
||||||
appBar: AppBar(
|
onTap: () {
|
||||||
elevation: 0,
|
if (isScreenDarkened.value) {
|
||||||
title: const Text(
|
stopScreenDarkenTimer();
|
||||||
"backup_controller_page_backup",
|
}
|
||||||
).tr(),
|
if (backupState.backupProgress == BackUpProgressEnum.inProgress) {
|
||||||
leading: IconButton(
|
startScreenDarkenTimer();
|
||||||
onPressed: () {
|
}
|
||||||
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
},
|
||||||
context.maybePop(true);
|
child: AnimatedOpacity(
|
||||||
},
|
opacity: isScreenDarkened.value ? 0.1 : 1.0,
|
||||||
splashRadius: 24,
|
duration: const Duration(seconds: 1),
|
||||||
icon: const Icon(
|
child: Scaffold(
|
||||||
Icons.arrow_back_ios_rounded,
|
appBar: AppBar(
|
||||||
),
|
elevation: 0,
|
||||||
),
|
title: const Text(
|
||||||
actions: [
|
"backup_controller_page_backup",
|
||||||
Padding(
|
).tr(),
|
||||||
padding: const EdgeInsets.only(right: 8.0),
|
leading: IconButton(
|
||||||
child: IconButton(
|
onPressed: () {
|
||||||
onPressed: () => context.pushRoute(const BackupOptionsRoute()),
|
ref.watch(websocketProvider.notifier).listenUploadEvent();
|
||||||
|
context.maybePop(true);
|
||||||
|
},
|
||||||
splashRadius: 24,
|
splashRadius: 24,
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.settings_outlined,
|
Icons.arrow_back_ios_rounded,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
actions: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () =>
|
||||||
|
context.pushRoute(const BackupOptionsRoute()),
|
||||||
|
splashRadius: 24,
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.settings_outlined,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.only(left: 16.0, right: 16, bottom: 32),
|
||||||
|
child: ListView(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: hasAnyAlbum
|
||||||
|
? [
|
||||||
|
buildFolderSelectionTile(),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_total".tr(),
|
||||||
|
subtitle: "backup_controller_page_total_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${backupState.allUniqueAssets.length}",
|
||||||
|
),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_backup".tr(),
|
||||||
|
subtitle: "backup_controller_page_backup_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${backupState.selectedAlbumsBackupAssetsIds.length}",
|
||||||
|
),
|
||||||
|
BackupInfoCard(
|
||||||
|
title: "backup_controller_page_remainder".tr(),
|
||||||
|
subtitle:
|
||||||
|
"backup_controller_page_remainder_sub".tr(),
|
||||||
|
info: ref
|
||||||
|
.watch(backupProvider)
|
||||||
|
.availableAlbums
|
||||||
|
.isEmpty
|
||||||
|
? "..."
|
||||||
|
: "${max(0, backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length)}",
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
const CurrentUploadingAssetInfoBox(),
|
||||||
|
if (!hasExclusiveAccess) buildBackgroundBackupInfo(),
|
||||||
|
buildBackupButton(),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
buildFolderSelectionTile(),
|
||||||
|
if (!didGetBackupInfo.value) buildLoadingIndicator(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 32),
|
|
||||||
child: ListView(
|
|
||||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: hasAnyAlbum
|
|
||||||
? [
|
|
||||||
buildFolderSelectionTile(),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_total".tr(),
|
|
||||||
subtitle: "backup_controller_page_total_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${backupState.allUniqueAssets.length}",
|
|
||||||
),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_backup".tr(),
|
|
||||||
subtitle: "backup_controller_page_backup_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${backupState.selectedAlbumsBackupAssetsIds.length}",
|
|
||||||
),
|
|
||||||
BackupInfoCard(
|
|
||||||
title: "backup_controller_page_remainder".tr(),
|
|
||||||
subtitle: "backup_controller_page_remainder_sub".tr(),
|
|
||||||
info: ref.watch(backupProvider).availableAlbums.isEmpty
|
|
||||||
? "..."
|
|
||||||
: "${max(0, backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length)}",
|
|
||||||
),
|
|
||||||
const Divider(),
|
|
||||||
const CurrentUploadingAssetInfoBox(),
|
|
||||||
if (!hasExclusiveAccess) buildBackgroundBackupInfo(),
|
|
||||||
buildBackupButton(),
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
buildFolderSelectionTile(),
|
|
||||||
if (!didGetBackupInfo.value) buildLoadingIndicator(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue