diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart index 0ffe7766..a2b53f59 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_cubit.dart @@ -1,34 +1,75 @@ +import 'dart:async'; + import 'package:selfprivacy/config/get_it_config.dart'; import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart'; -import 'package:selfprivacy/logic/cubit/server_detailed_info/server_detailed_info_repository.dart'; import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; import 'package:selfprivacy/logic/models/server_metadata.dart'; +import 'package:selfprivacy/logic/models/system_settings.dart'; import 'package:selfprivacy/logic/models/timezone_settings.dart'; +import 'package:selfprivacy/logic/providers/providers_controller.dart'; part 'server_detailed_info_state.dart'; class ServerDetailsCubit extends ServerConnectionDependentCubit { - ServerDetailsCubit() : super(ServerDetailsInitial()); + ServerDetailsCubit() : super(const ServerDetailsInitial()) { + final apiConnectionRepository = getIt(); + _apiDataSubscription = apiConnectionRepository.dataStream.listen( + (final ApiData apiData) { + if (apiData.settings.data != null) { + _handleServerSettings(apiData.settings.data!); + } + }, + ); + } - ServerDetailsRepository repository = ServerDetailsRepository(); + StreamSubscription? _apiDataSubscription; + + void _handleServerSettings(final SystemSettings settings) { + emit( + Loaded( + metadata: state.metadata, + serverTimezone: TimeZoneSettings.fromString(settings.timezone), + autoUpgradeSettings: settings.autoUpgradeSettings, + ), + ); + } + + Future> get _metadata async { + List data = []; + + final serverProviderApi = ProvidersController.currentServerProvider; + final dnsProviderApi = ProvidersController.currentDnsProvider; + if (serverProviderApi != null && dnsProviderApi != null) { + final serverId = getIt().serverDetails?.id ?? 0; + final metadataResult = await serverProviderApi.getMetadata(serverId); + metadataResult.data.add( + ServerMetadataEntity( + trId: 'server.dns_provider', + value: dnsProviderApi.type.displayName, + type: MetadataType.other, + ), + ); + + data = metadataResult.data; + } + + return data; + } void check() async { final bool isReadyToCheck = getIt().serverDetails != null; try { if (isReadyToCheck) { - emit(ServerDetailsLoading()); - final ServerDetailsRepositoryDto data = await repository.load(); + emit(const ServerDetailsLoading()); + final List metadata = await _metadata; emit( - Loaded( - metadata: data.metadata, - autoUpgradeSettings: data.autoUpgradeSettings, - serverTimezone: data.serverTimezone, - checkTime: DateTime.now(), + state.copyWith( + metadata: metadata, ), ); } else { - emit(ServerDetailsNotReady()); + emit(const ServerDetailsNotReady()); } } on StateError { print('Tried to emit server info state when cubit is closed'); @@ -37,11 +78,17 @@ class ServerDetailsCubit @override void clear() { - emit(ServerDetailsNotReady()); + emit(const ServerDetailsNotReady()); } @override void load() async { check(); } + + @override + Future close() { + _apiDataSubscription?.cancel(); + return super.close(); + } } diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart deleted file mode 100644 index 54540e5f..00000000 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_repository.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:selfprivacy/config/get_it_config.dart'; -import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart'; -import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart'; -import 'package:selfprivacy/logic/models/server_metadata.dart'; -import 'package:selfprivacy/logic/models/timezone_settings.dart'; -import 'package:selfprivacy/logic/providers/providers_controller.dart'; - -class ServerDetailsRepository { - ServerApi server = ServerApi(); - - Future load() async { - final settings = await server.getSystemSettings(); - return ServerDetailsRepositoryDto( - autoUpgradeSettings: settings.autoUpgradeSettings, - metadata: await metadata, - serverTimezone: TimeZoneSettings.fromString( - settings.timezone, - ), - ); - } - - Future> get metadata async { - List data = []; - - final serverProviderApi = ProvidersController.currentServerProvider; - final dnsProviderApi = ProvidersController.currentDnsProvider; - if (serverProviderApi != null && dnsProviderApi != null) { - final serverId = getIt().serverDetails?.id ?? 0; - final metadataResult = await serverProviderApi.getMetadata(serverId); - metadataResult.data.add( - ServerMetadataEntity( - trId: 'server.dns_provider', - value: dnsProviderApi.type.displayName, - type: MetadataType.other, - ), - ); - - data = metadataResult.data; - } - - return data; - } -} - -class ServerDetailsRepositoryDto { - ServerDetailsRepositoryDto({ - required this.metadata, - required this.serverTimezone, - required this.autoUpgradeSettings, - }); - final List metadata; - final TimeZoneSettings serverTimezone; - final AutoUpgradeSettings autoUpgradeSettings; -} diff --git a/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart b/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart index 64f4d91d..8fb3a6c7 100644 --- a/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart +++ b/lib/logic/cubit/server_detailed_info/server_detailed_info_state.dart @@ -1,37 +1,78 @@ part of 'server_detailed_info_cubit.dart'; abstract class ServerDetailsState extends ServerInstallationDependendState { - const ServerDetailsState(); + const ServerDetailsState({ + required this.metadata, + }); + + final List metadata; @override - List get props => []; + List get props => [metadata]; + + ServerDetailsState copyWith({ + final List? metadata, + }); } -class ServerDetailsInitial extends ServerDetailsState {} +class ServerDetailsInitial extends ServerDetailsState { + const ServerDetailsInitial({super.metadata = const []}); -class ServerDetailsLoading extends ServerDetailsState {} + @override + ServerDetailsInitial copyWith({final List? metadata}) => + ServerDetailsInitial( + metadata: metadata ?? this.metadata, + ); +} -class ServerDetailsNotReady extends ServerDetailsState {} +class ServerDetailsLoading extends ServerDetailsState { + const ServerDetailsLoading({super.metadata = const []}); -class Loading extends ServerDetailsState {} + @override + ServerDetailsLoading copyWith({final List? metadata}) => + ServerDetailsLoading( + metadata: metadata ?? this.metadata, + ); +} + +class ServerDetailsNotReady extends ServerDetailsState { + const ServerDetailsNotReady({super.metadata = const []}); + + @override + ServerDetailsNotReady copyWith({ + final List? metadata, + }) => + ServerDetailsNotReady( + metadata: metadata ?? this.metadata, + ); +} class Loaded extends ServerDetailsState { const Loaded({ - required this.metadata, + required super.metadata, required this.serverTimezone, required this.autoUpgradeSettings, - required this.checkTime, }); - final List metadata; final TimeZoneSettings serverTimezone; final AutoUpgradeSettings autoUpgradeSettings; - final DateTime checkTime; @override List get props => [ metadata, serverTimezone, autoUpgradeSettings, - checkTime, ]; + + @override + Loaded copyWith({ + final List? metadata, + final TimeZoneSettings? serverTimezone, + final AutoUpgradeSettings? autoUpgradeSettings, + final DateTime? checkTime, + }) => + Loaded( + metadata: metadata ?? this.metadata, + serverTimezone: serverTimezone ?? this.serverTimezone, + autoUpgradeSettings: autoUpgradeSettings ?? this.autoUpgradeSettings, + ); } diff --git a/lib/logic/get_it/api_connection_repository.dart b/lib/logic/get_it/api_connection_repository.dart index eb818f35..3096874c 100644 --- a/lib/logic/get_it/api_connection_repository.dart +++ b/lib/logic/get_it/api_connection_repository.dart @@ -15,6 +15,7 @@ import 'package:selfprivacy/logic/models/json/recovery_token_status.dart'; import 'package:selfprivacy/logic/models/json/server_disk_volume.dart'; import 'package:selfprivacy/logic/models/json/server_job.dart'; import 'package:selfprivacy/logic/models/service.dart'; +import 'package:selfprivacy/logic/models/system_settings.dart'; /// Repository for all API calls /// Stores the current state of all data from API and exposes it to Blocs. @@ -226,6 +227,7 @@ class ApiConnectionRepository { await _apiData.recoveryKeyStatus.fetchData(); _apiData.devices.data = await _apiData.devices.fetchData(); _apiData.users.data = await _apiData.users.fetchData(); + _apiData.settings.data = await _apiData.settings.fetchData(); _dataStream.add(_apiData); connectionStatus = ConnectionStatus.connected; @@ -270,6 +272,8 @@ class ApiConnectionRepository { await _apiData.devices .refetchData(version, () => _dataStream.add(_apiData)); await _apiData.users.refetchData(version, () => _dataStream.add(_apiData)); + await _apiData.settings + .refetchData(version, () => _dataStream.add(_apiData)); } void emitData() { @@ -312,6 +316,10 @@ class ApiData { ), users = ApiDataElement>( fetchData: () async => api.getAllUsers(), + ), + settings = ApiDataElement( + fetchData: () async => api.getSystemSettings(), + ttl: 600, ); ApiDataElement> serverJobs; @@ -323,6 +331,7 @@ class ApiData { ApiDataElement recoveryKeyStatus; ApiDataElement> devices; ApiDataElement> users; + ApiDataElement settings; } enum ConnectionStatus { diff --git a/lib/logic/models/job.dart b/lib/logic/models/job.dart index bce20d14..81248975 100644 --- a/lib/logic/models/job.dart +++ b/lib/logic/models/job.dart @@ -49,8 +49,7 @@ class RebuildServerJob extends ClientJob { !jobs.any((final job) => job is RebuildServerJob); @override - Future<(bool, String)> execute() async => - (false, 'unimplemented'); + Future<(bool, String)> execute() async => (false, 'unimplemented'); @override RebuildServerJob copyWithNewStatus({ @@ -73,8 +72,7 @@ class UpgradeServerJob extends ClientJob { !jobs.any((final job) => job is UpgradeServerJob); @override - Future<(bool, String)> execute() async => - (false, 'unimplemented'); + Future<(bool, String)> execute() async => (false, 'unimplemented'); @override UpgradeServerJob copyWithNewStatus({ @@ -100,8 +98,7 @@ class RebootServerJob extends ClientJob { !jobs.any((final job) => job is RebootServerJob); @override - Future<(bool, String)> execute() async => - (false, 'unimplemented'); + Future<(bool, String)> execute() async => (false, 'unimplemented'); @override RebootServerJob copyWithNewStatus({ @@ -232,7 +229,9 @@ class ServiceToggleJob extends ClientJob { @override Future<(bool, String)> execute() async { - await getIt().api.switchService(service.id, needToTurnOn); + await getIt() + .api + .switchService(service.id, needToTurnOn); return (true, 'Check not implemented'); } @@ -353,8 +352,9 @@ class ChangeAutoUpgradeSettingsJob extends ReplaceableJob { @override Future<(bool, String)> execute() async { await getIt().api.setAutoUpgradeSettings( - AutoUpgradeSettings(enable: enable, allowReboot: allowReboot), - ); + AutoUpgradeSettings(enable: enable, allowReboot: allowReboot), + ); + getIt().apiData.settings.invalidate(); return (true, 'Check not implemented'); } @@ -394,6 +394,7 @@ class ChangeServerTimezoneJob extends ReplaceableJob { @override Future<(bool, String)> execute() async { await getIt().api.setTimezone(timezone); + getIt().apiData.settings.invalidate(); return (true, 'Check not implemented'); }