diff --git a/lib/logic/api_maps/graphql_maps/graphql_api_map.dart b/lib/logic/api_maps/graphql_maps/graphql_api_map.dart index 75183cd1..0c5ababa 100644 --- a/lib/logic/api_maps/graphql_maps/graphql_api_map.dart +++ b/lib/logic/api_maps/graphql_maps/graphql_api_map.dart @@ -101,7 +101,13 @@ abstract class GraphQLApiMap { final WebSocketLink webSocketLink = WebSocketLink( 'ws://api.$rootAddress/graphql', config: SocketClientConfig( + // TODO: Figure out the keep alive pings, as the app disconnects after 30s of inactivity. autoReconnect: true, + initialPayload: _token.isEmpty + ? null + : { + 'Authorization': 'Bearer $_token', + }, headers: _token.isEmpty ? null : { diff --git a/lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart b/lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart index 4332fc4d..8f667465 100644 --- a/lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart +++ b/lib/logic/api_maps/graphql_maps/server_api/jobs_api.dart @@ -22,6 +22,18 @@ mixin JobsApi on GraphQLApiMap { return jobsList; } + Stream> getServerJobsStream() async* { + final GraphQLClient client = await getSubscriptionClient(); + final subscription = client.subscribe$JobUpdates(); + await for (final response in subscription) { + final jobsList = response.parsedData?.jobUpdates + .map((final job) => ServerJob.fromGraphQL(job)) + .toList() ?? + []; + yield jobsList; + } + } + Future> removeApiJob(final String uid) async { try { final GraphQLClient client = await getClient(); diff --git a/lib/logic/get_it/api_connection_repository.dart b/lib/logic/get_it/api_connection_repository.dart index a849c8b9..5b06c563 100644 --- a/lib/logic/get_it/api_connection_repository.dart +++ b/lib/logic/get_it/api_connection_repository.dart @@ -44,6 +44,8 @@ class ApiConnectionRepository { Timer? _timer; + StreamSubscription>? _serverJobsStreamSubscription; + Future removeServerJob(final String uid) async { await api.removeApiJob(uid); _apiData.serverJobs.data @@ -273,6 +275,12 @@ class ApiConnectionRepository { connectionStatus = ConnectionStatus.connected; _connectionStatusStream.add(connectionStatus); + _serverJobsStreamSubscription = + api.getServerJobsStream().listen((final List jobs) { + _apiData.serverJobs.data = jobs; + _dataStream.add(_apiData); + }); + // Use timer to periodically check for new jobs _timer = Timer.periodic( const Duration(seconds: 10), @@ -284,6 +292,7 @@ class ApiConnectionRepository { connectionStatus = ConnectionStatus.nonexistent; _connectionStatusStream.add(connectionStatus); _timer?.cancel(); + await _serverJobsStreamSubscription?.cancel(); } Future _refetchEverything(final Version version) async { @@ -338,7 +347,8 @@ class ApiData { ), serverJobs = ApiDataElement>( fetchData: () async => api.getServerJobs(), - ttl: 10, + // TODO: Figure this out later, as ws keeps this updated + ttl: 10000, ), backupConfig = ApiDataElement( fetchData: () async => api.getBackupsConfiguration(),