loris/lib/business_logic/chat/chat.dart

145 lines
3.9 KiB
Dart

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<AccountModel> 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<String, dynamic> json, String identity) {
final List accountsJson = json["accounts"];
final List<AccountModel> 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<ConversationModel> models;
final Map<String, String?> maxIds;
ConversationModelResult(this.models, {this.maxIds = const {}});
}
/*
loads conversation models from timeline
*/
Future<ConversationModelResult> _getConversationModels(
String identityName,
String? maxId,
) async {
final settings = global.settings!;
final identity = global.settings!.identities[identityName]!;
final headers = {
...identity.getAuthHeaders(),
...global.defaultHeaders,
};
final Map<String, String> 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<ConversationModel>(
(e) => ConversationModel.fromJson(e, identityName),
)
.toList(),
maxIds: {identityName: newMaxId},
);
}
Future<ConversationModelResult> getAllConversationModels(
Map<String, String?> maxIds) async {
List<Future> futureResults = [];
global.settings!.identities.forEach((key, value) {
futureResults.add(_getConversationModels(key, maxIds[key]));
});
List<ConversationModelResult> results = [];
List<ConversationModel> 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<String, String?> newMaxIds = {};
for (var element in results) {
newMaxIds.addAll(element.maxIds);
}
Set<String> appearingIdentities = {};
for (var i in models) {
appearingIdentities.add(i.identity);
}
newMaxIds.removeWhere((key, value) => (appearingIdentities.contains(value)));
print(newMaxIds);
return ConversationModelResult(models, maxIds: newMaxIds);
}