mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-04 03:27:09 -05: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 immichBrandColorDark = Color(0xFFACCBFA);
 | 
				
			||||||
const Color whiteOpacity75 = Color.fromARGB((0.75 * 255) ~/ 1, 255, 255, 255);
 | 
					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 blackOpacity90 = Color.fromARGB((0.90 * 255) ~/ 1, 0, 0, 0);
 | 
				
			||||||
 | 
					const Color red400 = Color(0xFFEF5350);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final Map<ImmichColorPreset, ImmichTheme> _themePresetsMap = {
 | 
					final Map<ImmichColorPreset, ImmichTheme> _themePresetsMap = {
 | 
				
			||||||
  ImmichColorPreset.indigo: ImmichTheme(
 | 
					  ImmichColorPreset.indigo: ImmichTheme(
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,9 @@ class CurrentUploadAsset {
 | 
				
			|||||||
    this.iCloudAsset,
 | 
					    this.iCloudAsset,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @pragma('vm:prefer-inline')
 | 
				
			||||||
 | 
					  bool get isIcloudAsset => iCloudAsset != null && iCloudAsset!;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CurrentUploadAsset copyWith({
 | 
					  CurrentUploadAsset copyWith({
 | 
				
			||||||
    String? id,
 | 
					    String? id,
 | 
				
			||||||
    DateTime? fileCreatedAt,
 | 
					    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,275 +1,26 @@
 | 
				
			|||||||
import 'dart:io';
 | 
					import 'dart:io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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_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/build_context_extensions.dart';
 | 
				
			||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
 | 
					import 'package:immich_mobile/widgets/backup/asset_info_table.dart';
 | 
				
			||||||
import 'package:immich_mobile/models/backup/backup_state.model.dart';
 | 
					import 'package:immich_mobile/widgets/backup/error_chip.dart';
 | 
				
			||||||
import 'package:immich_mobile/providers/backup/backup.provider.dart';
 | 
					import 'package:immich_mobile/widgets/backup/icloud_download_progress_bar.dart';
 | 
				
			||||||
import 'package:immich_mobile/providers/backup/error_backup_list.provider.dart';
 | 
					import 'package:immich_mobile/widgets/backup/upload_progress_bar.dart';
 | 
				
			||||||
import 'package:immich_mobile/providers/backup/manual_upload.provider.dart';
 | 
					import 'package:immich_mobile/widgets/backup/upload_stats.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';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
 | 
					class CurrentUploadingAssetInfoBox extends StatelessWidget {
 | 
				
			||||||
  const CurrentUploadingAssetInfoBox({super.key});
 | 
					  const CurrentUploadingAssetInfoBox({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    var isManualUpload = ref.watch(backupProvider).backupProgress ==
 | 
					    return ListTile(
 | 
				
			||||||
        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,
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        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]),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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,
 | 
					      isThreeLine: true,
 | 
				
			||||||
        leading: AnimatedCrossFade(
 | 
					      leading: Icon(
 | 
				
			||||||
          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,
 | 
					        Icons.image_outlined,
 | 
				
			||||||
        color: context.primaryColor,
 | 
					        color: context.primaryColor,
 | 
				
			||||||
        size: 30,
 | 
					        size: 30,
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
          crossFadeState: isShowThumbnail.value
 | 
					 | 
				
			||||||
              ? CrossFadeState.showFirst
 | 
					 | 
				
			||||||
              : CrossFadeState.showSecond,
 | 
					 | 
				
			||||||
          duration: const Duration(milliseconds: 200),
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      title: Row(
 | 
					      title: Row(
 | 
				
			||||||
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
					        mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
@ -277,21 +28,17 @@ class CurrentUploadingAssetInfoBox extends HookConsumerWidget {
 | 
				
			|||||||
            "backup_controller_page_uploading_file_info",
 | 
					            "backup_controller_page_uploading_file_info",
 | 
				
			||||||
            style: context.textTheme.titleSmall,
 | 
					            style: context.textTheme.titleSmall,
 | 
				
			||||||
          ).tr(),
 | 
					          ).tr(),
 | 
				
			||||||
            if (ref.watch(errorBackupListProvider).isNotEmpty) buildErrorChip(),
 | 
					          const BackupErrorChip(),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
      subtitle: Column(
 | 
					      subtitle: Column(
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
            if (Platform.isIOS) buildiCloudDownloadProgerssBar(),
 | 
					          if (Platform.isIOS) const IcloudDownloadProgressBar(),
 | 
				
			||||||
            buildUploadProgressBar(),
 | 
					          const BackupUploadProgressBar(),
 | 
				
			||||||
            buildUploadStats(),
 | 
					          const BackupUploadStats(),
 | 
				
			||||||
            Padding(
 | 
					          const BackupAssetInfoTable(),
 | 
				
			||||||
              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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user