Compare commits

...

24 Commits

Author SHA1 Message Date
NaiJi ✨ 76f977bc50 Merge pull request 'feat(ui): Add jobs fab button to Snapshot List page' (#396) from snapshost-list-fab into master
continuous-integration/drone/push Build is failing Details
Reviewed-on: #396
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
21 hours ago
NaiJi ✨ 5a33bec6bd feat(ui): Make Snapshot List page show fab button
- Resolve #290
21 hours ago
NaiJi ✨ 087813eaae Merge pull request 'fix: Revert lints of premaster flutter version back to 3.16' (#391) from fix-flutter-versioning-lints into master
continuous-integration/drone/push Build is failing Details
Reviewed-on: #391
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
1 week ago
NaiJi ✨ e50ef9b189 fix: Revert lints of premaster flutter version back to 3.16 1 week ago
NaiJi ✨ 699f906bf1 Merge pull request 'refactor: Fix linter warnings' (#384) from lints into master
continuous-integration/drone/push Build is failing Details
Reviewed-on: #384
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
1 week ago
NaiJi ✨ 8dc5847c6c Merge branch 'master' into 'lints' 1 week ago
NaiJi ✨ 1e68789a8c fix: Bump material_color_utilities version to 0.5.0, required by flutter test 1 week ago
NaiJi ✨ f11a75dfb7 refactor: Remove obsolete network objects 1 week ago
NaiJi ✨ d4ff17201e Merge pull request 'fix(hetzner): Remove optional status enum for getVolumes of Hetzner' (#388) from hetzner-volume into master
continuous-integration/drone/push Build is passing Details
Reviewed-on: #388
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
1 week ago
NaiJi ✨ cea2f6d8a4 refactor: Correct a typo in Hetzner API 1 week ago
NaiJi ✨ f7afd6fd15 fix(hetzner): Remove optional status enum for getVolumes of Hetzner 1 week ago
NaiJi ✨ 54dee9c291 Merge pull request 'feat: Implement flexible precision formatting for prices' (#387) from string-trailing into master
continuous-integration/drone/push Build is passing Details
Reviewed-on: #387
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
2 weeks ago
NaiJi ✨ a2b28e199d feat: Implement flexible precision formatting for prices 2 weeks ago
NaiJi ✨ 98262a473f Merge pull request 'fix(api): Force DateTime to UTC where timezone naive' (#386) from timezone-offset into master
continuous-integration/drone/push Build is passing Details
Reviewed-on: #386
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
2 weeks ago
NaiJi ✨ ec8d08ff07 fix(api): Force DateTime to UTC where timezone naive
- Solve #385
2 weeks ago
NaiJi ✨ c894456fe6 refactor: Fix linter warnings
- Remove unused text_extensions.dart
3 weeks ago
def dd9722646e Merge pull request 'update description' (#377) from update_description into master
continuous-integration/drone/push Build is passing Details
Reviewed-on: #377
Reviewed-by: Inex Code <inex.code@selfprivacy.org>
1 month ago
dettlaff a01f9d3786 Merge branch 'update_description' of git.selfprivacy.org:SelfPrivacy/selfprivacy.org.app into update_description 1 month ago
dettlaff c05a3d99a6 docs: update screenshot names, del old 1 month ago
def d14c2c5d36 docs: delete /fastlane/metadata/android/en-US/images/phoneScreenshots/4.jpg 1 month ago
dettlaff 1db6dc717a docs: upd description 1 month ago
dettlaff e337e93ac7 docs: add new screenshots 1 month ago
dettlaff 2eda1d18d2 docs: upd description 2 months ago
dettlaff d68b0b5251 docs: add new screenshots 2 months ago

@ -1,6 +1,6 @@
<p>SelfPrivacy — is a platform on your cloud hosting, that allows to deploy your own private services and control them using mobile application.</p>
<p>To use this application, you'll be required to create accounts of different service providers. Please reffer to this manual: https://selfprivacy.org/en/second</p>
<p>To use this application, you'll be required to create accounts of different service providers. Please reffer to this manual: https://selfprivacy.org/docs/getting-started/</p>
<p>Application will do the following things for you:</p>
@ -17,7 +17,5 @@
<li>Pleroma — your private fediverse space for blogging</li>
<li>Jitsi — awesome Zoom alternative</li>
<li>Gitea — your own Git server</li>
<li>OpenConnect — Personal VPN server</li>
</ul>
<p><b>Project is currently in open beta state</b>. Feel free to try it. It would be much appreciated if you would provide us with some feedback.</p>

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

@ -29,7 +29,7 @@ mixin ServerActionsApi on GraphQLApiMap {
print(response.exception.toString());
}
if (response.parsedData!.rebootSystem.success) {
time = DateTime.now();
time = DateTime.now().toUtc();
}
} catch (e) {
print(e);

@ -248,7 +248,7 @@ class ServerApi extends GraphQLApiMap
final GraphQLClient client = await getClient();
final input = Input$RecoveryKeyLimitsInput(
expirationDate: expirationDate,
expirationDate: expirationDate?.toUtc(),
uses: numberOfUses,
);
final variables = Variables$Mutation$GetNewRecoveryApiKey(

@ -137,7 +137,7 @@ class BackblazeApi extends RestApiMap {
{
'daysFromHidingToDeleting': 30,
'daysFromUploadingToHiding': null,
'fileNamePrefix': ''
'fileNamePrefix': '',
}
],
},

@ -5,7 +5,6 @@ import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
import 'package:selfprivacy/logic/api_maps/rest_maps/rest_api_map.dart';
import 'package:selfprivacy/logic/api_maps/tls_options.dart';
import 'package:selfprivacy/logic/models/disk_size.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/json/digital_ocean_server_info.dart';
import 'package:selfprivacy/utils/password_generator.dart';

@ -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,
],
),
);

@ -385,7 +385,7 @@ class CloudflareDnsProvider extends DnsProvider {
mx,
txt1,
txt2,
vpn
vpn,
];
}

@ -323,7 +323,7 @@ class DesecDnsProvider extends DnsProvider {
mx,
txt1,
txt2,
vpn
vpn,
];
}

@ -276,7 +276,7 @@ class DigitalOceanDnsProvider extends DnsProvider {
mx,
txt1,
txt2,
vpn
vpn,
];
}

@ -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),

