import 'package:http/http.dart' as http; import '../../../errors/server_exception.dart'; import '../../../http_errors.dart'; import '../../nextcloud_ocs.dart'; import 'get_chat_params.dart'; import 'get_chat_response.dart'; /// Long-poll variant of GetChat (`lookIntoFuture=1`). Bypasses [TalkApi] /// because that layer treats non-2xx as errors, and we need 304 to be a /// normal "no new messages" outcome. `setReadMarker=on` lets the server /// move the read cursor whenever the call returns messages. class LongPollChat { final String chatToken; final int lastKnownMessageId; final int timeoutSeconds; LongPollChat({ required this.chatToken, required this.lastKnownMessageId, this.timeoutSeconds = 30, }); /// Returns the response, or `null` on HTTP 304 (server timeout, nothing new). Future run() async { final params = GetChatParams( lookIntoFuture: GetChatParamsSwitch.on, timeout: timeoutSeconds, lastKnownMessageId: lastKnownMessageId, includeLastKnown: GetChatParamsSwitch.off, setReadMarker: GetChatParamsSwitch.on, limit: 100, ); final uri = NextcloudOcs.uri( 'apps/spreed/api/v1/chat/$chatToken', queryParameters: params.toJson(), ); final headers = NextcloudOcs.headers(); final response = (await sendGuarded( 'LongPollChat $uri', () => http .get(uri, headers: headers) .timeout(Duration(seconds: timeoutSeconds + 15)), ))!; final status = response.statusCode; if (status == 304) return null; if (status >= 200 && status < 300) { return GetChatResponse.fromJson(NextcloudOcs.decode(response.body)) ..headers = response.headers; } throw ServerException( statusCode: status, technicalDetails: 'LongPollChat $uri: HTTP $status', ); } }