mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-04 23:24:20 +00:00
Merge branch 'master' into 'dynamic-dns'
This commit is contained in:
commit
cd9b47b924
|
@ -137,7 +137,7 @@ class BackblazeApi extends RestApiMap {
|
|||
{
|
||||
'daysFromHidingToDeleting': 30,
|
||||
'daysFromUploadingToHiding': null,
|
||||
'fileNamePrefix': ''
|
||||
'fileNamePrefix': '',
|
||||
}
|
||||
],
|
||||
},
|
||||
|
|
|
@ -360,21 +360,14 @@ class HetznerApi extends RestApiMap {
|
|||
return GenericResult(success: true, data: pricing);
|
||||
}
|
||||
|
||||
Future<GenericResult<List<HetznerVolume>>> getVolumes({
|
||||
final String? status,
|
||||
}) async {
|
||||
Future<GenericResult<List<HetznerVolume>>> getVolumes() async {
|
||||
final List<HetznerVolume> volumes = [];
|
||||
|
||||
Response? getVolumesResonse;
|
||||
Response? getVolumesResponse;
|
||||
final Dio client = await getClient();
|
||||
try {
|
||||
getVolumesResonse = await client.get(
|
||||
'/volumes',
|
||||
queryParameters: {
|
||||
'status': status,
|
||||
},
|
||||
);
|
||||
for (final volume in getVolumesResonse.data['volumes']) {
|
||||
getVolumesResponse = await client.get('/volumes');
|
||||
for (final volume in getVolumesResponse.data['volumes']) {
|
||||
volumes.add(HetznerVolume.fromJson(volume));
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -391,8 +384,8 @@ class HetznerApi extends RestApiMap {
|
|||
return GenericResult(
|
||||
data: volumes,
|
||||
success: true,
|
||||
code: getVolumesResonse.statusCode,
|
||||
message: getVolumesResonse.statusMessage,
|
||||
code: getVolumesResponse.statusCode,
|
||||
message: getVolumesResponse.statusMessage,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -409,7 +402,7 @@ class HetznerApi extends RestApiMap {
|
|||
'labels': {'labelkey': 'value'},
|
||||
'location': region,
|
||||
'automount': false,
|
||||
'format': 'ext4'
|
||||
'format': 'ext4',
|
||||
},
|
||||
);
|
||||
volume = HetznerVolume.fromJson(createVolumeResponse.data['volume']);
|
||||
|
@ -586,7 +579,7 @@ class HetznerApi extends RestApiMap {
|
|||
final Map<String, dynamic> queryParameters = {
|
||||
'start': start.toUtc().toIso8601String(),
|
||||
'end': end.toUtc().toIso8601String(),
|
||||
'type': type
|
||||
'type': type,
|
||||
};
|
||||
final Response res = await client.get(
|
||||
'/servers/$serverId/metrics',
|
||||
|
|
|
@ -26,7 +26,7 @@ abstract class ServerInstallationState extends Equatable {
|
|||
serverDetails,
|
||||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
installationDialoguePopUp
|
||||
installationDialoguePopUp,
|
||||
];
|
||||
|
||||
final String? providerApiToken;
|
||||
|
@ -317,7 +317,7 @@ class ServerInstallationRecovery extends ServerInstallationState {
|
|||
isServerStarted,
|
||||
isServerResetedFirstTime,
|
||||
currentStep,
|
||||
installationDialoguePopUp
|
||||
installationDialoguePopUp,
|
||||
];
|
||||
|
||||
ServerInstallationRecovery copyWith({
|
||||
|
|
|
@ -90,7 +90,7 @@ class ServerJobsCubit
|
|||
ServerJobsState(
|
||||
serverJobList: [
|
||||
for (final ServerJob job in state.serverJobList)
|
||||
if (job.uid != uid) job
|
||||
if (job.uid != uid) job,
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -78,7 +78,7 @@ class _ProgressBarState extends State<ProgressBar> {
|
|||
end: Alignment.bottomRight,
|
||||
colors: [
|
||||
Theme.of(context).colorScheme.primary,
|
||||
Theme.of(context).colorScheme.secondary
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -110,7 +110,7 @@ class _ProgressBarState extends State<ProgressBar> {
|
|||
style: progressTextStyleLight,
|
||||
children: [
|
||||
TextSpan(text: '${index + 1}.', style: style),
|
||||
TextSpan(text: step, style: style)
|
||||
TextSpan(text: step, style: style),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -32,7 +32,7 @@ class EmptyPagePlaceholder extends StatelessWidget {
|
|||
child: _expandedContent(context),
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
autobackupPeriod != null
|
||||
? 'backup.autobackup_period_subtitle'.tr(
|
||||
namedArgs: {
|
||||
'period': autobackupPeriod.toPrettyString(context.locale)
|
||||
'period': autobackupPeriod.toPrettyString(context.locale),
|
||||
},
|
||||
)
|
||||
: 'backup.autobackup_period_never'.tr(),
|
||||
|
@ -337,7 +337,7 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
actionButtonOnPressed: () => {
|
||||
context.read<BackupsCubit>().forgetSnapshot(
|
||||
backup.id,
|
||||
)
|
||||
),
|
||||
},
|
||||
);
|
||||
},
|
||||
|
@ -385,7 +385,7 @@ class BackupDetailsPage extends StatelessWidget {
|
|||
),
|
||||
onTap: () =>
|
||||
context.pushRoute(BackupsListRoute(service: null)),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
|
@ -39,68 +39,70 @@ class BackupsListPage extends StatelessWidget {
|
|||
),
|
||||
)
|
||||
else
|
||||
...backups.map((final Backup backup) {
|
||||
final service = context
|
||||
.read<ServicesCubit>()
|
||||
.state
|
||||
.getServiceById(backup.serviceId);
|
||||
return ListTile(
|
||||
onTap: preventActions
|
||||
? null
|
||||
: () {
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (final BuildContext context) =>
|
||||
DraggableScrollableSheet(
|
||||
expand: false,
|
||||
maxChildSize: 0.9,
|
||||
minChildSize: 0.5,
|
||||
initialChildSize: 0.7,
|
||||
builder: (final context, final scrollController) =>
|
||||
SnapshotModal(
|
||||
snapshot: backup,
|
||||
scrollController: scrollController,
|
||||
...backups.map(
|
||||
(final Backup backup) {
|
||||
final service = context
|
||||
.read<ServicesCubit>()
|
||||
.state
|
||||
.getServiceById(backup.serviceId);
|
||||
return ListTile(
|
||||
onTap: preventActions
|
||||
? null
|
||||
: () {
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (final BuildContext context) =>
|
||||
DraggableScrollableSheet(
|
||||
expand: false,
|
||||
maxChildSize: 0.9,
|
||||
minChildSize: 0.5,
|
||||
initialChildSize: 0.7,
|
||||
builder: (final context, final scrollController) =>
|
||||
SnapshotModal(
|
||||
snapshot: backup,
|
||||
scrollController: scrollController,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
onLongPress: preventActions
|
||||
? null
|
||||
: () {
|
||||
showPopUpAlert(
|
||||
alertTitle: 'backup.forget_snapshot'.tr(),
|
||||
description: 'backup.forget_snapshot_alert'.tr(),
|
||||
actionButtonTitle: 'backup.forget_snapshot'.tr(),
|
||||
actionButtonOnPressed: () => {
|
||||
context.read<BackupsCubit>().forgetSnapshot(
|
||||
backup.id,
|
||||
),
|
||||
},
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
'${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}',
|
||||
),
|
||||
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,
|
||||
),
|
||||
);
|
||||
},
|
||||
onLongPress: preventActions
|
||||
? null
|
||||
: () {
|
||||
showPopUpAlert(
|
||||
alertTitle: 'backup.forget_snapshot'.tr(),
|
||||
description: 'backup.forget_snapshot_alert'.tr(),
|
||||
actionButtonTitle: 'backup.forget_snapshot'.tr(),
|
||||
actionButtonOnPressed: () => {
|
||||
context.read<BackupsCubit>().forgetSnapshot(
|
||||
backup.id,
|
||||
)
|
||||
},
|
||||
);
|
||||
},
|
||||
title: Text(
|
||||
'${MaterialLocalizations.of(context).formatShortDate(backup.time)} ${TimeOfDay.fromDateTime(backup.time).format(context)}',
|
||||
),
|
||||
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,
|
||||
),
|
||||
)
|
||||
: const Icon(
|
||||
Icons.question_mark_outlined,
|
||||
),
|
||||
);
|
||||
})
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ class _SnapshotModalState extends State<SnapshotModal> {
|
|||
isWarning: true,
|
||||
text: 'backup.snapshot_modal_service_not_found'.tr(),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -62,7 +62,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
),
|
||||
const _ResetAppTile(),
|
||||
// const Divider(height: 0),
|
||||
_deleteServer(context)
|
||||
_deleteServer(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ class MorePage extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -113,7 +113,7 @@ class _Chart extends StatelessWidget {
|
|||
titles: [
|
||||
'resource_chart.month'.tr(),
|
||||
'resource_chart.day'.tr(),
|
||||
'resource_chart.hour'.tr()
|
||||
'resource_chart.hour'.tr(),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
|
@ -86,7 +86,9 @@ class CpuChart extends StatelessWidget {
|
|||
maxY: 100,
|
||||
minX: 0,
|
||||
titlesData: FlTitlesData(
|
||||
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
topTitles: AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
interval: 40,
|
||||
|
|
|
@ -113,12 +113,14 @@ class NetworkChart extends StatelessWidget {
|
|||
minY: 0,
|
||||
maxY: [
|
||||
...listData[0].map((final e) => e.value),
|
||||
...listData[1].map((final e) => e.value)
|
||||
...listData[1].map((final e) => e.value),
|
||||
].reduce(max) *
|
||||
1.2,
|
||||
minX: 0,
|
||||
titlesData: FlTitlesData(
|
||||
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
topTitles: AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
interval: 40,
|
||||
|
@ -139,7 +141,9 @@ class NetworkChart extends StatelessWidget {
|
|||
showTitles: true,
|
||||
),
|
||||
),
|
||||
leftTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
rightTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
reservedSize: 50,
|
||||
|
@ -154,7 +158,7 @@ class NetworkChart extends StatelessWidget {
|
|||
),
|
||||
interval: [
|
||||
...listData[0].map((final e) => e.value),
|
||||
...listData[1].map((final e) => e.value)
|
||||
...listData[1].map((final e) => e.value),
|
||||
].reduce(max) *
|
||||
2 /
|
||||
6.5,
|
||||
|
@ -168,7 +172,7 @@ class NetworkChart extends StatelessWidget {
|
|||
verticalInterval: 40,
|
||||
horizontalInterval: [
|
||||
...listData[0].map((final e) => e.value),
|
||||
...listData[1].map((final e) => e.value)
|
||||
...listData[1].map((final e) => e.value),
|
||||
].reduce(max) *
|
||||
2 /
|
||||
6.5,
|
||||
|
|
|
@ -134,7 +134,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
.read<ApiServerVolumeCubit>()
|
||||
.state
|
||||
.getVolume(service.storageUsage.volume ?? '')
|
||||
.displayName
|
||||
.displayName,
|
||||
},
|
||||
),
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
|
|
|
@ -69,7 +69,7 @@ class _ServicesPageState extends State<ServicesPage> {
|
|||
),
|
||||
child: _Card(service: service),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -179,7 +179,7 @@ class _Card extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -49,7 +49,7 @@ class InitializingPage extends StatelessWidget {
|
|||
() => _stepCheck(cubit),
|
||||
() => _stepCheck(cubit),
|
||||
() => _stepCheck(cubit),
|
||||
() => _stepCheck(cubit)
|
||||
() => _stepCheck(cubit),
|
||||
][cubit.state.progress.index]();
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ class InitializingPage extends StatelessWidget {
|
|||
.replace(const RecoveryRoute());
|
||||
},
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -517,7 +517,7 @@ class InitializingPage extends StatelessWidget {
|
|||
BrandTimer(
|
||||
startDateTime: state.timerStart!,
|
||||
duration: state.duration!,
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
if (state.isLoading)
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:selfprivacy/logic/models/server_type.dart';
|
|||
import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
|
||||
import 'package:selfprivacy/ui/components/info_box/info_box.dart';
|
||||
import 'package:selfprivacy/ui/layouts/responsive_layout_with_infobox.dart';
|
||||
import 'package:selfprivacy/utils/ui_helpers.dart';
|
||||
|
||||
class ServerTypePicker extends StatefulWidget {
|
||||
const ServerTypePicker({
|
||||
|
@ -329,7 +330,7 @@ class SelectTypePage extends StatelessWidget {
|
|||
'initializing.choose_server_type_payment_per_month'
|
||||
.tr(
|
||||
args: [
|
||||
'${(type.price.value + storagePrice + publicIpPrice).toStringAsFixed(4)} ${type.price.currency.shortcode}'
|
||||
'${UiHelpers.formatWithPrecision(type.price.value + storagePrice + publicIpPrice)} ${type.price.currency.shortcode}',
|
||||
],
|
||||
),
|
||||
style: Theme.of(context)
|
||||
|
@ -370,8 +371,10 @@ class SelectTypePage extends StatelessWidget {
|
|||
'initializing.choose_server_type_payment_server'
|
||||
.tr(
|
||||
args: [
|
||||
type.price.value
|
||||
.toString()
|
||||
UiHelpers
|
||||
.formatWithPrecision(
|
||||
type.price.value,
|
||||
),
|
||||
],
|
||||
),
|
||||
style: Theme.of(context)
|
||||
|
@ -401,7 +404,10 @@ class SelectTypePage extends StatelessWidget {
|
|||
'initializing.choose_server_type_payment_storage'
|
||||
.tr(
|
||||
args: [
|
||||
storagePrice.toString()
|
||||
UiHelpers
|
||||
.formatWithPrecision(
|
||||
storagePrice,
|
||||
),
|
||||
],
|
||||
),
|
||||
style: Theme.of(context)
|
||||
|
@ -432,7 +438,10 @@ class SelectTypePage extends StatelessWidget {
|
|||
'initializing.choose_server_type_payment_ip'
|
||||
.tr(
|
||||
args: [
|
||||
publicIpPrice.toString()
|
||||
UiHelpers
|
||||
.formatWithPrecision(
|
||||
publicIpPrice,
|
||||
),
|
||||
],
|
||||
),
|
||||
style: Theme.of(context)
|
||||
|
|
|
@ -25,7 +25,7 @@ class RecoverByNewDeviceKeyInstruction extends StatelessWidget {
|
|||
child: Text('recovering.method_device_button'.tr()),
|
||||
onPressed: () => Navigator.of(context)
|
||||
.push(materialRoute(const RecoverByNewDeviceKeyInput())),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class RecoverByNewDeviceKeyInput extends StatelessWidget {
|
|||
: () =>
|
||||
context.read<RecoveryDeviceFormCubit>().trySubmit(),
|
||||
child: Text('basis.continue'.tr()),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
@ -41,7 +41,7 @@ class RecoverByOldTokenInstruction extends StatelessWidget {
|
|||
onPressed: () => context
|
||||
.read<ServerInstallationCubit>()
|
||||
.selectRecoveryMethod(ServerRecoveryMethods.oldToken),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -90,7 +90,7 @@ class RecoverByOldToken extends StatelessWidget {
|
|||
? null
|
||||
: () => context.read<RecoveryDeviceFormCubit>().trySubmit(),
|
||||
child: Text('basis.continue'.tr()),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
@ -50,7 +50,7 @@ class RecoverByRecoveryKey extends StatelessWidget {
|
|||
? null
|
||||
: () => context.read<RecoveryDeviceFormCubit>().trySubmit(),
|
||||
child: Text('basis.continue'.tr()),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
|
@ -81,7 +81,7 @@ class _RecoveryConfirmServerState extends State<RecoveryConfirmServer> {
|
|||
);
|
||||
}
|
||||
},
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class RecoveryMethodSelect extends StatelessWidget {
|
|||
title: 'recovering.method_select_nothing'.tr(),
|
||||
onPressed: () => Navigator.of(context)
|
||||
.push(materialRoute(const RecoveryFallbackMethodSelect())),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ class SelectDomainToRecover extends StatelessWidget {
|
|||
: () =>
|
||||
context.read<RecoveryDomainFormCubit>().trySubmit(),
|
||||
child: Text('basis.continue'.tr()),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -23,7 +23,7 @@ class RecoveryServerProviderConnected extends StatelessWidget {
|
|||
heroTitle: 'recovering.provider_connected'.tr(
|
||||
args: [
|
||||
appConfig.state.serverDetails?.provider.displayName ??
|
||||
'Server Provider'
|
||||
'Server Provider',
|
||||
],
|
||||
),
|
||||
heroSubtitle: 'recovering.provider_connected_description'.tr(
|
||||
|
@ -45,7 +45,7 @@ class RecoveryServerProviderConnected extends StatelessWidget {
|
|||
labelText: 'recovering.provider_connected_placeholder'.tr(
|
||||
args: [
|
||||
appConfig.state.serverDetails?.provider.displayName ??
|
||||
'Server Provider'
|
||||
'Server Provider',
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -124,7 +124,7 @@ class _DeleteUserTile extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
},
|
||||
leading: const Icon(Icons.person_remove_outlined),
|
||||
title: Text(
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
|
|||
const Set<TargetPlatform> _desktop = <TargetPlatform>{
|
||||
TargetPlatform.linux,
|
||||
TargetPlatform.macOS,
|
||||
TargetPlatform.windows
|
||||
TargetPlatform.windows,
|
||||
};
|
||||
|
||||
const Set<TargetPlatform> _mobile = <TargetPlatform>{
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
extension TextExtension on Text {
|
||||
Text withColor(final Color color) => Text(
|
||||
data!,
|
||||
key: key,
|
||||
strutStyle: strutStyle,
|
||||
textAlign: textAlign,
|
||||
textDirection: textDirection,
|
||||
locale: locale,
|
||||
softWrap: softWrap,
|
||||
overflow: overflow,
|
||||
textScaleFactor: textScaleFactor,
|
||||
maxLines: maxLines,
|
||||
semanticsLabel: semanticsLabel,
|
||||
textWidthBasis: textWidthBasis ?? textWidthBasis,
|
||||
style: style != null
|
||||
? style!.copyWith(color: color)
|
||||
: TextStyle(color: color),
|
||||
);
|
||||
|
||||
Text copyWith({
|
||||
final Key? key,
|
||||
final StrutStyle? strutStyle,
|
||||
final TextAlign? textAlign,
|
||||
final TextDirection? textDirection,
|
||||
final Locale? locale,
|
||||
final bool? softWrap,
|
||||
final TextOverflow? overflow,
|
||||
final double? textScaleFactor,
|
||||
final int? maxLines,
|
||||
final String? semanticsLabel,
|
||||
final TextWidthBasis? textWidthBasis,
|
||||
final TextStyle? style,
|
||||
}) =>
|
||||
Text(
|
||||
data!,
|
||||
key: key ?? this.key,
|
||||
strutStyle: strutStyle ?? this.strutStyle,
|
||||
textAlign: textAlign ?? this.textAlign,
|
||||
textDirection: textDirection ?? this.textDirection,
|
||||
locale: locale ?? this.locale,
|
||||
softWrap: softWrap ?? this.softWrap,
|
||||
overflow: overflow ?? this.overflow,
|
||||
textScaleFactor: textScaleFactor ?? this.textScaleFactor,
|
||||
maxLines: maxLines ?? this.maxLines,
|
||||
semanticsLabel: semanticsLabel ?? this.semanticsLabel,
|
||||
textWidthBasis: textWidthBasis ?? this.textWidthBasis,
|
||||
style: style != null ? this.style?.merge(style) ?? style : this.style,
|
||||
);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||
|
||||
/// it's ui helpers use only for ui components, don't use for logic components.
|
||||
|
@ -5,4 +6,14 @@ import 'package:selfprivacy/logic/cubit/server_installation/server_installation_
|
|||
class UiHelpers {
|
||||
static String getDomainName(final ServerInstallationState config) =>
|
||||
config.isDomainSelected ? config.serverDomain!.domainName : 'example.com';
|
||||
|
||||
static String formatWithPrecision(
|
||||
final double value, {
|
||||
final int fraction = 2,
|
||||
}) {
|
||||
final NumberFormat formatter = NumberFormat();
|
||||
formatter.minimumFractionDigits = 0;
|
||||
formatter.maximumFractionDigits = fraction;
|
||||
return formatter.format(value);
|
||||
}
|
||||
}
|
||||
|
|
1931
pubspec.lock
1931
pubspec.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue