Merge branch 'master' into backblaze-refactor

This commit is contained in:
NaiJi 2023-09-19 11:13:33 -03:00
commit 49896a8e9f
11 changed files with 81 additions and 45 deletions

View file

@ -304,6 +304,7 @@
"extending_volume_price_info": "Price includes VAT and is estimated from pricing data provided by your server provider. Server will be rebooted after resizing.",
"extending_volume_error": "Couldn't initialize volume extending.",
"size": "Size",
"price": "Price",
"data_migration_title": "Data migration",
"data_migration_notice": "During migration all services will be turned off.",
"start_migration_button": "Start migration",

View file

@ -18,6 +18,32 @@ class UsersState extends ServerInstallationDependendState {
@override
List<Object> get props => [users, isLoading];
/// Makes a copy of existing users list, but places 'primary'
/// to the beginning and sorts the rest alphabetically
///
/// If found a 'root' user, it doesn't get copied into the result
List<User> get orderedUsers {
User? primaryUser;
final List<User> normalUsers = [];
for (final User user in users) {
if (user.type == UserType.primary) {
primaryUser = user;
continue;
}
if (user.type == UserType.root) {
continue;
}
normalUsers.add(user);
}
normalUsers.sort(
(final User a, final User b) =>
a.login.toLowerCase().compareTo(b.login.toLowerCase()),
);
return primaryUser == null ? normalUsers : [primaryUser] + normalUsers;
}
UsersState copyWith({
final List<User>? users,
final bool? isLoading,

View file

@ -1,7 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:selfprivacy/logic/models/message.dart';
import 'package:selfprivacy/utils/platform_adapter.dart';
class LogListItem extends StatelessWidget {
const LogListItem({
@ -71,7 +71,7 @@ class _RestApiRequestMessageItem extends StatelessWidget {
if (message.text != null)
TextButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: message.text ?? ''));
PlatformAdapter.setClipboard(message.text ?? '');
},
child: Text('console_page.copy'.tr()),
),
@ -121,7 +121,7 @@ class _RestApiResponseMessageItem extends StatelessWidget {
if (message.text != null)
TextButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: message.text ?? ''));
PlatformAdapter.setClipboard(message.text ?? '');
},
child: Text('console_page.copy'.tr()),
),
@ -195,7 +195,7 @@ class _GraphQlResponseMessageItem extends StatelessWidget {
if (message.text != null)
TextButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: message.text ?? ''));
PlatformAdapter.setClipboard(message.text ?? '');
},
child: Text('console_page.copy'.tr()),
),
@ -264,7 +264,7 @@ class _GraphQlRequestMessageItem extends StatelessWidget {
if (message.text != null)
TextButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: message.text ?? ''));
PlatformAdapter.setClipboard(message.text ?? '');
},
child: Text('console_page.copy'.tr()),
),

View file

