mirror of
https://github.com/immich-app/immich.git
synced 2024-11-20 18:15:52 +02:00
refactor(mobile): backup info box (#14171)
split up backup info box into separate widgets
This commit is contained in:
parent
6729782c3f
commit
caf6c0996d
@ -21,6 +21,7 @@ const Color immichBrandColorLight = Color(0xFF4150AF);
|
||||
const Color immichBrandColorDark = Color(0xFFACCBFA);
|
||||
const Color whiteOpacity75 = Color.fromARGB((0.75 * 255) ~/ 1, 255, 255, 255);
|
||||
const Color blackOpacity90 = Color.fromARGB((0.90 * 255) ~/ 1, 0, 0, 0);
|
||||
const Color red400 = Color(0xFFEF5350);
|
||||
|
||||
final Map<ImmichColorPreset, ImmichTheme> _themePresetsMap = {
|
||||
ImmichColorPreset.indigo: ImmichTheme(
|
||||
|
@ -18,6 +18,9 @@ class CurrentUploadAsset {
|
||||
this.iCloudAsset,
|
||||
});
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
bool get isIcloudAsset => iCloudAsset != null && iCloudAsset!;
|
||||
|
||||
CurrentUploadAsset copyWith({
|
||||
String? id,
|
||||
DateTime? fileCreatedAt,
|
||||
|
102
mobile/lib/widgets/backup/asset_info_table.dart
Normal file
102
mobile/lib/widgets/backup/asset_info_table.dart
Normal file
@ -0,0 +1,102 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
import 'package:immich_mobile/models/backup/current_upload_asset.model.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
|
||||
|
||||
class BackupAssetInfoTable extends ConsumerWidget {
|
||||
const BackupAssetInfoTable({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isManualUpload = ref.watch(
|
||||
backupProvider.select(
|
||||
(value) => value.backupProgress == BackUpProgressEnum.manualInProgress,
|
||||
),
|
||||
);
|
||||
|
||||
final asset = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider.select((value) => value.currentUploadAsset),
|
||||
)
|
||||
: ref.watch(backupProvider.select((value) => value.currentUploadAsset));
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Table(
|
||||
border: TableBorder.all(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
width: 1,
|
||||
),
|
||||
children: [
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
'backup_controller_page_filename',
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(
|
||||
args: [asset.fileName, asset.fileType.toLowerCase()],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
"backup_controller_page_created",
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(
|
||||
args: [_getAssetCreationDate(asset)],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
"backup_controller_page_id",
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(args: [asset.id]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
String _getAssetCreationDate(CurrentUploadAsset asset) {
|
||||
return DateFormat.yMMMMd().format(asset.fileCreatedAt.toLocal());
|
||||
}
|
||||
}
|
@ -1,296 +1,43 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
|
||||
import 'package:immich_mobile/repositories/asset_media.repository.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_thumbnail.dart';
|
||||
import 'package:immich_mobile/widgets/backup/asset_info_table.dart';
|
||||
import 'package:immich_mobile/widgets/backup/error_chip.dart';
|
||||
import 'package:immich_mobile/widgets/backup/icloud_download_progress_bar.dart';
|
||||
import 'package:immich_mobile/widgets/backup/upload_progress_bar.dart';
|
||||
import 'package:immich_mobile/widgets/backup/upload_stats.dart';
|
||||
|
||||
class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
|
||||
class CurrentUploadingAssetInfoBox extends StatelessWidget {
|
||||
const CurrentUploadingAssetInfoBox({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
var isManualUpload = ref.watch(backupProvider).backupProgress ==
|
||||
BackUpProgressEnum.manualInProgress;
|
||||
var asset = !isManualUpload
|
||||
? ref.watch(backupProvider).currentUploadAsset
|
||||
: ref.watch(manualUploadProvider).currentUploadAsset;
|
||||
var uploadProgress = !isManualUpload
|
||||
? ref.watch(backupProvider).progressInPercentage
|
||||
: ref.watch(manualUploadProvider).progressInPercentage;
|
||||
var uploadFileProgress = !isManualUpload
|
||||
? ref.watch(backupProvider).progressInFileSize
|
||||
: ref.watch(manualUploadProvider).progressInFileSize;
|
||||
var uploadFileSpeed = !isManualUpload
|
||||
? ref.watch(backupProvider).progressInFileSpeed
|
||||
: ref.watch(manualUploadProvider).progressInFileSpeed;
|
||||
var iCloudDownloadProgress =
|
||||
ref.watch(backupProvider).iCloudDownloadProgress;
|
||||
final isShowThumbnail = useState(false);
|
||||
|
||||
String formatUploadFileSpeed(double uploadFileSpeed) {
|
||||
if (uploadFileSpeed < 1024) {
|
||||
return '${uploadFileSpeed.toStringAsFixed(2)} B/s';
|
||||
} else if (uploadFileSpeed < 1024 * 1024) {
|
||||
return '${(uploadFileSpeed / 1024).toStringAsFixed(2)} KB/s';
|
||||
} else if (uploadFileSpeed < 1024 * 1024 * 1024) {
|
||||
return '${(uploadFileSpeed / (1024 * 1024)).toStringAsFixed(2)} MB/s';
|
||||
} else {
|
||||
return '${(uploadFileSpeed / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB/s';
|
||||
}
|
||||
}
|
||||
|
||||
String getAssetCreationDate() {
|
||||
return DateFormat.yMMMMd().format(
|
||||
DateTime.parse(
|
||||
asset.fileCreatedAt.toString(),
|
||||
).toLocal(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildErrorChip() {
|
||||
return ActionChip(
|
||||
avatar: Icon(
|
||||
Icons.info,
|
||||
color: Colors.red[400],
|
||||
),
|
||||
elevation: 1,
|
||||
visualDensity: VisualDensity.compact,
|
||||
label: Text(
|
||||
"backup_controller_page_failed",
|
||||
style: TextStyle(
|
||||
color: Colors.red[400],
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 11,
|
||||
),
|
||||
).tr(
|
||||
args: [ref.watch(errorBackupListProvider).length.toString()],
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
onPressed: () => context.pushRoute(const FailedBackupStatusRoute()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAssetInfoTable() {
|
||||
return Table(
|
||||
border: TableBorder.all(
|
||||
color: context.colorScheme.outlineVariant,
|
||||
width: 1,
|
||||
),
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
isThreeLine: true,
|
||||
leading: Icon(
|
||||
Icons.image_outlined,
|
||||
color: context.primaryColor,
|
||||
size: 30,
|
||||
),
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
'backup_controller_page_filename',
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(
|
||||
args: [asset.fileName, asset.fileType.toLowerCase()],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
verticalAlignment: TableCellVerticalAlignment.middle,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
"backup_controller_page_created",
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(
|
||||
args: [getAssetCreationDate()],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
TableCell(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(6.0),
|
||||
child: Text(
|
||||
"backup_controller_page_id",
|
||||
style: TextStyle(
|
||||
color: context.colorScheme.onSurfaceSecondary,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
).tr(args: [asset.id]),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
"backup_controller_page_uploading_file_info",
|
||||
style: context.textTheme.titleSmall,
|
||||
).tr(),
|
||||
const BackupErrorChip(),
|
||||
],
|
||||
),
|
||||
subtitle: Column(
|
||||
children: [
|
||||
if (Platform.isIOS) const IcloudDownloadProgressBar(),
|
||||
const BackupUploadProgressBar(),
|
||||
const BackupUploadStats(),
|
||||
const BackupAssetInfoTable(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
buildiCloudDownloadProgerssBar() {
|
||||
if (asset.iCloudAsset != null && asset.iCloudAsset!) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
"iCloud Download",
|
||||
style: context.textTheme.labelSmall,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: 10.0,
|
||||
value: uploadProgress / 100.0,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
" ${iCloudDownloadProgress.toStringAsFixed(0)}%",
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
buildUploadProgressBar() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
if (asset.iCloudAsset != null && asset.iCloudAsset!)
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
"Immich Upload",
|
||||
style: context.textTheme.labelSmall,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: 10.0,
|
||||
value: uploadProgress / 100.0,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
" ${uploadProgress.toStringAsFixed(0)}%",
|
||||
style: const TextStyle(fontSize: 12, fontFamily: "OverpassMono"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
buildUploadStats() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
uploadFileProgress,
|
||||
style: const TextStyle(fontSize: 10, fontFamily: "OverpassMono"),
|
||||
),
|
||||
Text(
|
||||
formatUploadFileSpeed(uploadFileSpeed),
|
||||
style: const TextStyle(fontSize: 10, fontFamily: "OverpassMono"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return FutureBuilder<Asset?>(
|
||||
future: ref.read(assetMediaRepositoryProvider).get(asset.id),
|
||||
builder: (context, thumbnail) => ListTile(
|
||||
isThreeLine: true,
|
||||
leading: AnimatedCrossFade(
|
||||
alignment: Alignment.centerLeft,
|
||||
firstChild: GestureDetector(
|
||||
onTap: () => isShowThumbnail.value = false,
|
||||
child: thumbnail.hasData
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: ImmichThumbnail(
|
||||
asset: thumbnail.data,
|
||||
width: 50,
|
||||
height: 50,
|
||||
),
|
||||
)
|
||||
: const SizedBox(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
secondChild: GestureDetector(
|
||||
onTap: () => isShowThumbnail.value = true,
|
||||
child: Icon(
|
||||
Icons.image_outlined,
|
||||
color: context.primaryColor,
|
||||
size: 30,
|
||||
),
|
||||
),
|
||||
crossFadeState: isShowThumbnail.value
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
),
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"backup_controller_page_uploading_file_info",
|
||||
style: context.textTheme.titleSmall,
|
||||
).tr(),
|
||||
if (ref.watch(errorBackupListProvider).isNotEmpty) buildErrorChip(),
|
||||
],
|
||||
),
|
||||
subtitle: Column(
|
||||
children: [
|
||||
if (Platform.isIOS) buildiCloudDownloadProgerssBar(),
|
||||
buildUploadProgressBar(),
|
||||
buildUploadStats(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: buildAssetInfoTable(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
32
mobile/lib/widgets/backup/error_chip.dart
Normal file
32
mobile/lib/widgets/backup/error_chip.dart
Normal file
@ -0,0 +1,32 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/widgets/backup/error_chip_text.dart';
|
||||
|
||||
class BackupErrorChip extends ConsumerWidget {
|
||||
const BackupErrorChip({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final hasErrors =
|
||||
ref.watch(errorBackupListProvider.select((value) => value.isNotEmpty));
|
||||
if (!hasErrors) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return ActionChip(
|
||||
avatar: const Icon(
|
||||
Icons.info,
|
||||
color: red400,
|
||||
),
|
||||
elevation: 1,
|
||||
visualDensity: VisualDensity.compact,
|
||||
label: const BackupErrorChipText(),
|
||||
backgroundColor: Colors.white,
|
||||
onPressed: () => context.pushRoute(const FailedBackupStatusRoute()),
|
||||
);
|
||||
}
|
||||
}
|
28
mobile/lib/widgets/backup/error_chip_text.dart
Normal file
28
mobile/lib/widgets/backup/error_chip_text.dart
Normal file
@ -0,0 +1,28 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/immich_colors.dart';
|
||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
|
||||
|
||||
class BackupErrorChipText extends ConsumerWidget {
|
||||
const BackupErrorChipText({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final count = ref.watch(errorBackupListProvider).length;
|
||||
if (count == 0) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
return const Text(
|
||||
"backup_controller_page_failed",
|
||||
style: TextStyle(
|
||||
color: red400,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 11,
|
||||
),
|
||||
).tr(
|
||||
args: [count.toString()],
|
||||
);
|
||||
}
|
||||
}
|
61
mobile/lib/widgets/backup/icloud_download_progress_bar.dart
Normal file
61
mobile/lib/widgets/backup/icloud_download_progress_bar.dart
Normal file
@ -0,0 +1,61 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
|
||||
|
||||
class IcloudDownloadProgressBar extends ConsumerWidget {
|
||||
const IcloudDownloadProgressBar({super.key});
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isManualUpload = ref.watch(
|
||||
backupProvider.select(
|
||||
(value) => value.backupProgress == BackUpProgressEnum.manualInProgress,
|
||||
),
|
||||
);
|
||||
|
||||
final isIcloudAsset = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider
|
||||
.select((value) => value.currentUploadAsset.isIcloudAsset),
|
||||
)
|
||||
: ref.watch(
|
||||
backupProvider
|
||||
.select((value) => value.currentUploadAsset.isIcloudAsset),
|
||||
);
|
||||
|
||||
if (!isIcloudAsset) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
final iCloudDownloadProgress = ref
|
||||
.watch(backupProvider.select((value) => value.iCloudDownloadProgress));
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
"iCloud Download",
|
||||
style: context.textTheme.labelSmall,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: 10.0,
|
||||
value: iCloudDownloadProgress / 100.0,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
" ${iCloudDownloadProgress ~/ 1}%",
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
64
mobile/lib/widgets/backup/upload_progress_bar.dart
Normal file
64
mobile/lib/widgets/backup/upload_progress_bar.dart
Normal file
@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
|
||||
|
||||
class BackupUploadProgressBar extends ConsumerWidget {
|
||||
const BackupUploadProgressBar({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isManualUpload = ref.watch(
|
||||
backupProvider.select(
|
||||
(value) => value.backupProgress == BackUpProgressEnum.manualInProgress,
|
||||
),
|
||||
);
|
||||
|
||||
final isIcloudAsset = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider
|
||||
.select((value) => value.currentUploadAsset.isIcloudAsset),
|
||||
)
|
||||
: ref.watch(
|
||||
backupProvider
|
||||
.select((value) => value.currentUploadAsset.isIcloudAsset),
|
||||
);
|
||||
|
||||
final uploadProgress = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider.select((value) => value.progressInPercentage),
|
||||
)
|
||||
: ref.watch(
|
||||
backupProvider.select((value) => value.progressInPercentage),
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
if (isIcloudAsset)
|
||||
SizedBox(
|
||||
width: 110,
|
||||
child: Text(
|
||||
"Immich Upload",
|
||||
style: context.textTheme.labelSmall,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: LinearProgressIndicator(
|
||||
minHeight: 10.0,
|
||||
value: uploadProgress / 100.0,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
" ${uploadProgress.toStringAsFixed(0)}%",
|
||||
style: const TextStyle(fontSize: 12, fontFamily: "OverpassMono"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
62
mobile/lib/widgets/backup/upload_stats.dart
Normal file
62
mobile/lib/widgets/backup/upload_stats.dart
Normal file
@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
|
||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
|
||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
|
||||
|
||||
class BackupUploadStats extends ConsumerWidget {
|
||||
const BackupUploadStats({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isManualUpload = ref.watch(
|
||||
backupProvider.select(
|
||||
(value) => value.backupProgress == BackUpProgressEnum.manualInProgress,
|
||||
),
|
||||
);
|
||||
|
||||
final uploadFileProgress = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider.select((value) => value.progressInFileSize),
|
||||
)
|
||||
: ref.watch(backupProvider.select((value) => value.progressInFileSize));
|
||||
|
||||
final uploadFileSpeed = isManualUpload
|
||||
? ref.watch(
|
||||
manualUploadProvider.select((value) => value.progressInFileSpeed),
|
||||
)
|
||||
: ref.watch(
|
||||
backupProvider.select((value) => value.progressInFileSpeed),
|
||||
);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 2.0, bottom: 2.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
uploadFileProgress,
|
||||
style: const TextStyle(fontSize: 10, fontFamily: "OverpassMono"),
|
||||
),
|
||||
Text(
|
||||
_formatUploadFileSpeed(uploadFileSpeed),
|
||||
style: const TextStyle(fontSize: 10, fontFamily: "OverpassMono"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
String _formatUploadFileSpeed(double uploadFileSpeed) {
|
||||
if (uploadFileSpeed < 1024) {
|
||||
return '${uploadFileSpeed.toStringAsFixed(2)} B/s';
|
||||
} else if (uploadFileSpeed < 1024 * 1024) {
|
||||
return '${(uploadFileSpeed / 1024).toStringAsFixed(2)} KB/s';
|
||||
} else if (uploadFileSpeed < 1024 * 1024 * 1024) {
|
||||
return '${(uploadFileSpeed / (1024 * 1024)).toStringAsFixed(2)} MB/s';
|
||||
} else {
|
||||
return '${(uploadFileSpeed / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB/s';
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user