@ -31,6 +31,7 @@ class BackupsListPage extends StatelessWidget {
context.watch<BackupsCubit>().state.preventActions;
return BrandHeroScreen(
heroTitle: 'backup.snapshots_title'.tr(),
hasFlashButton: true,
children: [
if (backups.isEmpty)
Center(
@ -39,68 +40,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);
}
}

@ -197,10 +197,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.18.0"
connectivity_plus:
dependency: transitive
description:
@ -697,10 +697,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
version: "0.18.0"
version: "0.18.1"
io:
dependency: transitive
description:
@ -817,26 +817,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: "direct main"
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: transitive
description:
@ -1198,26 +1198,26 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
stream_transform:
dependency: transitive
description:
@ -1246,26 +1246,26 @@ packages:
dependency: transitive
description:
name: test
sha256: "3dac9aecf2c3991d09b9cdde4f98ded7b30804a88a0d7e4e7e1678e78d6b97f4"
sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f
url: "https://pub.dev"
source: hosted
version: "1.24.1"
version: "1.24.9"
test_api:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.1"
test_core:
dependency: transitive
description:
name: test_core
sha256: "5138dbffb77b2289ecb12b81c11ba46036590b72a64a7a90d6ffb880f1a29e93"
sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.5.9"
timezone:
dependency: "direct main"
description:
@ -1410,6 +1410,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.3.0"
web_socket_channel:
dependency: transitive
description:
@ -1467,5 +1475,5 @@ packages:
source: hosted
version: "3.1.1"
sdks:
dart: ">=3.0.2 <4.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.10.2"

@ -39,7 +39,7 @@ dependencies:
ionicons: ^0.2.2
json_annotation: ^4.8.1
local_auth: ^2.1.6
material_color_utilities: ^0.2.0
material_color_utilities: ^0.5.0
modal_bottom_sheet: ^3.0.0-pre
nanoid: ^1.0.0
package_info: ^2.0.2

Loading…
Cancel
Save