@ -2,11 +2,11 @@ import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
import 'package:selfprivacy/logic/cubit/backups/backups_cubit.dart';
import 'package:selfprivacy/logic/cubit/server_jobs/server_jobs_cubit.dart';
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
import 'package:selfprivacy/utils/platform_adapter.dart';
class CopyEncryptionKeyModal extends StatefulWidget {
const CopyEncryptionKeyModal({
@ -144,11 +144,7 @@ class _CopyEncryptionKeyModalState extends State<CopyEncryptionKeyModal> {
},
);
});
Clipboard.setData(
ClipboardData(
text: encryptionKey,
),
);
PlatformAdapter.setClipboard(encryptionKey);
},
icon: const Icon(Icons.copy_all_outlined),
label: Text(

View file

@ -1,7 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/utils/platform_adapter.dart';
class SnapshotIdListTile extends StatelessWidget {
const SnapshotIdListTile({
@ -14,7 +14,7 @@ class SnapshotIdListTile extends StatelessWidget {
@override
Widget build(final BuildContext context) => ListTile(
onLongPress: () {
Clipboard.setData(ClipboardData(text: snapshotId));
PlatformAdapter.setClipboard(snapshotId);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
behavior: SnackBarBehavior.floating,

View file

@ -79,10 +79,12 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
}
final price = snapshot.data as Price;
_pricePerGb = price.value;
_sizeController.text = _currentSliderGbValue.truncate().toString();
final currentSizeValue = _currentSliderGbValue.truncate().toString();
_sizeController.text = 'storage.gb'.tr(args: [currentSizeValue]);
_priceController.text =
(_pricePerGb * double.parse(_sizeController.text))
.toStringAsFixed(2);
'${(_pricePerGb * double.parse(currentSizeValue)).toStringAsFixed(2)}'
' '
'${price.currency.shortcode}';
minSize =
widget.diskVolumeToResize.sizeTotal + DiskSize.fromGibibyte(3);
if (_currentSliderGbValue < 0) {
@ -130,7 +132,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
decoration: InputDecoration(
border: const OutlineInputBorder(),
errorText: _isError ? ' ' : null,
labelText: price.currency.shortcode,
labelText: 'storage.price'.tr(),
),
),
),

View file

@ -160,13 +160,15 @@ class _Card extends StatelessWidget {
],
),
Text(
service.loginInfo,
service.description,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(height: 10),
Text(
service.description,
style: Theme.of(context).textTheme.bodyMedium,
service.loginInfo,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
const SizedBox(height: 10),
],

View file

@ -3,11 +3,11 @@ part of 'users.dart';
class _User extends StatelessWidget {
const _User({
required this.user,
required this.isRootUser,
required this.isPrimaryUser,
});
final User user;
final bool isRootUser;
final bool isPrimaryUser;
@override
Widget build(final BuildContext context) => InkWell(
onTap: () {
@ -32,7 +32,7 @@ class _User extends StatelessWidget {
user.login,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onBackground,
decoration: isRootUser
decoration: isPrimaryUser
? TextDecoration.underline
: user.isFoundOnServer
? TextDecoration.none

View file

@ -143,17 +143,27 @@ class _UserLogins extends StatelessWidget {
final String domainName;
@override
Widget build(final BuildContext context) => FilledCard(
child: Column(
children: [
ListTileOnSurfaceVariant(
title: '${user.login}@$domainName',
subtitle: 'users.email_login'.tr(),
leadingIcon: Icons.alternate_email_outlined,
),
],
),
);
Widget build(final BuildContext context) {
final email = '${user.login}@$domainName';
return FilledCard(
child: Column(
children: [
ListTileOnSurfaceVariant(
onTap: () {
PlatformAdapter.setClipboard(email);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
behavior: SnackBarBehavior.floating,
);
},
title: email,
subtitle: 'users.email_login'.tr(),
leadingIcon: Icons.alternate_email_outlined,
),
],
),
);
}
}
class _SshKeysCard extends StatelessWidget {

View file

@ -3,6 +3,7 @@ import 'package:cubit_form/cubit_form.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/cubit/forms/user/ssh_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/factories/field_cubit_factory.dart';
@ -22,6 +23,7 @@ import 'package:selfprivacy/ui/components/list_tiles/list_tile_on_surface_varian
import 'package:selfprivacy/ui/components/not_ready_card/not_ready_card.dart';
import 'package:selfprivacy/ui/router/router.dart';
import 'package:selfprivacy/utils/breakpoints.dart';
import 'package:selfprivacy/utils/platform_adapter.dart';
import 'package:selfprivacy/utils/ui_helpers.dart';
part 'empty.dart';
@ -45,15 +47,7 @@ class UsersPage extends StatelessWidget {
} else {
child = BlocBuilder<UsersCubit, UsersState>(
builder: (final BuildContext context, final UsersState state) {
final List<User> users = state.users
.where((final user) => user.type != UserType.root)
.toList();
// final List<User> users = [];
users.sort(
(final User a, final User b) =>
a.login.toLowerCase().compareTo(b.login.toLowerCase()),
);
final users = state.orderedUsers;
if (users.isEmpty) {
if (state.isLoading) {
return const Center(
@ -115,7 +109,7 @@ class UsersPage extends StatelessWidget {
itemBuilder:
(final BuildContext context, final int index) => _User(
user: users[index],
isRootUser: users[index].type == UserType.primary,
isPrimaryUser: users[index].type == UserType.primary,
),
),
),

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
/// SelfPrivacy wrapper for Platform information provider.
class PlatformAdapter {
@ -56,4 +57,8 @@ class PlatformAdapter {
return 'Unidentified';
}
static void setClipboard(final String clipboardData) {
Clipboard.setData(ClipboardData(text: clipboardData));
}
}