|
@@ -2,6 +2,7 @@ import 'package:auto_route/auto_route.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/material.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/modules/backup/providers/error_backup_list.provider.dart';
|
|
import 'package:immich_mobile/modules/login/models/authentication_state.model.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/backup/models/backup_state.model.dart';
|
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
|
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
|
|
@@ -9,6 +10,7 @@ import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
|
|
import 'package:immich_mobile/routing/router.dart';
|
|
import 'package:immich_mobile/routing/router.dart';
|
|
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
|
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
|
|
import 'package:immich_mobile/modules/backup/ui/backup_info_card.dart';
|
|
import 'package:immich_mobile/modules/backup/ui/backup_info_card.dart';
|
|
|
|
+import 'package:intl/intl.dart';
|
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
|
|
|
|
|
class BackupControllerPage extends HookConsumerWidget {
|
|
class BackupControllerPage extends HookConsumerWidget {
|
|
@@ -42,7 +44,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
color: Theme.of(context).primaryColor,
|
|
color: Theme.of(context).primaryColor,
|
|
),
|
|
),
|
|
title: const Text(
|
|
title: const Text(
|
|
- "Server Storage",
|
|
|
|
|
|
+ "Server storage",
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
|
|
),
|
|
),
|
|
subtitle: Padding(
|
|
subtitle: Padding(
|
|
@@ -56,7 +58,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
padding:
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
|
const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
|
barRadius: const Radius.circular(2),
|
|
barRadius: const Radius.circular(2),
|
|
- lineHeight: 6.0,
|
|
|
|
|
|
+ lineHeight: 10.0,
|
|
percent: backupState.serverInfo.diskUsagePercentage / 100.0,
|
|
percent: backupState.serverInfo.diskUsagePercentage / 100.0,
|
|
backgroundColor: Colors.grey,
|
|
backgroundColor: Colors.grey,
|
|
progressColor: Theme.of(context).primaryColor,
|
|
progressColor: Theme.of(context).primaryColor,
|
|
@@ -246,6 +248,141 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ _buildCurrentBackupAssetInfoCard() {
|
|
|
|
+ return ListTile(
|
|
|
|
+ leading: Icon(
|
|
|
|
+ Icons.info_outline_rounded,
|
|
|
|
+ color: Theme.of(context).primaryColor,
|
|
|
|
+ ),
|
|
|
|
+ title: Row(
|
|
|
|
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
+ children: [
|
|
|
|
+ const Text(
|
|
|
|
+ "Uploading file info",
|
|
|
|
+ style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),
|
|
|
|
+ ),
|
|
|
|
+ if (ref.watch(errorBackupListProvider).isNotEmpty)
|
|
|
|
+ ActionChip(
|
|
|
|
+ avatar: Icon(
|
|
|
|
+ Icons.info,
|
|
|
|
+ size: 24,
|
|
|
|
+ color: Colors.red[400],
|
|
|
|
+ ),
|
|
|
|
+ elevation: 1,
|
|
|
|
+ visualDensity: VisualDensity.compact,
|
|
|
|
+ label: Text(
|
|
|
|
+ "Failed (${ref.watch(errorBackupListProvider).length})",
|
|
|
|
+ style: TextStyle(
|
|
|
|
+ color: Colors.red[400],
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ fontSize: 11,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ backgroundColor: Colors.white,
|
|
|
|
+ onPressed: () {
|
|
|
|
+ AutoRouter.of(context).push(const FailedBackupStatusRoute());
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ subtitle: Column(
|
|
|
|
+ children: [
|
|
|
|
+ Padding(
|
|
|
|
+ padding: const EdgeInsets.only(top: 8.0),
|
|
|
|
+ child: LinearPercentIndicator(
|
|
|
|
+ padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
|
|
|
|
+ barRadius: const Radius.circular(2),
|
|
|
|
+ lineHeight: 10.0,
|
|
|
|
+ trailing: Text(
|
|
|
|
+ " ${backupState.progressInPercentage.toStringAsFixed(0)}%",
|
|
|
|
+ style: const TextStyle(fontSize: 12),
|
|
|
|
+ ),
|
|
|
|
+ percent: backupState.progressInPercentage / 100.0,
|
|
|
|
+ backgroundColor: Colors.grey,
|
|
|
|
+ progressColor: Theme.of(context).primaryColor,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ Padding(
|
|
|
|
+ padding: const EdgeInsets.only(top: 8.0),
|
|
|
|
+ child: Table(
|
|
|
|
+ border: TableBorder.all(
|
|
|
|
+ color: Colors.black12,
|
|
|
|
+ width: 1,
|
|
|
|
+ ),
|
|
|
|
+ children: [
|
|
|
|
+ TableRow(
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ color: Colors.grey[100],
|
|
|
|
+ ),
|
|
|
|
+ children: [
|
|
|
|
+ TableCell(
|
|
|
|
+ verticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
|
+ child: Padding(
|
|
|
|
+ padding: const EdgeInsets.all(6.0),
|
|
|
|
+ child: Text(
|
|
|
|
+ 'File name: ${backupState.currentUploadAsset.fileName} [${backupState.currentUploadAsset.fileType.toLowerCase()}]',
|
|
|
|
+ style: const TextStyle(
|
|
|
|
+ fontWeight: FontWeight.bold, fontSize: 10.0),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ TableRow(
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ color: Colors.grey[200],
|
|
|
|
+ ),
|
|
|
|
+ children: [
|
|
|
|
+ TableCell(
|
|
|
|
+ verticalAlignment: TableCellVerticalAlignment.middle,
|
|
|
|
+ child: Padding(
|
|
|
|
+ padding: const EdgeInsets.all(6.0),
|
|
|
|
+ child: Text(
|
|
|
|
+ "Created on: ${DateFormat.yMMMMd('en_US').format(
|
|
|
|
+ DateTime.parse(
|
|
|
|
+ backupState.currentUploadAsset.createdAt
|
|
|
|
+ .toString(),
|
|
|
|
+ ),
|
|
|
|
+ )}",
|
|
|
|
+ style: const TextStyle(
|
|
|
|
+ fontWeight: FontWeight.bold, fontSize: 10.0),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ TableRow(
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
+ color: Colors.grey[100],
|
|
|
|
+ ),
|
|
|
|
+ children: [
|
|
|
|
+ TableCell(
|
|
|
|
+ child: Padding(
|
|
|
|
+ padding: const EdgeInsets.all(6.0),
|
|
|
|
+ child: Text(
|
|
|
|
+ "ID: ${backupState.currentUploadAsset.id}",
|
|
|
|
+ style: const TextStyle(
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ fontSize: 10.0,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
|
|
+ ],
|
|
|
|
+ ),
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void startBackup() {
|
|
|
|
+ ref.watch(errorBackupListProvider.notifier).empty();
|
|
|
|
+ ref.watch(backupProvider.notifier).startBackupProcess();
|
|
|
|
+ }
|
|
|
|
+
|
|
return Scaffold(
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
appBar: AppBar(
|
|
elevation: 0,
|
|
elevation: 0,
|
|
@@ -264,7 +401,7 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
)),
|
|
)),
|
|
),
|
|
),
|
|
body: Padding(
|
|
body: Padding(
|
|
- padding: const EdgeInsets.all(16.0),
|
|
|
|
|
|
+ padding: const EdgeInsets.only(left: 16.0, right: 16, bottom: 32),
|
|
child: ListView(
|
|
child: ListView(
|
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
children: [
|
|
@@ -297,23 +434,11 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
const Divider(),
|
|
const Divider(),
|
|
_buildStorageInformation(),
|
|
_buildStorageInformation(),
|
|
const Divider(),
|
|
const Divider(),
|
|
|
|
+ _buildCurrentBackupAssetInfoCard(),
|
|
Padding(
|
|
Padding(
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
|
- child: Text(
|
|
|
|
- "Asset that were being backup: ${backupState.allUniqueAssets.length - backupState.selectedAlbumsBackupAssetsIds.length} [${backupState.progressInPercentage.toStringAsFixed(0)}%]"),
|
|
|
|
- ),
|
|
|
|
- Padding(
|
|
|
|
- padding: const EdgeInsets.only(left: 8.0),
|
|
|
|
- child: Row(children: [
|
|
|
|
- const Text("Backup Progress:"),
|
|
|
|
- const Padding(padding: EdgeInsets.symmetric(horizontal: 2)),
|
|
|
|
- backupState.backupProgress == BackUpProgressEnum.inProgress
|
|
|
|
- ? const CircularProgressIndicator.adaptive()
|
|
|
|
- : const Text("Done"),
|
|
|
|
- ]),
|
|
|
|
- ),
|
|
|
|
- Padding(
|
|
|
|
- padding: const EdgeInsets.all(8.0),
|
|
|
|
|
|
+ padding: const EdgeInsets.only(
|
|
|
|
+ top: 24,
|
|
|
|
+ ),
|
|
child: Container(
|
|
child: Container(
|
|
child:
|
|
child:
|
|
backupState.backupProgress == BackUpProgressEnum.inProgress
|
|
backupState.backupProgress == BackUpProgressEnum.inProgress
|
|
@@ -321,25 +446,33 @@ class BackupControllerPage extends HookConsumerWidget {
|
|
style: ElevatedButton.styleFrom(
|
|
style: ElevatedButton.styleFrom(
|
|
primary: Colors.red[300],
|
|
primary: Colors.red[300],
|
|
onPrimary: Colors.grey[50],
|
|
onPrimary: Colors.grey[50],
|
|
|
|
+ padding: const EdgeInsets.all(14),
|
|
),
|
|
),
|
|
onPressed: () {
|
|
onPressed: () {
|
|
ref.read(backupProvider.notifier).cancelBackup();
|
|
ref.read(backupProvider.notifier).cancelBackup();
|
|
},
|
|
},
|
|
- child: const Text("Cancel"),
|
|
|
|
|
|
+ child: const Text(
|
|
|
|
+ "CANCEL",
|
|
|
|
+ style: TextStyle(
|
|
|
|
+ fontSize: 14,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ ),
|
|
|
|
+ ),
|
|
)
|
|
)
|
|
: ElevatedButton(
|
|
: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
style: ElevatedButton.styleFrom(
|
|
primary: Theme.of(context).primaryColor,
|
|
primary: Theme.of(context).primaryColor,
|
|
onPrimary: Colors.grey[50],
|
|
onPrimary: Colors.grey[50],
|
|
|
|
+ padding: const EdgeInsets.all(14),
|
|
|
|
+ ),
|
|
|
|
+ onPressed: shouldBackup ? startBackup : null,
|
|
|
|
+ child: const Text(
|
|
|
|
+ "START BACKUP",
|
|
|
|
+ style: TextStyle(
|
|
|
|
+ fontSize: 14,
|
|
|
|
+ fontWeight: FontWeight.bold,
|
|
|
|
+ ),
|
|
),
|
|
),
|
|
- onPressed: shouldBackup
|
|
|
|
- ? () {
|
|
|
|
- ref
|
|
|
|
- .read(backupProvider.notifier)
|
|
|
|
- .startBackupProcess();
|
|
|
|
- }
|
|
|
|
- : null,
|
|
|
|
- child: const Text("Start Backup"),
|
|
|
|
),
|
|
),
|
|
),
|
|
),
|
|
)
|
|
)
|