import 'dart:convert'; import 'package:loris/business_logic/account/account.dart'; import 'package:loris/business_logic/timeline/timeline.dart'; import 'package:loris/global.dart' as global; import 'package:http/http.dart' as http; class ConversationModel implements Comparable { final String id; final List accounts; final bool unread; final PostModel? lastStatus; final String identity; ConversationModel( {required this.id, required this.accounts, required this.unread, this.lastStatus, required this.identity}); factory ConversationModel.fromJson( Map json, String identity) { final List accountsJson = json["accounts"]; final List accounts = accountsJson .map( (e) => AccountModel.fromJson(e, identity), ) .toList(); return ConversationModel( accounts: accounts, id: json["id"], identity: identity, unread: json["unread"], lastStatus: PostModel.fromJson(json["last_status"], identity)); } @override int compareTo(other) { if (lastStatus == null && other.lastStatus == null) return 0; if (lastStatus == null) return -1; return lastStatus!.createdAt.compareTo(other.lastStatus!.createdAt); } String getAccountsString() { String ret = ""; for (var acc in accounts) { ret = "$ret${acc.acct}"; } return ret; } } class ConversationModelResult { // list of models final List models; final Map maxIds; ConversationModelResult(this.models, {this.maxIds = const {}}); } /* loads conversation models from timeline */ Future _getConversationModels( String identityName, String? maxId, ) async { final settings = global.settings!; final identity = global.settings!.identities[identityName]!; final headers = { ...identity.getAuthHeaders(), ...global.defaultHeaders, }; final Map queries = { "limit": settings.batchSize.toString(), if (maxId != null) "max_id": maxId, }; final uri = Uri( scheme: "https", host: identity.instanceUrl, queryParameters: queries, path: "/api/v1/conversations", ); final result = await http.get(uri, headers: headers); if (result.statusCode != 200) { return ConversationModelResult([]); } String? newMaxId = result.headers["link"]; final firstOpen = newMaxId?.indexOf("<"); final firstClose = newMaxId?.indexOf(">"); newMaxId = newMaxId?.substring(firstOpen! + 1, firstClose); if (newMaxId != null) { final maxIdUri = Uri.parse(newMaxId); newMaxId = maxIdUri.queryParameters["max_id"]; } return ConversationModelResult( jsonDecode(result.body) .map( (e) => ConversationModel.fromJson(e, identityName), ) .toList(), maxIds: {identityName: newMaxId}, ); } Future getAllConversationModels( Map maxIds) async { List futureResults = []; global.settings!.identities.forEach((key, value) { futureResults.add(_getConversationModels(key, maxIds[key])); }); List results = []; List models = []; for (var element in futureResults) { final r = await element; results.add(r); models.addAll(r.models); } models.sort(); models = models.reversed.toList(); if (models.length > global.settings!.batchSize) { models = models.sublist(0, global.settings!.batchSize); } Map newMaxIds = {}; for (var element in results) { newMaxIds.addAll(element.maxIds); } Set appearingIdentities = {}; for (var i in models) { appearingIdentities.add(i.identity); } newMaxIds.removeWhere((key, value) => (appearingIdentities.contains(value))); return ConversationModelResult(models, maxIds: newMaxIds); }