import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/business_logic/account/account.dart'; import 'package:loris/business_logic/timeline/timeline.dart'; import '../../global.dart' as global; import 'package:http/http.dart' as http; class NotificationModel implements Comparable { late String id; late String time; late NotificationType type; late AccountModel account; late PostModel? post; late String identity; NotificationModel.fromJson(Map json, String identity) { post = null; time = json["created_at"]; id = json["id"]; account = AccountModel.fromJson(json["account"]); type = NotificationType.values .firstWhere((element) => element.param == json["type"]); if (json["status"] != null) { post = PostModel.fromJson(json["status"], identity); } } @override int compareTo(other) { return time.compareTo(other.time); } } class NotificationData { // stores latest post ids for each identity // value is null if there is no latest id final Map latest; final List models; NotificationData(this.latest, this.models); } Future loadOldNotifications( Map? data, ) async { List models = []; Map map = data ?? {}; for (int i = 0; i < global.settings!.identities.length; i++) { final idkey = global.settings!.identities.keys.toList()[i]; final id = global.settings!.identities[idkey]!; Map headers = id.getAuthHeaders(); headers.addAll(global.defaultHeaders); Map query = { "limit": global.settings!.batchSize.toString() }; if (map[idkey] != null) { query.addAll({"max_id": map[idkey]!}); } final uri = Uri( host: id.instanceUrl, path: "/api/v1/notifications", scheme: "https", queryParameters: query, ); final response = await http.get( uri, headers: headers, ); // get notifs if (response.statusCode == 200) { List json = jsonDecode(response.body); for (int n = 0; n < json.length; n++) { NotificationModel model = NotificationModel.fromJson(json[n], idkey); model.identity = idkey; models.add(model); } } } // massage list models.sort(); models = models.reversed.toList(); models.removeRange(global.settings!.batchSize, models.length); for (NotificationModel m in models) { if (map[m.identity] == null) { map.addAll({ m.identity: m.id, }); } else if (m.id.compareTo(map[m.identity]!) < 0) { map.addAll({m.identity: m.id}); } } return NotificationData(map, models); } enum NotificationType { follow, followRequest, mention, reblog, favourite, poll, status, } extension NotificationTypeExtension on NotificationType { String get name { switch (this) { case NotificationType.followRequest: return "follow_request"; default: return toString(); } } String get param { switch (this) { case NotificationType.favourite: return "favourite"; case NotificationType.followRequest: return "follow_request"; case NotificationType.mention: return "mention"; case NotificationType.reblog: return "reblog"; case NotificationType.poll: return "poll"; case NotificationType.status: return "status"; case NotificationType.follow: return "follow"; } } IconData get icon { switch (this) { case NotificationType.follow: return Icons.person_add; case NotificationType.followRequest: return Icons.person_add; case NotificationType.mention: return Icons.forum; case NotificationType.favourite: return Icons.favorite; case NotificationType.poll: return Icons.poll; case NotificationType.reblog: return Icons.repeat; case NotificationType.status: return Icons.forum; default: return Icons.question_mark; } } String get actionName { switch (this) { case NotificationType.favourite: return "liked-your-post".i18n(); case NotificationType.follow: return "followed-you".i18n(); case NotificationType.followRequest: return "requested-to-folow-you".i18n(); case NotificationType.mention: return "mentioned-you".i18n(); case NotificationType.reblog: return "reblogged-your-post".i18n(); case NotificationType.status: return "made-a-status".i18n(); case NotificationType.poll: return "poll-has-ended".i18n(); default: return "interacted-with-you".i18n(); } } }