simplified code across the app and consolidated duplicated helpers

This commit is contained in:
2026-09-27 17:29:54 +02:00
parent 3e856d0b1c
commit ee1240f71a
155 changed files with 1772 additions and 2546 deletions
@@ -0,0 +1,46 @@
import 'package:flutter/foundation.dart';
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';
/// GETs a chat page outside [TalkApi], which treats non-2xx as errors: here
/// HTTP 304 (nothing new / no older messages) is a normal outcome and yields
/// `null`.
Future<GetChatResponse?> fetchChatPage({
required String label,
required String chatToken,
required GetChatParams params,
Duration? timeout,
bool parseOffIsolate = false,
}) async {
final uri = NextcloudOcs.uri(
'apps/spreed/api/v1/chat/$chatToken',
queryParameters: params.toJson(),
);
final headers = NextcloudOcs.headers();
final response = (await sendGuarded('$label $uri', () {
final request = http.get(uri, headers: headers);
return timeout == null ? request : request.timeout(timeout);
}))!;
final status = response.statusCode;
if (status == 304) return null;
if (status >= 200 && status < 300) {
final parsed = parseOffIsolate
? await compute(_parseChatResponse, response.body)
: _parseChatResponse(response.body);
return parsed..headers = response.headers;
}
throw ServerException(
statusCode: status,
technicalDetails: '$label $uri: HTTP $status',
);
}
GetChatResponse _parseChatResponse(String body) =>
GetChatResponse.fromJson(NextcloudOcs.decode(body));
@@ -1,6 +1,3 @@
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import '../../nextcloud_ocs.dart';
import '../talk_api.dart';
import 'get_chat_params.dart';
@@ -16,11 +13,4 @@ class GetChat extends TalkApi<GetChatResponse> {
@override
GetChatResponse assemble(String raw) =>
GetChatResponse.fromJson(NextcloudOcs.decode(raw));
@override
Future<Response> request(
Uri uri,
Object? body,
Map<String, String>? headers,
) => http.get(uri, headers: headers);
}
@@ -1,17 +1,12 @@
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import '../../../errors/server_exception.dart';
import '../../../http_errors.dart';
import '../../nextcloud_ocs.dart';
import 'fetch_chat_page.dart';
import 'get_chat_params.dart';
import 'get_chat_response.dart';
/// Backwards-paging variant of GetChat (`lookIntoFuture=0` + `lastKnownMessageId`)
/// that fetches the page of messages *older* than a given id. Bypasses [TalkApi]
/// because that layer treats non-2xx as errors, and the server answers HTTP 304
/// when there are no older messages left — a normal "start of chat" outcome here.
/// `setReadMarker=off` so paging into history never moves the read cursor.
/// that fetches the page of messages *older* than a given id. The server
/// answers HTTP 304 when there are no older messages left — a normal "start of
/// chat" outcome (see [fetchChatPage]). `setReadMarker=off` so paging into
/// history never moves the read cursor.
class GetChatHistory {
final String chatToken;
final int lastKnownMessageId;
@@ -24,39 +19,18 @@ class GetChatHistory {
});
/// Returns the older page, or `null` on HTTP 304 (no older messages).
Future<GetChatResponse?> run() async {
final params = GetChatParams(
Future<GetChatResponse?> run() => fetchChatPage(
label: 'GetChatHistory',
chatToken: chatToken,
params: GetChatParams(
lookIntoFuture: GetChatParamsSwitch.off,
lastKnownMessageId: lastKnownMessageId,
includeLastKnown: GetChatParamsSwitch.off,
setReadMarker: GetChatParamsSwitch.off,
limit: limit,
);
final uri = NextcloudOcs.uri(
'apps/spreed/api/v1/chat/$chatToken',
queryParameters: params.toJson(),
);
final headers = NextcloudOcs.headers();
final response = (await sendGuarded(
'GetChatHistory $uri',
() => http.get(uri, headers: headers),
))!;
final status = response.statusCode;
if (status == 304) return null;
if (status >= 200 && status < 300) {
// A page holds up to 200 messages and lands while the user is scrolling;
// decoding it on the UI isolate stalls the fling.
final parsed = await compute(_parseChatResponse, response.body);
return parsed..headers = response.headers;
}
throw ServerException(
statusCode: status,
technicalDetails: 'GetChatHistory $uri: HTTP $status',
);
}
),
// A page holds up to 200 messages and lands while the user is scrolling;
// decoding it on the UI isolate stalls the fling.
parseOffIsolate: true,
);
}
GetChatResponse _parseChatResponse(String body) =>
GetChatResponse.fromJson(NextcloudOcs.decode(body));
@@ -1,15 +1,10 @@
import 'package:http/http.dart' as http;
import '../../../errors/server_exception.dart';
import '../../../http_errors.dart';
import '../../nextcloud_ocs.dart';
import 'fetch_chat_page.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.
/// Long-poll variant of GetChat (`lookIntoFuture=1`); HTTP 304 is the normal
/// "no new messages" outcome (see [fetchChatPage]). `setReadMarker=on` lets
/// the server move the read cursor whenever the call returns messages.
class LongPollChat {
final String chatToken;
final int lastKnownMessageId;
@@ -22,37 +17,17 @@ class LongPollChat {
});
/// Returns the response, or `null` on HTTP 304 (server timeout, nothing new).
Future<GetChatResponse?> run() async {
final params = GetChatParams(
Future<GetChatResponse?> run() => fetchChatPage(
label: 'LongPollChat',
chatToken: chatToken,
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',
);
}
),
timeout: Duration(seconds: timeoutSeconds + 15),
);
}