mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 00:51:20 +00:00
feat(backups): Add descriptions for backups
This commit is contained in:
parent
b3b7c83461
commit
62b7a0ee7e
|
@ -1,10 +1,10 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'disk_volumes.graphql.dart';
|
||||||
import 'package:gql/ast.dart';
|
import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'package:selfprivacy/utils/scalars.dart';
|
import 'package:selfprivacy/utils/scalars.dart';
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
import 'server_api.graphql.dart';
|
import 'server_api.graphql.dart';
|
||||||
import 'services.graphql.dart';
|
|
||||||
|
|
||||||
class Fragment$genericBackupConfigReturn {
|
class Fragment$genericBackupConfigReturn {
|
||||||
Fragment$genericBackupConfigReturn({
|
Fragment$genericBackupConfigReturn({
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
import 'server_api.graphql.dart';
|
import 'server_api.graphql.dart';
|
||||||
import 'services.graphql.dart';
|
|
||||||
|
|
||||||
class Fragment$basicMutationReturnFields {
|
class Fragment$basicMutationReturnFields {
|
||||||
Fragment$basicMutationReturnFields({
|
Fragment$basicMutationReturnFields({
|
||||||
|
|
|
@ -255,6 +255,7 @@ type Service {
|
||||||
isRequired: Boolean!
|
isRequired: Boolean!
|
||||||
isEnabled: Boolean!
|
isEnabled: Boolean!
|
||||||
canBeBackedUp: Boolean!
|
canBeBackedUp: Boolean!
|
||||||
|
backupDescription: String!
|
||||||
status: ServiceStatusEnum!
|
status: ServiceStatusEnum!
|
||||||
url: String
|
url: String
|
||||||
dnsRecords: [DnsRecord!]
|
dnsRecords: [DnsRecord!]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'disk_volumes.graphql.dart';
|
||||||
import 'package:gql/ast.dart';
|
import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'package:selfprivacy/utils/scalars.dart';
|
import 'package:selfprivacy/utils/scalars.dart';
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
import 'services.graphql.dart';
|
|
||||||
|
|
||||||
class Fragment$basicMutationReturnFields {
|
class Fragment$basicMutationReturnFields {
|
||||||
Fragment$basicMutationReturnFields({
|
Fragment$basicMutationReturnFields({
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'disk_volumes.graphql.dart';
|
||||||
import 'package:gql/ast.dart';
|
import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
import 'services.graphql.dart';
|
|
||||||
|
|
||||||
class Fragment$basicMutationReturnFields {
|
class Fragment$basicMutationReturnFields {
|
||||||
Fragment$basicMutationReturnFields({
|
Fragment$basicMutationReturnFields({
|
||||||
|
|
|
@ -17,6 +17,7 @@ query AllServices {
|
||||||
isMovable
|
isMovable
|
||||||
isRequired
|
isRequired
|
||||||
canBeBackedUp
|
canBeBackedUp
|
||||||
|
backupDescription
|
||||||
status
|
status
|
||||||
storageUsage {
|
storageUsage {
|
||||||
title
|
title
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'disk_volumes.graphql.dart';
|
||||||
import 'package:gql/ast.dart';
|
import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
|
@ -2502,6 +2503,13 @@ const documentNodeQueryAllServices = DocumentNode(definitions: [
|
||||||
directives: [],
|
directives: [],
|
||||||
selectionSet: null,
|
selectionSet: null,
|
||||||
),
|
),
|
||||||
|
FieldNode(
|
||||||
|
name: NameNode(value: 'backupDescription'),
|
||||||
|
alias: null,
|
||||||
|
arguments: [],
|
||||||
|
directives: [],
|
||||||
|
selectionSet: null,
|
||||||
|
),
|
||||||
FieldNode(
|
FieldNode(
|
||||||
name: NameNode(value: 'status'),
|
name: NameNode(value: 'status'),
|
||||||
alias: null,
|
alias: null,
|
||||||
|
@ -2884,6 +2892,7 @@ class Query$AllServices$services$allServices {
|
||||||
required this.isMovable,
|
required this.isMovable,
|
||||||
required this.isRequired,
|
required this.isRequired,
|
||||||
required this.canBeBackedUp,
|
required this.canBeBackedUp,
|
||||||
|
required this.backupDescription,
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.storageUsage,
|
required this.storageUsage,
|
||||||
required this.svgIcon,
|
required this.svgIcon,
|
||||||
|
@ -2901,6 +2910,7 @@ class Query$AllServices$services$allServices {
|
||||||
final l$isMovable = json['isMovable'];
|
final l$isMovable = json['isMovable'];
|
||||||
final l$isRequired = json['isRequired'];
|
final l$isRequired = json['isRequired'];
|
||||||
final l$canBeBackedUp = json['canBeBackedUp'];
|
final l$canBeBackedUp = json['canBeBackedUp'];
|
||||||
|
final l$backupDescription = json['backupDescription'];
|
||||||
final l$status = json['status'];
|
final l$status = json['status'];
|
||||||
final l$storageUsage = json['storageUsage'];
|
final l$storageUsage = json['storageUsage'];
|
||||||
final l$svgIcon = json['svgIcon'];
|
final l$svgIcon = json['svgIcon'];
|
||||||
|
@ -2918,6 +2928,7 @@ class Query$AllServices$services$allServices {
|
||||||
isMovable: (l$isMovable as bool),
|
isMovable: (l$isMovable as bool),
|
||||||
isRequired: (l$isRequired as bool),
|
isRequired: (l$isRequired as bool),
|
||||||
canBeBackedUp: (l$canBeBackedUp as bool),
|
canBeBackedUp: (l$canBeBackedUp as bool),
|
||||||
|
backupDescription: (l$backupDescription as String),
|
||||||
status: fromJson$Enum$ServiceStatusEnum((l$status as String)),
|
status: fromJson$Enum$ServiceStatusEnum((l$status as String)),
|
||||||
storageUsage:
|
storageUsage:
|
||||||
Query$AllServices$services$allServices$storageUsage.fromJson(
|
Query$AllServices$services$allServices$storageUsage.fromJson(
|
||||||
|
@ -2944,6 +2955,8 @@ class Query$AllServices$services$allServices {
|
||||||
|
|
||||||
final bool canBeBackedUp;
|
final bool canBeBackedUp;
|
||||||
|
|
||||||
|
final String backupDescription;
|
||||||
|
|
||||||
final Enum$ServiceStatusEnum status;
|
final Enum$ServiceStatusEnum status;
|
||||||
|
|
||||||
final Query$AllServices$services$allServices$storageUsage storageUsage;
|
final Query$AllServices$services$allServices$storageUsage storageUsage;
|
||||||
|
@ -2972,6 +2985,8 @@ class Query$AllServices$services$allServices {
|
||||||
_resultData['isRequired'] = l$isRequired;
|
_resultData['isRequired'] = l$isRequired;
|
||||||
final l$canBeBackedUp = canBeBackedUp;
|
final l$canBeBackedUp = canBeBackedUp;
|
||||||
_resultData['canBeBackedUp'] = l$canBeBackedUp;
|
_resultData['canBeBackedUp'] = l$canBeBackedUp;
|
||||||
|
final l$backupDescription = backupDescription;
|
||||||
|
_resultData['backupDescription'] = l$backupDescription;
|
||||||
final l$status = status;
|
final l$status = status;
|
||||||
_resultData['status'] = toJson$Enum$ServiceStatusEnum(l$status);
|
_resultData['status'] = toJson$Enum$ServiceStatusEnum(l$status);
|
||||||
final l$storageUsage = storageUsage;
|
final l$storageUsage = storageUsage;
|
||||||
|
@ -2995,6 +3010,7 @@ class Query$AllServices$services$allServices {
|
||||||
final l$isMovable = isMovable;
|
final l$isMovable = isMovable;
|
||||||
final l$isRequired = isRequired;
|
final l$isRequired = isRequired;
|
||||||
final l$canBeBackedUp = canBeBackedUp;
|
final l$canBeBackedUp = canBeBackedUp;
|
||||||
|
final l$backupDescription = backupDescription;
|
||||||
final l$status = status;
|
final l$status = status;
|
||||||
final l$storageUsage = storageUsage;
|
final l$storageUsage = storageUsage;
|
||||||
final l$svgIcon = svgIcon;
|
final l$svgIcon = svgIcon;
|
||||||
|
@ -3009,6 +3025,7 @@ class Query$AllServices$services$allServices {
|
||||||
l$isMovable,
|
l$isMovable,
|
||||||
l$isRequired,
|
l$isRequired,
|
||||||
l$canBeBackedUp,
|
l$canBeBackedUp,
|
||||||
|
l$backupDescription,
|
||||||
l$status,
|
l$status,
|
||||||
l$storageUsage,
|
l$storageUsage,
|
||||||
l$svgIcon,
|
l$svgIcon,
|
||||||
|
@ -3077,6 +3094,11 @@ class Query$AllServices$services$allServices {
|
||||||
if (l$canBeBackedUp != lOther$canBeBackedUp) {
|
if (l$canBeBackedUp != lOther$canBeBackedUp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
final l$backupDescription = backupDescription;
|
||||||
|
final lOther$backupDescription = other.backupDescription;
|
||||||
|
if (l$backupDescription != lOther$backupDescription) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final l$status = status;
|
final l$status = status;
|
||||||
final lOther$status = other.status;
|
final lOther$status = other.status;
|
||||||
if (l$status != lOther$status) {
|
if (l$status != lOther$status) {
|
||||||
|
@ -3134,6 +3156,7 @@ abstract class CopyWith$Query$AllServices$services$allServices<TRes> {
|
||||||
bool? isMovable,
|
bool? isMovable,
|
||||||
bool? isRequired,
|
bool? isRequired,
|
||||||
bool? canBeBackedUp,
|
bool? canBeBackedUp,
|
||||||
|
String? backupDescription,
|
||||||
Enum$ServiceStatusEnum? status,
|
Enum$ServiceStatusEnum? status,
|
||||||
Query$AllServices$services$allServices$storageUsage? storageUsage,
|
Query$AllServices$services$allServices$storageUsage? storageUsage,
|
||||||
String? svgIcon,
|
String? svgIcon,
|
||||||
|
@ -3172,6 +3195,7 @@ class _CopyWithImpl$Query$AllServices$services$allServices<TRes>
|
||||||
Object? isMovable = _undefined,
|
Object? isMovable = _undefined,
|
||||||
Object? isRequired = _undefined,
|
Object? isRequired = _undefined,
|
||||||
Object? canBeBackedUp = _undefined,
|
Object? canBeBackedUp = _undefined,
|
||||||
|
Object? backupDescription = _undefined,
|
||||||
Object? status = _undefined,
|
Object? status = _undefined,
|
||||||
Object? storageUsage = _undefined,
|
Object? storageUsage = _undefined,
|
||||||
Object? svgIcon = _undefined,
|
Object? svgIcon = _undefined,
|
||||||
|
@ -3201,6 +3225,10 @@ class _CopyWithImpl$Query$AllServices$services$allServices<TRes>
|
||||||
canBeBackedUp: canBeBackedUp == _undefined || canBeBackedUp == null
|
canBeBackedUp: canBeBackedUp == _undefined || canBeBackedUp == null
|
||||||
? _instance.canBeBackedUp
|
? _instance.canBeBackedUp
|
||||||
: (canBeBackedUp as bool),
|
: (canBeBackedUp as bool),
|
||||||
|
backupDescription:
|
||||||
|
backupDescription == _undefined || backupDescription == null
|
||||||
|
? _instance.backupDescription
|
||||||
|
: (backupDescription as String),
|
||||||
status: status == _undefined || status == null
|
status: status == _undefined || status == null
|
||||||
? _instance.status
|
? _instance.status
|
||||||
: (status as Enum$ServiceStatusEnum),
|
: (status as Enum$ServiceStatusEnum),
|
||||||
|
@ -3251,6 +3279,7 @@ class _CopyWithStubImpl$Query$AllServices$services$allServices<TRes>
|
||||||
bool? isMovable,
|
bool? isMovable,
|
||||||
bool? isRequired,
|
bool? isRequired,
|
||||||
bool? canBeBackedUp,
|
bool? canBeBackedUp,
|
||||||
|
String? backupDescription,
|
||||||
Enum$ServiceStatusEnum? status,
|
Enum$ServiceStatusEnum? status,
|
||||||
Query$AllServices$services$allServices$storageUsage? storageUsage,
|
Query$AllServices$services$allServices$storageUsage? storageUsage,
|
||||||
String? svgIcon,
|
String? svgIcon,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'disk_volumes.graphql.dart';
|
||||||
import 'package:gql/ast.dart';
|
import 'package:gql/ast.dart';
|
||||||
import 'package:graphql/client.dart' as graphql;
|
import 'package:graphql/client.dart' as graphql;
|
||||||
import 'schema.graphql.dart';
|
import 'schema.graphql.dart';
|
||||||
import 'services.graphql.dart';
|
|
||||||
|
|
||||||
class Fragment$basicMutationReturnFields {
|
class Fragment$basicMutationReturnFields {
|
||||||
Fragment$basicMutationReturnFields({
|
Fragment$basicMutationReturnFields({
|
||||||
|
|
|
@ -30,6 +30,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
final BackupConfiguration? backupConfig =
|
final BackupConfiguration? backupConfig =
|
||||||
await api.getBackupsConfiguration();
|
await api.getBackupsConfiguration();
|
||||||
final List<Backup> backups = await api.getBackups();
|
final List<Backup> backups = await api.getBackups();
|
||||||
|
backups.sort((final a, final b) => b.time.compareTo(a.time));
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
backblazeBucket: bucket,
|
backblazeBucket: bucket,
|
||||||
|
@ -144,6 +145,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
Future<void> updateBackups({final bool useTimer = false}) async {
|
Future<void> updateBackups({final bool useTimer = false}) async {
|
||||||
emit(state.copyWith(refreshing: true));
|
emit(state.copyWith(refreshing: true));
|
||||||
final backups = await api.getBackups();
|
final backups = await api.getBackups();
|
||||||
|
backups.sort((final a, final b) => b.time.compareTo(a.time));
|
||||||
final backupConfig = await api.getBackupsConfiguration();
|
final backupConfig = await api.getBackupsConfiguration();
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
|
|
|
@ -25,7 +25,7 @@ class BackupsState extends ServerInstallationDependendState {
|
||||||
backups,
|
backups,
|
||||||
preventActions,
|
preventActions,
|
||||||
refreshTimer,
|
refreshTimer,
|
||||||
refreshing
|
refreshing,
|
||||||
];
|
];
|
||||||
|
|
||||||
BackupsState copyWith({
|
BackupsState copyWith({
|
||||||
|
|
|
@ -18,6 +18,7 @@ class Service {
|
||||||
isRequired: service.isRequired,
|
isRequired: service.isRequired,
|
||||||
isMovable: service.isMovable,
|
isMovable: service.isMovable,
|
||||||
canBeBackedUp: service.canBeBackedUp,
|
canBeBackedUp: service.canBeBackedUp,
|
||||||
|
backupDescription: service.backupDescription,
|
||||||
status: ServiceStatus.fromGraphQL(service.status),
|
status: ServiceStatus.fromGraphQL(service.status),
|
||||||
storageUsage: ServiceStorageUsage(
|
storageUsage: ServiceStorageUsage(
|
||||||
used: DiskSize(byte: int.parse(service.storageUsage.usedSpace)),
|
used: DiskSize(byte: int.parse(service.storageUsage.usedSpace)),
|
||||||
|
@ -44,6 +45,7 @@ class Service {
|
||||||
required this.isRequired,
|
required this.isRequired,
|
||||||
required this.isMovable,
|
required this.isMovable,
|
||||||
required this.canBeBackedUp,
|
required this.canBeBackedUp,
|
||||||
|
required this.backupDescription,
|
||||||
required this.status,
|
required this.status,
|
||||||
required this.storageUsage,
|
required this.storageUsage,
|
||||||
required this.svgIcon,
|
required this.svgIcon,
|
||||||
|
@ -78,6 +80,7 @@ class Service {
|
||||||
isRequired: false,
|
isRequired: false,
|
||||||
isMovable: false,
|
isMovable: false,
|
||||||
canBeBackedUp: false,
|
canBeBackedUp: false,
|
||||||
|
backupDescription: '',
|
||||||
status: ServiceStatus.off,
|
status: ServiceStatus.off,
|
||||||
storageUsage: ServiceStorageUsage(
|
storageUsage: ServiceStorageUsage(
|
||||||
used: const DiskSize(byte: 0),
|
used: const DiskSize(byte: 0),
|
||||||
|
@ -95,6 +98,7 @@ class Service {
|
||||||
final bool isRequired;
|
final bool isRequired;
|
||||||
final bool isMovable;
|
final bool isMovable;
|
||||||
final bool canBeBackedUp;
|
final bool canBeBackedUp;
|
||||||
|
final String backupDescription;
|
||||||
final ServiceStatus status;
|
final ServiceStatus status;
|
||||||
final ServiceStorageUsage storageUsage;
|
final ServiceStorageUsage storageUsage;
|
||||||
final String svgIcon;
|
final String svgIcon;
|
||||||
|
|
|
@ -147,7 +147,8 @@ class _HeroSliverAppBarState extends State<HeroSliverAppBar> {
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: true,
|
useRootNavigator: true,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
builder: (final BuildContext context) => DraggableScrollableSheet(
|
builder: (final BuildContext context) =>
|
||||||
|
DraggableScrollableSheet(
|
||||||
expand: false,
|
expand: false,
|
||||||
maxChildSize: 0.9,
|
maxChildSize: 0.9,
|
||||||
minChildSize: 0.4,
|
minChildSize: 0.4,
|
||||||
|
|
|
@ -93,59 +93,88 @@ class _BackupDetailsPageState extends State<BackupDetailsPage>
|
||||||
// Each list item has a date
|
// Each list item has a date
|
||||||
// When clicked, starts the restore action
|
// When clicked, starts the restore action
|
||||||
if (isBackupInitialized)
|
if (isBackupInitialized)
|
||||||
OutlinedCard(
|
Column(
|
||||||
child: Column(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
'backups.latest_snapshots'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Text(
|
||||||
|
'backups.latest_snapshots_subtitle'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.labelMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (backups.isEmpty)
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(
|
leading: const Icon(
|
||||||
Icons.refresh,
|
Icons.error_outline,
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
'backup.restore'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
|
||||||
),
|
),
|
||||||
|
title: Text('backup.no_backups'.tr()),
|
||||||
),
|
),
|
||||||
const Divider(
|
if (backups.isNotEmpty)
|
||||||
height: 1.0,
|
Column(
|
||||||
),
|
children: backups.take(20).map(
|
||||||
if (backups.isEmpty)
|
(final Backup backup) {
|
||||||
ListTile(
|
final service = context
|
||||||
leading: const Icon(
|
.read<ServicesCubit>()
|
||||||
Icons.error_outline,
|
.state
|
||||||
),
|
.getServiceById(backup.serviceId);
|
||||||
title: Text('backup.no_backups'.tr()),
|
return ListTile(
|
||||||
),
|
onTap: preventActions
|
||||||
if (backups.isNotEmpty)
|
? null
|
||||||
Column(
|
: () {
|
||||||
children: backups
|
showPopUpAlert(
|
||||||
.map(
|
alertTitle: 'backup.restoring'.tr(),
|
||||||
(final Backup backup) => ListTile(
|
description: 'backup.restore_alert'.tr(
|
||||||
onTap: preventActions
|
args: [backup.time.toString()],
|
||||||
? null
|
),
|
||||||
: () {
|
actionButtonTitle: 'modals.yes'.tr(),
|
||||||
showPopUpAlert(
|
actionButtonOnPressed: () => {
|
||||||
alertTitle: 'backup.restoring'.tr(),
|
context
|
||||||
description: 'backup.restore_alert'.tr(
|
.read<BackupsCubit>()
|
||||||
args: [backup.time.toString()],
|
.restoreBackup(backup.id)
|
||||||
),
|
|
||||||
actionButtonTitle: 'modals.yes'.tr(),
|
|
||||||
actionButtonOnPressed: () => {
|
|
||||||
context
|
|
||||||
.read<BackupsCubit>()
|
|
||||||
.restoreBackup(backup.id)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
title: Text(
|
);
|
||||||
'${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}',
|
},
|
||||||
),
|
title: Text(
|
||||||
),
|
'${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}',
|
||||||
)
|
),
|
||||||
.toList(),
|
subtitle: Text(
|
||||||
|
service?.displayName ?? backup.fallbackServiceName,
|
||||||
|
),
|
||||||
|
leading: service != null
|
||||||
|
? SvgPicture.string(
|
||||||
|
service.svgIcon,
|
||||||
|
height: 24,
|
||||||
|
width: 24,
|
||||||
|
colorFilter: ColorFilter.mode(
|
||||||
|
Theme.of(context).colorScheme.onBackground,
|
||||||
|
BlendMode.srcIn,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const Icon(
|
||||||
|
Icons.question_mark_outlined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).toList(),
|
||||||
|
),
|
||||||
|
if (backups.isNotEmpty && backups.length > 20)
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
'backups.show_more'.tr(),
|
||||||
|
style: Theme.of(context).textTheme.labelMedium,
|
||||||
),
|
),
|
||||||
],
|
leading: const Icon(
|
||||||
),
|
Icons.arrow_drop_down,
|
||||||
|
),
|
||||||
|
onTap: null,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
OutlinedCard(
|
OutlinedCard(
|
||||||
|
@ -317,7 +346,7 @@ class _CreateBackupsModalState extends State<CreateBackupsModal> {
|
||||||
service.displayName,
|
service.displayName,
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
busy ? 'backup.service_busy'.tr() : service.description,
|
busy ? 'backup.service_busy'.tr() : service.backupDescription,
|
||||||
),
|
),
|
||||||
secondary: SvgPicture.string(
|
secondary: SvgPicture.string(
|
||||||
service.svgIcon,
|
service.svgIcon,
|
||||||
|
|
Loading…
Reference in a new issue