diff --git a/lib/di_initialization.dart b/lib/di_initialization.dart index 24f1aff..560fd79 100644 --- a/lib/di_initialization.dart +++ b/lib/di_initialization.dart @@ -7,8 +7,10 @@ import 'data/memory/memory_groups_repo.dart'; import 'data/objectbox/objectbox_cache.dart'; import 'data/objectbox/objectbox_connections_repo.dart'; import 'data/objectbox/objectbox_hashtag_repo.dart'; +import 'friendica_client/friendica_client.dart'; import 'globals.dart'; import 'models/auth/profile.dart'; +import 'models/instance_info.dart'; import 'services/auth_service.dart'; import 'services/connections_manager.dart'; import 'services/direct_message_service.dart'; @@ -40,6 +42,9 @@ Future dependencyInjectionInitialization() async { getIt.registerSingleton>( ActiveProfileSelector(null)); + getIt.registerSingleton>( + ActiveProfileSelector(null)); + final secretsService = SecretsService(); final serviceInit = await secretsService.initialize(); @@ -93,4 +98,13 @@ Future updateProfileDependencyInjectors(Profile profile) async { getIt>(); connectionReposSelector.injectEntry( profile, ObjectBoxConnectionsRepo(objectBox)); + + final instanceSelector = getIt>(); + final instanceInfo = await InstanceDataClient(profile).getInstanceData(); + instanceInfo.andThenSuccess( + (instanceInfo) => instanceSelector.injectEntry( + profile, + instanceInfo, + ), + ); } diff --git a/lib/friendica_client/friendica_client.dart b/lib/friendica_client/friendica_client.dart index 5856ec6..f081c0c 100644 --- a/lib/friendica_client/friendica_client.dart +++ b/lib/friendica_client/friendica_client.dart @@ -16,6 +16,7 @@ import '../models/exec_error.dart'; import '../models/gallery_data.dart'; import '../models/group_data.dart'; import '../models/image_entry.dart'; +import '../models/instance_info.dart'; import '../models/media_attachment_uploads/image_types_enum.dart'; import '../models/timeline_entry.dart'; import '../models/user_notification.dart'; @@ -24,6 +25,7 @@ import '../serializers/friendica/gallery_data_friendica_extensions.dart'; import '../serializers/friendica/image_entry_friendica_extensions.dart'; import '../serializers/mastodon/connection_mastodon_extensions.dart'; import '../serializers/mastodon/group_data_mastodon_extensions.dart'; +import '../serializers/mastodon/instance_info_mastodon_extensions.dart'; import '../serializers/mastodon/notification_mastodon_extension.dart'; import '../serializers/mastodon/timeline_entry_mastodon_extensions.dart'; import '../services/network_status_service.dart'; @@ -260,6 +262,41 @@ class InteractionsClient extends FriendicaClient { } } +class InstanceDataClient extends FriendicaClient { + static final _logger = Logger('$InteractionsClient'); + + InstanceDataClient(super.credentials); + + FutureResult getInstanceData() async { + _logger.finest(() => 'Getting $serverName instance info'); + final v2Result = await getInstanceDataV2(); + if (v2Result.isSuccess) { + return v2Result; + } + + return getInstanceDataV1(); + } + + FutureResult getInstanceDataV1() async { + _logger.finest(() => 'Getting $serverName instance info via V1 endpoint'); + final url = Uri.parse('https://$serverName/api/v1/instance'); + final result = await _getApiRequest(url); + return result.andThen((json) { + return fromInstanceV1Json(json); + }).execErrorCast(); + } + + FutureResult getInstanceDataV2() async { + _logger.finest(() => 'Getting $serverName instance info via V2 endpoint'); + final url = Uri.parse('https://$serverName/api/v2/instance'); + final result = await _getApiRequest(url); + return result.andThen((response) { + final instanceInfoResult = fromInstanceV2Json(response); + return instanceInfoResult; + }).execErrorCast(); + } +} + class NotificationsClient extends FriendicaClient { static final _logger = Logger('$NotificationsClient'); diff --git a/lib/models/instance_info.dart b/lib/models/instance_info.dart new file mode 100644 index 0000000..1315b6d --- /dev/null +++ b/lib/models/instance_info.dart @@ -0,0 +1,20 @@ +import 'friendica_version.dart'; + +class InstanceInfo { + final int maxStatusCharacters; + final FriendicaVersion friendicaVersion; + final String versionString; + final int maxImageBytes; + + InstanceInfo({ + required this.maxStatusCharacters, + required this.friendicaVersion, + required this.versionString, + required this.maxImageBytes, + }); + + @override + String toString() { + return 'InstanceInfo{maxStatusCharacters: $maxStatusCharacters, version: $versionString, maxImageBytes: $maxImageBytes}'; + } +} diff --git a/lib/serializers/mastodon/instance_info_mastodon_extensions.dart b/lib/serializers/mastodon/instance_info_mastodon_extensions.dart new file mode 100644 index 0000000..253318e --- /dev/null +++ b/lib/serializers/mastodon/instance_info_mastodon_extensions.dart @@ -0,0 +1,43 @@ +import 'package:result_monad/result_monad.dart'; + +import '../../models/exec_error.dart'; +import '../../models/friendica_version.dart'; +import '../../models/instance_info.dart'; + +const _defaultMaxImageBytes = 819200; +const _defaultMaxCharacters = 4000; + +Result fromInstanceV1Json(Map json) { + return runCatching(() { + final maxStatusCharacters = json['max_toot_chars'] ?? _defaultMaxCharacters; + final versionString = json['version']; + return Result.ok(InstanceInfo( + friendicaVersion: FriendicaVersion.fromMastodonVersionString( + versionString, + ), + maxStatusCharacters: maxStatusCharacters, + versionString: versionString, + maxImageBytes: _defaultMaxImageBytes, + )); + }).execErrorCast(); +} + +Result fromInstanceV2Json(Map json) { + return runCatching(() { + final maxStatusCharacters = json['configuration']?['statuses'] + ?['max_characters'] ?? + _defaultMaxCharacters; + final maxImageBytes = json['configuration']?['media_attachments'] + ?['image_size_limit'] ?? + _defaultMaxImageBytes; + final versionString = + json['friendica']?['version'] ?? 'Not a friendica server'; + final version = FriendicaVersion.fromVersionString(versionString); + return Result.ok(InstanceInfo( + friendicaVersion: version, + maxStatusCharacters: maxStatusCharacters, + versionString: versionString, + maxImageBytes: maxImageBytes, + )); + }).execErrorCast(); +}