import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:loris/business_logic/timeline/timeline.dart'; import 'package:loris/global.dart' as global; class AccountModel { final String acct; final String displayName; final String avatar; final String url; final String id; final String note; final String header; final bool locked; final bool? discoverable; final List? fields; final bool? bot; final bool? suspended; final String identity; AccountModel({ required this.identity, required this.note, required this.header, required this.locked, this.discoverable, this.fields, this.bot, this.suspended, required this.acct, required this.displayName, required this.avatar, required this.url, required this.id, }); factory AccountModel.fromJson(Map json, String identity) { return AccountModel( identity: identity, id: json["id"], acct: json["acct"], displayName: json["display_name"], avatar: json["avatar"], url: json["url"], note: json["note"], discoverable: json["discoverable"], header: json["header"], locked: json["locked"], bot: json["bot"], fields: json["fields"], suspended: json["suspended"], ); } } class RelationshipModel { final String identity; final bool blockedBy; final bool blocking; final bool endorsed; final bool followedBy; final bool following; final String id; final bool muting; final bool mutingNotifications; final String note; final bool notifying; final bool requested; final bool showingReblogs; RelationshipModel({ required this.identity, required this.blockedBy, required this.blocking, required this.endorsed, required this.followedBy, required this.following, required this.id, required this.muting, required this.mutingNotifications, required this.note, required this.notifying, required this.requested, required this.showingReblogs, }); factory RelationshipModel.fromJson( Map json, String identity, ) { return RelationshipModel( identity: identity, blockedBy: json["blocked_by"], blocking: json["blocking"], endorsed: json["endorsed"], followedBy: json["followed_by"], following: json["following"], id: json["id"], muting: json["muting"], mutingNotifications: json["muting_notifications"], note: json["note"], notifying: json["notifying"], requested: json["requested"], showingReblogs: json["showing_reblogs"]); } } Future> getRelationship( String identityName, String id) async { final identity = global.settings!.identities[identityName]!; Map headers = identity.getAuthHeaders(); headers.addAll(global.defaultHeaders); final uri = Uri( scheme: "https", host: identity.instanceUrl, path: "/api/v1/accounts/relationships", queryParameters: {"id": id}, ); final response = await http.get(uri, headers: headers); if (response.statusCode == 200 && jsonDecode(response.body).isNotEmpty) { return { response.statusCode: RelationshipModel.fromJson(jsonDecode(response.body)[0], identityName) }; } return {response.statusCode: null}; } Future> searchModel( String identityName, String url) async { final identity = global.settings!.identities[identityName]!; Map headers = identity.getAuthHeaders(); headers.addAll(global.defaultHeaders); Map params = { "type": "accounts", "q": url, "limit": "1", "resolve": "true", }; final uri1 = Uri( scheme: "https", host: identity.instanceUrl, path: "/api/v1/search", queryParameters: params, ); final uri2 = Uri( scheme: "https", host: identity.instanceUrl, path: "/api/v2/search", queryParameters: params, ); final r1 = await http.get(uri1, headers: headers); if (r1.statusCode == 200) { List accounts = jsonDecode(r1.body)["accounts"]; if (accounts.isEmpty) { return {r1.statusCode: null}; } return { r1.statusCode: AccountModel.fromJson( jsonDecode(r1.body)["accounts"][0], identityName, ) }; } final r2 = await http.get(uri2, headers: headers); if (r2.statusCode == 200) { List accounts = jsonDecode(r2.body)["accounts"]; if (accounts.isEmpty) { return {r2.statusCode: null}; } return { r2.statusCode: AccountModel.fromJson( jsonDecode(r2.body)["accounts"][0], identityName, ) }; } return {r2.statusCode: null}; } Future?>> getPostsForAccount( AccountModel model, String? maxid, ) async { final identity = global.settings!.identities[model.identity]; var headers = identity!.getAuthHeaders(); headers.addAll(global.defaultHeaders); final params = { "limit": global.settings!.batchSize.toString(), if (maxid != null) "max_id": maxid, }; final uri = Uri( scheme: "https", host: identity.instanceUrl, path: "/api/v1/accounts/${model.id}/statuses", queryParameters: params, ); final r = await http.get(uri, headers: headers); if (r.statusCode != 200) { return MapEntry(r.statusCode, null); } List rb = jsonDecode(r.body); List posts = []; for (var element in rb) { posts.add(PostModel.fromJson(element, model.identity)); } // posts.sort(); List threads = []; for (var element in posts) { threads.add( await element.getThread(), ); } return MapEntry(r.statusCode, threads); } enum AccountInteractionTypes { follow, block, mute, } extension AccountInteractionTypesExenstion on AccountInteractionTypes { String get slug { switch (this) { case AccountInteractionTypes.block: return "block"; case AccountInteractionTypes.follow: return "follow"; case AccountInteractionTypes.mute: return "mute"; } } IconData get icon { switch (this) { case AccountInteractionTypes.block: return Icons.block; case AccountInteractionTypes.follow: return Icons.person_add; case AccountInteractionTypes.mute: return Icons.volume_off; } } String get revokeSlug { switch (this) { case AccountInteractionTypes.block: return "unblock"; case AccountInteractionTypes.follow: return "unfollow"; case AccountInteractionTypes.mute: return "unmute"; } } } enum AccountTextInteractionTypes { note, report, } Future> performInteraction( String identityName, String accountId, AccountInteractionTypes type, bool revoke, ) async { final identity = global.settings!.identities[identityName]!; var headers = identity.getAuthHeaders(); headers.addAll(global.defaultHeaders); headers.remove("Content-Type"); final uri = Uri( scheme: "https", host: identity.instanceUrl, path: "/api/v1/accounts/$accountId/${revoke ? type.revokeSlug : type.slug}"); final response = await http.post(uri, headers: headers); if (response.statusCode != 200) { return MapEntry(response.statusCode, null); } return MapEntry( response.statusCode, RelationshipModel.fromJson( jsonDecode(response.body), identityName, ), ); }