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
@@ -2,8 +2,8 @@ import 'dart:convert';
import 'package:dio/dio.dart';
import '../../../errors/app_exception.dart';
import '../../../errors/ticker_content_unavailable_exception.dart';
import '../../errors/marianumconnect_error.dart';
import '../../marianumconnect_query.dart';
import 'get_ticker_page_response.dart';
@@ -14,26 +14,20 @@ import 'get_ticker_page_response.dart';
/// 404 `{ "error": "CONTENT_UNAVAILABLE", "webUrl": ... }`; that case is mapped
/// to a dedicated [TickerContentUnavailableException] carrying the browser
/// fallback URL, so the detail screen can offer "open in browser" instead of a
/// generic error. The bespoke 404 handling is why this keeps its own try/catch
/// instead of the base [guard].
/// generic error.
class GetTickerPage extends MarianumConnectQuery {
final String slug;
GetTickerPage(this.slug, {super.dio});
Future<TickerPageResponse> run() async {
try {
final response = await dio.get<Map<String, dynamic>>(
endpoint('ticker/pages/${Uri.encodeComponent(slug)}'),
);
return TickerPageResponse.fromJson(response.data!);
} on DioException catch (e) {
throw _mapError(e);
}
}
Future<TickerPageResponse> run() => getObject(
'ticker/pages/${Uri.encodeComponent(slug)}',
TickerPageResponse.fromJson,
);
Object _mapError(DioException e) {
final response = e.response;
@override
AppException mapError(DioException error) {
final response = error.response;
if (response?.statusCode == 404) {
final body = _asMap(response?.data);
if (body != null && body['error'] == 'CONTENT_UNAVAILABLE') {
@@ -44,7 +38,7 @@ class GetTickerPage extends MarianumConnectQuery {
);
}
}
return mapMarianumConnectError(e);
return super.mapError(error);
}
Map<String, dynamic>? _asMap(dynamic data) {
@@ -1,10 +1,10 @@
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../../client_platform.dart';
import 'report_client_error.dart';
/// Fire-and-forget bridge from the app's global error handlers to the
@@ -61,7 +61,7 @@ class ClientErrorReporter {
message: message,
stacktrace: stacktrace,
context: context,
platform: _platform(),
platform: clientPlatform(),
appVersion: _appVersion,
);
} catch (e) {
@@ -73,10 +73,4 @@ class ClientErrorReporter {
final normalized = message.toLowerCase().replaceAll(RegExp(r'\d+'), '#');
return '$errorType|$normalized|${context ?? ''}';
}
static String? _platform() {
if (Platform.isAndroid) return 'android';
if (Platform.isIOS) return 'ios';
return null;
}
}
@@ -5,6 +5,7 @@ import 'dart:typed_data';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../../client_platform.dart';
import '../../marianumconnect_query.dart';
/// Submits user feedback to MarianumConnect (`POST me/feedback`, bearer-auth).
@@ -27,7 +28,7 @@ class SubmitFeedback extends MarianumConnectQuery {
'message': message,
'screenshot': ?screenshotBase64,
'screenshotContentType': screenshot != null ? screenshotContentType : null,
'platform': _platform(),
'platform': clientPlatform(),
'appVersion': package.version,
'appBuild': int.tryParse(package.buildNumber),
'deviceModel': await _deviceModel(),
@@ -35,12 +36,6 @@ class SubmitFeedback extends MarianumConnectQuery {
);
});
static String? _platform() {
if (Platform.isAndroid) return 'android';
if (Platform.isIOS) return 'ios';
return null;
}
static Future<String?> _deviceModel() async {
try {
final info = DeviceInfoPlugin();