2022-02-03 18:06:44 +02:00
import ' package:auto_route/auto_route.dart ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter_hooks/flutter_hooks.dart ' ;
import ' package:hooks_riverpod/hooks_riverpod.dart ' ;
import ' package:immich_mobile/modules/login/models/authentication_state.model.dart ' ;
2022-05-06 14:22:23 +02:00
import ' package:immich_mobile/modules/backup/models/backup_state.model.dart ' ;
2022-02-03 18:06:44 +02:00
import ' package:immich_mobile/modules/login/providers/authentication.provider.dart ' ;
2022-05-06 14:22:23 +02:00
import ' package:immich_mobile/modules/backup/providers/backup.provider.dart ' ;
import ' package:immich_mobile/routing/router.dart ' ;
2022-04-03 19:31:45 +02:00
import ' package:immich_mobile/shared/providers/websocket.provider.dart ' ;
2022-05-06 14:22:23 +02:00
import ' package:immich_mobile/modules/backup/ui/backup_info_card.dart ' ;
2022-02-03 18:06:44 +02:00
import ' package:percent_indicator/linear_percent_indicator.dart ' ;
class BackupControllerPage extends HookConsumerWidget {
const BackupControllerPage ( { Key ? key } ) : super ( key: key ) ;
@ override
Widget build ( BuildContext context , WidgetRef ref ) {
2022-05-06 14:22:23 +02:00
BackUpState backupState = ref . watch ( backupProvider ) ;
2022-02-03 18:06:44 +02:00
AuthenticationState _authenticationState = ref . watch ( authenticationProvider ) ;
2022-05-06 14:22:23 +02:00
bool shouldBackup =
backupState . allUniqueAssets . length - backupState . selectedAlbumsBackupAssetsIds . length = = 0 ? false : true ;
2022-02-03 18:06:44 +02:00
useEffect ( ( ) {
2022-05-06 14:22:23 +02:00
if ( backupState . backupProgress ! = BackUpProgressEnum . inProgress ) {
2022-02-03 18:06:44 +02:00
ref . read ( backupProvider . notifier ) . getBackupInfo ( ) ;
}
2022-02-13 23:10:42 +02:00
2022-04-03 19:31:45 +02:00
ref . watch ( websocketProvider . notifier ) . stopListenToEvent ( ' on_upload_success ' ) ;
2022-02-13 23:10:42 +02:00
return null ;
2022-02-03 18:06:44 +02:00
} , [ ] ) ;
Widget _buildStorageInformation ( ) {
return ListTile (
leading: Icon (
Icons . storage_rounded ,
color: Theme . of ( context ) . primaryColor ,
) ,
title: const Text (
" Server Storage " ,
style: TextStyle ( fontWeight: FontWeight . bold , fontSize: 14 ) ,
) ,
subtitle: Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
2022-05-29 05:35:45 +02:00
Padding (
2022-02-03 18:06:44 +02:00
padding: const EdgeInsets . only ( top: 8.0 ) ,
2022-05-29 05:35:45 +02:00
child: LinearPercentIndicator (
padding: const EdgeInsets . symmetric ( horizontal: 0 , vertical: 0 ) ,
barRadius: const Radius . circular ( 2 ) ,
lineHeight: 6.0 ,
percent: backupState . serverInfo . diskUsagePercentage / 100.0 ,
backgroundColor: Colors . grey ,
progressColor: Theme . of ( context ) . primaryColor ,
) ,
2022-02-03 18:06:44 +02:00
) ,
Padding (
padding: const EdgeInsets . only ( top: 12.0 ) ,
2022-05-06 14:22:23 +02:00
child: Text ( ' ${ backupState . serverInfo . diskUse } of ${ backupState . serverInfo . diskSize } used ' ) ,
2022-02-03 18:06:44 +02:00
) ,
] ,
) ,
) ,
) ;
}
ListTile _buildBackupController ( ) {
var backUpOption = _authenticationState . deviceInfo . isAutoBackup ? " on " : " off " ;
var isAutoBackup = _authenticationState . deviceInfo . isAutoBackup ;
var backupBtnText = _authenticationState . deviceInfo . isAutoBackup ? " off " : " on " ;
return ListTile (
isThreeLine: true ,
leading: isAutoBackup
? Icon (
Icons . cloud_done_rounded ,
color: Theme . of ( context ) . primaryColor ,
)
: const Icon ( Icons . cloud_off_rounded ) ,
title: Text (
" Back up is $ backUpOption " ,
style: const TextStyle ( fontWeight: FontWeight . bold , fontSize: 14 ) ,
) ,
subtitle: Padding (
padding: const EdgeInsets . symmetric ( vertical: 8.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
! isAutoBackup
? const Text (
" Turn on backup to automatically upload new assets to the server. " ,
style: TextStyle ( fontSize: 14 ) ,
)
: Container ( ) ,
2022-04-05 06:37:48 +02:00
Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: OutlinedButton (
onPressed: ( ) {
isAutoBackup
? ref . watch ( authenticationProvider . notifier ) . setAutoBackup ( false )
: ref . watch ( authenticationProvider . notifier ) . setAutoBackup ( true ) ;
} ,
child: Text ( " Turn $ backupBtnText Backup " , style: const TextStyle ( fontWeight: FontWeight . bold ) ) ,
) ,
2022-02-03 18:06:44 +02:00
)
] ,
) ,
) ,
) ;
}
2022-05-06 14:22:23 +02:00
Widget _buildSelectedAlbumName ( ) {
var text = " Selected: " ;
var albums = ref . watch ( backupProvider ) . selectedBackupAlbums ;
if ( albums . isNotEmpty ) {
for ( var album in albums ) {
if ( album . name = = " Recent " | | album . name = = " Recents " ) {
text + = " ${ album . name } (All), " ;
} else {
text + = " ${ album . name } , " ;
}
}
return Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: Text (
text . trim ( ) . substring ( 0 , text . length - 2 ) ,
style: TextStyle ( color: Theme . of ( context ) . primaryColor , fontSize: 12 , fontWeight: FontWeight . bold ) ,
) ,
) ;
} else {
return Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: Text (
" None selected " ,
style: TextStyle ( color: Theme . of ( context ) . primaryColor , fontSize: 12 , fontWeight: FontWeight . bold ) ,
) ,
) ;
}
}
Widget _buildExcludedAlbumName ( ) {
var text = " Excluded: " ;
var albums = ref . watch ( backupProvider ) . excludedBackupAlbums ;
if ( albums . isNotEmpty ) {
for ( var album in albums ) {
text + = " ${ album . name } , " ;
}
return Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: Text (
text . trim ( ) . substring ( 0 , text . length - 2 ) ,
style: TextStyle ( color: Colors . red [ 300 ] , fontSize: 12 , fontWeight: FontWeight . bold ) ,
) ,
) ;
} else {
return Container ( ) ;
}
}
_buildFolderSelectionTile ( ) {
return Card (
shape: RoundedRectangleBorder (
borderRadius: BorderRadius . circular ( 5 ) , // if you need this
side: const BorderSide (
color: Colors . black12 ,
width: 1 ,
) ,
) ,
elevation: 0 ,
borderOnForeground: false ,
child: ListTile (
minVerticalPadding: 15 ,
title: const Text ( " Backup Albums " , style: TextStyle ( fontWeight: FontWeight . bold , fontSize: 20 ) ) ,
subtitle: Padding (
padding: const EdgeInsets . only ( top: 8.0 ) ,
child: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
const Text (
" Albums to be backup " ,
style: TextStyle ( color: Color ( 0xFF808080 ) , fontSize: 12 ) ,
) ,
_buildSelectedAlbumName ( ) ,
_buildExcludedAlbumName ( )
] ,
) ,
) ,
trailing: OutlinedButton (
onPressed: ( ) {
AutoRouter . of ( context ) . push ( const BackupAlbumSelectionRoute ( ) ) ;
} ,
child: const Padding (
padding: EdgeInsets . symmetric (
vertical: 16.0 ,
) ,
child: Text (
" Select " ,
style: TextStyle ( fontWeight: FontWeight . bold ) ,
) ,
) ,
) ,
) ,
) ;
}
2022-02-03 18:06:44 +02:00
return Scaffold (
appBar: AppBar (
2022-05-06 14:22:23 +02:00
elevation: 0 ,
2022-02-03 18:06:44 +02:00
title: const Text (
" Backup " ,
2022-05-06 14:22:23 +02:00
style: TextStyle ( fontSize: 16 , fontWeight: FontWeight . bold ) ,
2022-02-03 18:06:44 +02:00
) ,
leading: IconButton (
onPressed: ( ) {
2022-04-03 19:31:45 +02:00
ref . watch ( websocketProvider . notifier ) . listenUploadEvent ( ) ;
2022-02-03 18:06:44 +02:00
AutoRouter . of ( context ) . pop ( true ) ;
} ,
2022-05-06 14:22:23 +02:00
splashRadius: 24 ,
icon: const Icon (
Icons . arrow_back_ios_rounded ,
) ) ,
2022-02-03 18:06:44 +02:00
) ,
body: Padding (
padding: const EdgeInsets . all ( 16.0 ) ,
child: ListView (
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding (
padding: EdgeInsets . all ( 8.0 ) ,
child: Text (
" Backup Information " ,
style: TextStyle ( fontWeight: FontWeight . bold , fontSize: 16 ) ,
) ,
) ,
2022-05-06 14:22:23 +02:00
_buildFolderSelectionTile ( ) ,
2022-02-03 18:06:44 +02:00
BackupInfoCard (
title: " Total " ,
2022-05-06 14:22:23 +02:00
subtitle: " All unique photos and videos from selected albums " ,
info: " ${ backupState . allUniqueAssets . length } " ,
2022-02-03 18:06:44 +02:00
) ,
BackupInfoCard (
title: " Backup " ,
2022-05-06 14:22:23 +02:00
subtitle: " Photos and videos from selected albums that are backup " ,
info: " ${ backupState . selectedAlbumsBackupAssetsIds . length } " ,
2022-02-03 18:06:44 +02:00
) ,
BackupInfoCard (
title: " Remainder " ,
2022-05-06 14:22:23 +02:00
subtitle: " Photos and videos that has not been backing up from selected albums " ,
info: " ${ backupState . allUniqueAssets . length - backupState . selectedAlbumsBackupAssetsIds . length } " ,
2022-02-03 18:06:44 +02:00
) ,
const Divider ( ) ,
_buildBackupController ( ) ,
const Divider ( ) ,
_buildStorageInformation ( ) ,
const Divider ( ) ,
Padding (
padding: const EdgeInsets . all ( 8.0 ) ,
child: Text (
2022-05-06 14:22:23 +02:00
" Asset that were being backup: ${ backupState . allUniqueAssets . length - backupState . selectedAlbumsBackupAssetsIds . length } [ ${ backupState . progressInPercentage . toStringAsFixed ( 0 ) } %] " ) ,
2022-02-03 18:06:44 +02:00
) ,
Padding (
padding: const EdgeInsets . only ( left: 8.0 ) ,
child: Row ( children: [
const Text ( " Backup Progress: " ) ,
const Padding ( padding: EdgeInsets . symmetric ( horizontal: 2 ) ) ,
2022-05-06 14:22:23 +02:00
backupState . backupProgress = = BackUpProgressEnum . inProgress
2022-02-03 18:06:44 +02:00
? const CircularProgressIndicator . adaptive ( )
: const Text ( " Done " ) ,
] ) ,
) ,
Padding (
padding: const EdgeInsets . all ( 8.0 ) ,
child: Container (
2022-05-06 14:22:23 +02:00
child: backupState . backupProgress = = BackUpProgressEnum . inProgress
2022-02-03 18:06:44 +02:00
? ElevatedButton (
style: ElevatedButton . styleFrom ( primary: Colors . red [ 300 ] ) ,
onPressed: ( ) {
ref . read ( backupProvider . notifier ) . cancelBackup ( ) ;
} ,
child: const Text ( " Cancel " ) ,
)
: ElevatedButton (
onPressed: shouldBackup
? ( ) {
ref . read ( backupProvider . notifier ) . startBackupProcess ( ) ;
}
: null ,
child: const Text ( " Start Backup " ) ,
) ,
) ,
)
] ,
) ,
) ,
) ;
}
}