mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-08 01:43:13 +00:00
Merge branch 'master' into backblaze-refactor
This commit is contained in:
commit
49896a8e9f
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()),
|
||||
),
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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),
|
||||
],
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue