mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-08 17:11:14 +00:00
refactor(ui): Refactor server screens
This commit is contained in:
parent
c61b3f5b19
commit
24f2844125
|
@ -16,7 +16,7 @@ class Legend extends StatelessWidget {
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
ColoredCircle(color: color),
|
ColoredCircle(color: color),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
text,
|
text,
|
||||||
style: Theme.of(context).textTheme.labelSmall,
|
style: Theme.of(context).textTheme.labelSmall,
|
||||||
|
|
65
lib/ui/molecules/cards/service_status.dart
Normal file
65
lib/ui/molecules/cards/service_status.dart
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/service.dart';
|
||||||
|
import 'package:selfprivacy/ui/atoms/cards/filled_card.dart';
|
||||||
|
|
||||||
|
class ServiceStatusCard extends StatelessWidget {
|
||||||
|
const ServiceStatusCard({
|
||||||
|
required this.status,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
final ServiceStatus status;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) {
|
||||||
|
late IconData icon;
|
||||||
|
late String buttonTitle;
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case ServiceStatus.active:
|
||||||
|
icon = Icons.check_circle_outline;
|
||||||
|
buttonTitle = 'service_page.status.active';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.inactive:
|
||||||
|
icon = Icons.stop_circle_outlined;
|
||||||
|
buttonTitle = 'service_page.status.inactive';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.failed:
|
||||||
|
icon = Icons.error_outline;
|
||||||
|
buttonTitle = 'service_page.status.failed';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.off:
|
||||||
|
icon = Icons.power_settings_new;
|
||||||
|
buttonTitle = 'service_page.status.off';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.activating:
|
||||||
|
icon = Icons.restart_alt_outlined;
|
||||||
|
buttonTitle = 'service_page.status.activating';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.deactivating:
|
||||||
|
icon = Icons.restart_alt_outlined;
|
||||||
|
buttonTitle = 'service_page.status.deactivating';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ServiceStatus.reloading:
|
||||||
|
icon = Icons.restart_alt_outlined;
|
||||||
|
buttonTitle = 'service_page.status.reloading';
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilledCard(
|
||||||
|
tertiary: true,
|
||||||
|
child: ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
icon,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
title: Text(buttonTitle.tr()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,7 +67,7 @@ class StorageCard extends StatelessWidget {
|
||||||
highlightShape: BoxShape.rectangle,
|
highlightShape: BoxShape.rectangle,
|
||||||
onTap: () => diskStatus.diskVolumes.isEmpty
|
onTap: () => diskStatus.diskVolumes.isEmpty
|
||||||
? null
|
? null
|
||||||
: context.pushRoute(ServerStorageRoute(diskStatus: diskStatus)),
|
: context.pushRoute(const ServerStorageRoute()),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:fl_chart/fl_chart.dart';
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:selfprivacy/ui/molecules/charts/generic_chart.dart';
|
import 'package:selfprivacy/ui/molecules/charts/generic_chart.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_details/server_details_screen.dart';
|
import 'package:selfprivacy/ui/organisms/charts/server_charts.dart';
|
||||||
|
|
||||||
class DiskChart extends GenericLineChart {
|
class DiskChart extends GenericLineChart {
|
||||||
DiskChart({
|
DiskChart({
|
||||||
|
|
|
@ -20,7 +20,6 @@ class UserListItem extends StatelessWidget {
|
||||||
context.pushRoute(UserDetailsRoute(login: user.login));
|
context.pushRoute(UserDetailsRoute(login: user.login));
|
||||||
},
|
},
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: user.color,
|
|
||||||
child: Text(
|
child: Text(
|
||||||
user.login[0].toUpperCase(),
|
user.login[0].toUpperCase(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
part of '../server_details_screen.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||||
|
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/metrics.dart';
|
||||||
|
import 'package:selfprivacy/theming/harmonized_basic_colors.dart';
|
||||||
|
import 'package:selfprivacy/ui/atoms/cards/filled_card.dart';
|
||||||
|
import 'package:selfprivacy/ui/atoms/chart_elements/legend.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/buttons/period_selector.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/cards/chart_card.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/charts/cpu_chart.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/charts/disk_charts.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/charts/memory_chart.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/charts/network_charts.dart';
|
||||||
|
import 'package:selfprivacy/ui/router/router.dart';
|
||||||
|
|
||||||
|
class ServerCharts extends StatelessWidget {
|
||||||
|
const ServerCharts({super.key});
|
||||||
|
|
||||||
class _Chart extends StatelessWidget {
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
final MetricsCubit cubit = context.watch<MetricsCubit>();
|
final MetricsCubit cubit = context.watch<MetricsCubit>();
|
|
@ -9,16 +9,16 @@ import 'package:selfprivacy/ui/molecules/placeholders/empty_page_placeholder.dar
|
||||||
import 'package:selfprivacy/utils/platform_adapter.dart';
|
import 'package:selfprivacy/utils/platform_adapter.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ServerLogsScreen extends StatefulWidget {
|
class ServerLogsPage extends StatefulWidget {
|
||||||
const ServerLogsScreen({this.serviceId, super.key});
|
const ServerLogsPage({this.serviceId, super.key});
|
||||||
|
|
||||||
final String? serviceId;
|
final String? serviceId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ServerLogsScreen> createState() => _ServerLogsScreenState();
|
State<ServerLogsPage> createState() => _ServerLogsPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ServerLogsScreenState extends State<ServerLogsScreen> {
|
class _ServerLogsPageState extends State<ServerLogsPage> {
|
||||||
final ScrollController _scrollController = ScrollController();
|
final ScrollController _scrollController = ScrollController();
|
||||||
late ServerLogsBloc _serverLogsBloc;
|
late ServerLogsBloc _serverLogsBloc;
|
||||||
|
|
|
@ -16,8 +16,8 @@ import 'package:selfprivacy/ui/router/router.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class MemoryUsageByServiceScreen extends StatelessWidget {
|
class MemoryUsageByServicePage extends StatelessWidget {
|
||||||
const MemoryUsageByServiceScreen({super.key});
|
const MemoryUsageByServicePage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => BlocProvider(
|
Widget build(final BuildContext context) => BlocProvider(
|
|
@ -1,4 +1,4 @@
|
||||||
part of '../server_settings_screen.dart';
|
part of 'server_settings.dart';
|
||||||
|
|
||||||
final List<Location> locations = timeZoneDatabase.locations.values.toList()
|
final List<Location> locations = timeZoneDatabase.locations.values.toList()
|
||||||
..sort(
|
..sort(
|
||||||
|
@ -6,14 +6,15 @@ final List<Location> locations = timeZoneDatabase.locations.values.toList()
|
||||||
l1.currentTimeZone.offset.compareTo(l2.currentTimeZone.offset),
|
l1.currentTimeZone.offset.compareTo(l2.currentTimeZone.offset),
|
||||||
);
|
);
|
||||||
|
|
||||||
class SelectTimezone extends StatefulWidget {
|
@RoutePage()
|
||||||
const SelectTimezone({super.key});
|
class SelectTimezonePage extends StatefulWidget {
|
||||||
|
const SelectTimezonePage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SelectTimezone> createState() => _SelectTimezoneState();
|
State<SelectTimezonePage> createState() => _SelectTimezonePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SelectTimezoneState extends State<SelectTimezone> {
|
class _SelectTimezonePageState extends State<SelectTimezonePage> {
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
final TextEditingController searchController = TextEditingController();
|
final TextEditingController searchController = TextEditingController();
|
||||||
|
|
|
@ -3,39 +3,27 @@ import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||||
import 'package:selfprivacy/logic/common_enum/common_enum.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/metrics/metrics_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_status.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/metrics.dart';
|
|
||||||
import 'package:selfprivacy/theming/harmonized_basic_colors.dart';
|
|
||||||
import 'package:selfprivacy/ui/atoms/cards/filled_card.dart';
|
|
||||||
import 'package:selfprivacy/ui/atoms/chart_elements/legend.dart';
|
|
||||||
import 'package:selfprivacy/ui/atoms/icons/brand_icons.dart';
|
import 'package:selfprivacy/ui/atoms/icons/brand_icons.dart';
|
||||||
|
import 'package:selfprivacy/ui/atoms/list_tiles/section_headline.dart';
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
import 'package:selfprivacy/ui/molecules/buttons/period_selector.dart';
|
|
||||||
import 'package:selfprivacy/ui/molecules/cards/chart_card.dart';
|
|
||||||
import 'package:selfprivacy/ui/molecules/cards/server_text_details_card.dart';
|
import 'package:selfprivacy/ui/molecules/cards/server_text_details_card.dart';
|
||||||
import 'package:selfprivacy/ui/molecules/cards/storage_card.dart';
|
import 'package:selfprivacy/ui/molecules/cards/storage_card.dart';
|
||||||
import 'package:selfprivacy/ui/molecules/charts/cpu_chart.dart';
|
import 'package:selfprivacy/ui/organisms/charts/server_charts.dart';
|
||||||
import 'package:selfprivacy/ui/molecules/charts/disk_charts.dart';
|
|
||||||
import 'package:selfprivacy/ui/molecules/charts/memory_chart.dart';
|
|
||||||
import 'package:selfprivacy/ui/molecules/charts/network_charts.dart';
|
|
||||||
import 'package:selfprivacy/ui/router/router.dart';
|
import 'package:selfprivacy/ui/router/router.dart';
|
||||||
|
|
||||||
part 'charts/chart.dart';
|
|
||||||
|
|
||||||
var navigatorKey = GlobalKey<NavigatorState>();
|
var navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ServerDetailsScreen extends StatefulWidget {
|
class ServerDetailsPage extends StatefulWidget {
|
||||||
const ServerDetailsScreen({super.key});
|
const ServerDetailsPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ServerDetailsScreen> createState() => _ServerDetailsScreenState();
|
State<ServerDetailsPage> createState() => _ServerDetailsPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
class _ServerDetailsPageState extends State<ServerDetailsPage>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
late TabController tabController;
|
late TabController tabController;
|
||||||
|
|
||||||
|
@ -89,14 +77,13 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
||||||
onTap: () => context.pushRoute(ServerLogsRoute()),
|
onTap: () => context.pushRoute(ServerLogsRoute()),
|
||||||
),
|
),
|
||||||
const Divider(height: 32),
|
const Divider(height: 32),
|
||||||
Text(
|
SectionHeadline(
|
||||||
'server.resource_usage'.tr(),
|
title: 'server.resource_usage'.tr(),
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (final context) => MetricsCubit()..restart(),
|
create: (final context) => MetricsCubit()..restart(),
|
||||||
child: _Chart(),
|
child: const ServerCharts(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
const ServerTextDetailsCard(),
|
const ServerTextDetailsCard(),
|
|
@ -1,4 +1,37 @@
|
||||||
part of 'server_settings_screen.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart';
|
||||||
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
|
import 'package:selfprivacy/ui/atoms/progress_indicators/brand_loader.dart';
|
||||||
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
|
import 'package:selfprivacy/ui/router/router.dart';
|
||||||
|
import 'package:selfprivacy/utils/breakpoints.dart';
|
||||||
|
import 'package:selfprivacy/utils/extensions/duration.dart';
|
||||||
|
import 'package:timezone/timezone.dart';
|
||||||
|
|
||||||
|
part 'select_timezone.dart';
|
||||||
|
|
||||||
|
@RoutePage()
|
||||||
|
class ServerSettingsPage extends StatefulWidget {
|
||||||
|
const ServerSettingsPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ServerSettingsPage> createState() => _ServerSettingsPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ServerSettingsPageState extends State<ServerSettingsPage> {
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => BrandHeroScreen(
|
||||||
|
hasFlashButton: true,
|
||||||
|
heroIcon: Icons.settings_outlined,
|
||||||
|
heroTitle: 'server.settings'.tr(),
|
||||||
|
children: const [
|
||||||
|
_ServerSettings(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class _ServerSettings extends StatefulWidget {
|
class _ServerSettings extends StatefulWidget {
|
||||||
const _ServerSettings();
|
const _ServerSettings();
|
||||||
|
@ -106,11 +139,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
||||||
serverDetailsState.serverTimezone.toString(),
|
serverDetailsState.serverTimezone.toString(),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(
|
context.pushRoute(const SelectTimezoneRoute());
|
||||||
materialRoute(
|
|
||||||
const SelectTimezone(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SwitchListTile.adaptive(
|
SwitchListTile.adaptive(
|
|
@ -1,35 +0,0 @@
|
||||||
import 'package:auto_route/auto_route.dart';
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
|
||||||
import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart';
|
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
|
||||||
import 'package:selfprivacy/ui/atoms/progress_indicators/brand_loader.dart';
|
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
|
||||||
import 'package:selfprivacy/utils/breakpoints.dart';
|
|
||||||
import 'package:selfprivacy/utils/extensions/duration.dart';
|
|
||||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
|
||||||
import 'package:timezone/timezone.dart';
|
|
||||||
|
|
||||||
part 'server_settings.dart';
|
|
||||||
part 'time_zone/time_zone.dart';
|
|
||||||
|
|
||||||
@RoutePage()
|
|
||||||
class ServerSettingsScreen extends StatefulWidget {
|
|
||||||
const ServerSettingsScreen({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ServerSettingsScreen> createState() => _ServerSettingsScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _ServerSettingsScreenState extends State<ServerSettingsScreen> {
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) => BrandHeroScreen(
|
|
||||||
hasFlashButton: true,
|
|
||||||
heroIcon: Icons.settings_outlined,
|
|
||||||
heroTitle: 'server.settings'.tr(),
|
|
||||||
children: const [
|
|
||||||
_ServerSettings(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
|
import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
|
||||||
|
import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/disk_status.dart';
|
import 'package:selfprivacy/logic/models/disk_status.dart';
|
||||||
|
@ -17,12 +18,9 @@ import 'package:selfprivacy/utils/show_jobs_modal.dart';
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ServerStoragePage extends StatefulWidget {
|
class ServerStoragePage extends StatefulWidget {
|
||||||
const ServerStoragePage({
|
const ServerStoragePage({
|
||||||
required this.diskStatus,
|
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DiskStatus diskStatus;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<ServerStoragePage> createState() => _ServerStoragePageState();
|
State<ServerStoragePage> createState() => _ServerStoragePageState();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +31,7 @@ class _ServerStoragePageState extends State<ServerStoragePage> {
|
||||||
final bool isReady = context.watch<ServerInstallationCubit>().state
|
final bool isReady = context.watch<ServerInstallationCubit>().state
|
||||||
is ServerInstallationFinished;
|
is ServerInstallationFinished;
|
||||||
|
|
||||||
final List<Service> services = context.watch<ServicesBloc>().state.services;
|
final DiskStatus diskStatus = context.watch<VolumesBloc>().state.diskStatus;
|
||||||
|
|
||||||
if (!isReady) {
|
if (!isReady) {
|
||||||
return BrandHeroScreen(
|
return BrandHeroScreen(
|
||||||
|
@ -49,24 +47,10 @@ class _ServerStoragePageState extends State<ServerStoragePage> {
|
||||||
bodyPadding: const EdgeInsets.symmetric(vertical: 16.0),
|
bodyPadding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||||
hasFlashButton: true,
|
hasFlashButton: true,
|
||||||
children: [
|
children: [
|
||||||
...widget.diskStatus.diskVolumes.map(
|
...diskStatus.diskVolumes.map(
|
||||||
(final volume) => Column(
|
(final volume) => DiskConsumptionOverview(
|
||||||
mainAxisSize: MainAxisSize.min,
|
volume: volume,
|
||||||
children: [
|
diskStatus: diskStatus,
|
||||||
ServerStorageSection(
|
|
||||||
volume: volume,
|
|
||||||
diskStatus: widget.diskStatus,
|
|
||||||
services: services
|
|
||||||
.where(
|
|
||||||
(final service) =>
|
|
||||||
service.storageUsage.volume == volume.name,
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
const Gap(16),
|
|
||||||
const Divider(),
|
|
||||||
const Gap(16),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
|
@ -85,6 +69,39 @@ class _ServerStoragePageState extends State<ServerStoragePage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DiskConsumptionOverview extends StatelessWidget {
|
||||||
|
const DiskConsumptionOverview({
|
||||||
|
required this.volume,
|
||||||
|
required this.diskStatus,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final DiskVolume volume;
|
||||||
|
final DiskStatus diskStatus;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) {
|
||||||
|
final List<Service> services = context.watch<ServicesBloc>().state.services;
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ServerStorageSection(
|
||||||
|
volume: volume,
|
||||||
|
diskStatus: diskStatus,
|
||||||
|
services: services
|
||||||
|
.where(
|
||||||
|
(final service) => service.storageUsage.volume == volume.name,
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
const Gap(16),
|
||||||
|
const Divider(),
|
||||||
|
const Gap(16),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ServerStorageSection extends StatelessWidget {
|
class ServerStorageSection extends StatelessWidget {
|
||||||
const ServerStorageSection({
|
const ServerStorageSection({
|
||||||
required this.volume,
|
required this.volume,
|
||||||
|
|
|
@ -8,8 +8,8 @@ import 'package:selfprivacy/logic/bloc/volumes/volumes_bloc.dart';
|
||||||
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
||||||
import 'package:selfprivacy/logic/models/job.dart';
|
import 'package:selfprivacy/logic/models/job.dart';
|
||||||
import 'package:selfprivacy/logic/models/service.dart';
|
import 'package:selfprivacy/logic/models/service.dart';
|
||||||
import 'package:selfprivacy/ui/atoms/cards/filled_card.dart';
|
|
||||||
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
||||||
|
import 'package:selfprivacy/ui/molecules/cards/service_status.dart';
|
||||||
import 'package:selfprivacy/ui/router/router.dart';
|
import 'package:selfprivacy/ui/router/router.dart';
|
||||||
import 'package:selfprivacy/utils/launch_url.dart';
|
import 'package:selfprivacy/utils/launch_url.dart';
|
||||||
import 'package:selfprivacy/utils/platform_adapter.dart';
|
import 'package:selfprivacy/utils/platform_adapter.dart';
|
||||||
|
@ -198,64 +198,3 @@ class _ServicePageState extends State<ServicePage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServiceStatusCard extends StatelessWidget {
|
|
||||||
const ServiceStatusCard({
|
|
||||||
required this.status,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
final ServiceStatus status;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(final BuildContext context) {
|
|
||||||
late IconData icon;
|
|
||||||
late String buttonTitle;
|
|
||||||
|
|
||||||
switch (status) {
|
|
||||||
case ServiceStatus.active:
|
|
||||||
icon = Icons.check_circle_outline;
|
|
||||||
buttonTitle = 'service_page.status.active';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.inactive:
|
|
||||||
icon = Icons.stop_circle_outlined;
|
|
||||||
buttonTitle = 'service_page.status.inactive';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.failed:
|
|
||||||
icon = Icons.error_outline;
|
|
||||||
buttonTitle = 'service_page.status.failed';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.off:
|
|
||||||
icon = Icons.power_settings_new;
|
|
||||||
buttonTitle = 'service_page.status.off';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.activating:
|
|
||||||
icon = Icons.restart_alt_outlined;
|
|
||||||
buttonTitle = 'service_page.status.activating';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.deactivating:
|
|
||||||
icon = Icons.restart_alt_outlined;
|
|
||||||
buttonTitle = 'service_page.status.deactivating';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ServiceStatus.reloading:
|
|
||||||
icon = Icons.restart_alt_outlined;
|
|
||||||
buttonTitle = 'service_page.status.reloading';
|
|
||||||
}
|
|
||||||
|
|
||||||
return FilledCard(
|
|
||||||
tertiary: true,
|
|
||||||
child: ListTile(
|
|
||||||
leading: Icon(
|
|
||||||
icon,
|
|
||||||
size: 24,
|
|
||||||
),
|
|
||||||
title: Text(buttonTitle.tr()),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,10 +20,10 @@ import 'package:selfprivacy/ui/pages/onboarding/onboarding.dart';
|
||||||
import 'package:selfprivacy/ui/pages/providers/providers.dart';
|
import 'package:selfprivacy/ui/pages/providers/providers.dart';
|
||||||
import 'package:selfprivacy/ui/pages/recovery_key/recovery_key.dart';
|
import 'package:selfprivacy/ui/pages/recovery_key/recovery_key.dart';
|
||||||
import 'package:selfprivacy/ui/pages/root_route.dart';
|
import 'package:selfprivacy/ui/pages/root_route.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_details/logs/logs_screen.dart';
|
import 'package:selfprivacy/ui/pages/server/logs.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_details/memory_usage_by_service_screen.dart';
|
import 'package:selfprivacy/ui/pages/server/memory_usage_by_service.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_details/server_details_screen.dart';
|
import 'package:selfprivacy/ui/pages/server/server_details.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_details/server_settings_screen.dart';
|
import 'package:selfprivacy/ui/pages/server/server_settings.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_storage/binds_migration/services_migration.dart';
|
import 'package:selfprivacy/ui/pages/server_storage/binds_migration/services_migration.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_storage/extending_volume.dart';
|
import 'package:selfprivacy/ui/pages/server_storage/extending_volume.dart';
|
||||||
import 'package:selfprivacy/ui/pages/server_storage/server_storage.dart';
|
import 'package:selfprivacy/ui/pages/server_storage/server_storage.dart';
|
||||||
|
@ -108,6 +108,7 @@ class RootRouter extends RootStackRouter {
|
||||||
AutoRoute(page: ServiceRoute.page),
|
AutoRoute(page: ServiceRoute.page),
|
||||||
AutoRoute(page: ServiceSettingsRoute.page),
|
AutoRoute(page: ServiceSettingsRoute.page),
|
||||||
AutoRoute(page: ServerDetailsRoute.page),
|
AutoRoute(page: ServerDetailsRoute.page),
|
||||||
|
AutoRoute(page: SelectTimezoneRoute.page),
|
||||||
AutoRoute(page: DnsDetailsRoute.page),
|
AutoRoute(page: DnsDetailsRoute.page),
|
||||||
AutoRoute(page: BackupDetailsRoute.page),
|
AutoRoute(page: BackupDetailsRoute.page),
|
||||||
AutoRoute(page: BackupsListRoute.page),
|
AutoRoute(page: BackupsListRoute.page),
|
||||||
|
|
|
@ -307,7 +307,7 @@ class InitializingRoute extends PageRouteInfo<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [MemoryUsageByServiceScreen]
|
/// [MemoryUsageByServicePage]
|
||||||
class MemoryUsageByServiceRoute extends PageRouteInfo<void> {
|
class MemoryUsageByServiceRoute extends PageRouteInfo<void> {
|
||||||
const MemoryUsageByServiceRoute({List<PageRouteInfo>? children})
|
const MemoryUsageByServiceRoute({List<PageRouteInfo>? children})
|
||||||
: super(
|
: super(
|
||||||
|
@ -320,7 +320,7 @@ class MemoryUsageByServiceRoute extends PageRouteInfo<void> {
|
||||||
static PageInfo page = PageInfo(
|
static PageInfo page = PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const MemoryUsageByServiceScreen();
|
return const MemoryUsageByServicePage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,26 @@ class RootRoute extends PageRouteInfo<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [ServerDetailsScreen]
|
/// [SelectTimezonePage]
|
||||||
|
class SelectTimezoneRoute extends PageRouteInfo<void> {
|
||||||
|
const SelectTimezoneRoute({List<PageRouteInfo>? children})
|
||||||
|
: super(
|
||||||
|
SelectTimezoneRoute.name,
|
||||||
|
initialChildren: children,
|
||||||
|
);
|
||||||
|
|
||||||
|
static const String name = 'SelectTimezoneRoute';
|
||||||
|
|
||||||
|
static PageInfo page = PageInfo(
|
||||||
|
name,
|
||||||
|
builder: (data) {
|
||||||
|
return const SelectTimezonePage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// generated route for
|
||||||
|
/// [ServerDetailsPage]
|
||||||
class ServerDetailsRoute extends PageRouteInfo<void> {
|
class ServerDetailsRoute extends PageRouteInfo<void> {
|
||||||
const ServerDetailsRoute({List<PageRouteInfo>? children})
|
const ServerDetailsRoute({List<PageRouteInfo>? children})
|
||||||
: super(
|
: super(
|
||||||
|
@ -491,13 +510,13 @@ class ServerDetailsRoute extends PageRouteInfo<void> {
|
||||||
static PageInfo page = PageInfo(
|
static PageInfo page = PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const ServerDetailsScreen();
|
return const ServerDetailsPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [ServerLogsScreen]
|
/// [ServerLogsPage]
|
||||||
class ServerLogsRoute extends PageRouteInfo<ServerLogsRouteArgs> {
|
class ServerLogsRoute extends PageRouteInfo<ServerLogsRouteArgs> {
|
||||||
ServerLogsRoute({
|
ServerLogsRoute({
|
||||||
String? serviceId,
|
String? serviceId,
|
||||||
|
@ -519,7 +538,7 @@ class ServerLogsRoute extends PageRouteInfo<ServerLogsRouteArgs> {
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<ServerLogsRouteArgs>(
|
final args = data.argsAs<ServerLogsRouteArgs>(
|
||||||
orElse: () => const ServerLogsRouteArgs());
|
orElse: () => const ServerLogsRouteArgs());
|
||||||
return ServerLogsScreen(
|
return ServerLogsPage(
|
||||||
serviceId: args.serviceId,
|
serviceId: args.serviceId,
|
||||||
key: args.key,
|
key: args.key,
|
||||||
);
|
);
|
||||||
|
@ -544,7 +563,7 @@ class ServerLogsRouteArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [ServerSettingsScreen]
|
/// [ServerSettingsPage]
|
||||||
class ServerSettingsRoute extends PageRouteInfo<void> {
|
class ServerSettingsRoute extends PageRouteInfo<void> {
|
||||||
const ServerSettingsRoute({List<PageRouteInfo>? children})
|
const ServerSettingsRoute({List<PageRouteInfo>? children})
|
||||||
: super(
|
: super(
|
||||||
|
@ -557,24 +576,17 @@ class ServerSettingsRoute extends PageRouteInfo<void> {
|
||||||
static PageInfo page = PageInfo(
|
static PageInfo page = PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
return const ServerSettingsScreen();
|
return const ServerSettingsPage();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [ServerStoragePage]
|
/// [ServerStoragePage]
|
||||||
class ServerStorageRoute extends PageRouteInfo<ServerStorageRouteArgs> {
|
class ServerStorageRoute extends PageRouteInfo<void> {
|
||||||
ServerStorageRoute({
|
const ServerStorageRoute({List<PageRouteInfo>? children})
|
||||||
required DiskStatus diskStatus,
|
: super(
|
||||||
Key? key,
|
|
||||||
List<PageRouteInfo>? children,
|
|
||||||
}) : super(
|
|
||||||
ServerStorageRoute.name,
|
ServerStorageRoute.name,
|
||||||
args: ServerStorageRouteArgs(
|
|
||||||
diskStatus: diskStatus,
|
|
||||||
key: key,
|
|
||||||
),
|
|
||||||
initialChildren: children,
|
initialChildren: children,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -583,31 +595,11 @@ class ServerStorageRoute extends PageRouteInfo<ServerStorageRouteArgs> {
|
||||||
static PageInfo page = PageInfo(
|
static PageInfo page = PageInfo(
|
||||||
name,
|
name,
|
||||||
builder: (data) {
|
builder: (data) {
|
||||||
final args = data.argsAs<ServerStorageRouteArgs>();
|
return const ServerStoragePage();
|
||||||
return ServerStoragePage(
|
|
||||||
diskStatus: args.diskStatus,
|
|
||||||
key: args.key,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerStorageRouteArgs {
|
|
||||||
const ServerStorageRouteArgs({
|
|
||||||
required this.diskStatus,
|
|
||||||
this.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
final DiskStatus diskStatus;
|
|
||||||
|
|
||||||
final Key? key;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ServerStorageRouteArgs{diskStatus: $diskStatus, key: $key}';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// generated route for
|
/// generated route for
|
||||||
/// [ServicePage]
|
/// [ServicePage]
|
||||||
class ServiceRoute extends PageRouteInfo<ServiceRouteArgs> {
|
class ServiceRoute extends PageRouteInfo<ServiceRouteArgs> {
|
||||||
|
|
|
@ -1411,10 +1411,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
|
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.2.5"
|
version: "14.2.4"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
Loading…
Reference in a new issue