303 lines
7.3 KiB
Dart
303 lines
7.3 KiB
Dart
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<dynamic>? 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<String, dynamic> 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<String, dynamic> 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<Map<int, RelationshipModel?>> getRelationship(
|
|
String identityName, String id) async {
|
|
final identity = global.settings!.identities[identityName]!;
|
|
|
|
Map<String, String> 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) {
|
|
return {
|
|
response.statusCode:
|
|
RelationshipModel.fromJson(jsonDecode(response.body)[0], identityName)
|
|
};
|
|
}
|
|
|
|
return {404: null};
|
|
}
|
|
|
|
Future<Map<int, AccountModel?>> searchModel(
|
|
String identityName, String url) async {
|
|
final identity = global.settings!.identities[identityName]!;
|
|
|
|
Map<String, String> headers = identity.getAuthHeaders();
|
|
headers.addAll(global.defaultHeaders);
|
|
|
|
Map<String, String> 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<dynamic> 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<dynamic> 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<MapEntry<int, List<ThreadModel>?>> 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);
|
|
}
|
|
|
|
final List<dynamic> rb = jsonDecode(r.body);
|
|
List<ThreadModel> threads = [];
|
|
for (var element in rb) {
|
|
threads.add(
|
|
await PostModel.fromJson(
|
|
element,
|
|
model.identity,
|
|
).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<MapEntry<int, RelationshipModel?>> 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,
|
|
),
|
|
);
|
|
}
|