Fix user storage indicator
This commit is contained in:
parent
fd5b234ba9
commit
1c77951431
4 changed files with 148 additions and 30 deletions
|
@ -39,4 +39,11 @@ class UserApi {
|
|||
final data = jsonDecode(response.body);
|
||||
return PersonalProfile.fromMap(data);
|
||||
}
|
||||
|
||||
static Future<StorageQuota> getStorageQuota(ApiClient client) async {
|
||||
final response = await client.get("/users/${client.userId}/storage");
|
||||
client.checkResponse(response);
|
||||
final data = jsonDecode(response.body);
|
||||
return StorageQuota.fromMap(data);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import 'package:recon/auxiliary.dart';
|
||||
import 'package:recon/models/users/entitlement.dart';
|
||||
import 'package:recon/models/users/user_profile.dart';
|
||||
|
||||
class PersonalProfile {
|
||||
|
@ -6,18 +8,21 @@ class PersonalProfile {
|
|||
final String email;
|
||||
final DateTime? publicBanExpiration;
|
||||
final String? publicBanType;
|
||||
final List<StorageQuotas> storageQuotas;
|
||||
final Map<String, int> quotaBytesSource;
|
||||
final int quotaBytes;
|
||||
final int usedBytes;
|
||||
final bool twoFactor;
|
||||
final bool isPatreonSupporter;
|
||||
final UserProfile userProfile;
|
||||
final List<Entitlement> entitlements;
|
||||
final List<SupporterMetadata> supporterMetadata;
|
||||
|
||||
PersonalProfile({
|
||||
required this.id, required this.username, required this.email, required this.publicBanExpiration,
|
||||
required this.publicBanType, required this.storageQuotas, required this.quotaBytesSource, required this.quotaBytes,
|
||||
required this.usedBytes, required this.twoFactor, required this.isPatreonSupporter, required this.userProfile,
|
||||
required this.id,
|
||||
required this.username,
|
||||
required this.email,
|
||||
required this.publicBanExpiration,
|
||||
required this.publicBanType,
|
||||
required this.twoFactor,
|
||||
required this.userProfile,
|
||||
required this.entitlements,
|
||||
required this.supporterMetadata,
|
||||
});
|
||||
|
||||
factory PersonalProfile.fromMap(Map map) {
|
||||
|
@ -27,34 +32,83 @@ class PersonalProfile {
|
|||
email: map["email"] ?? "",
|
||||
publicBanExpiration: DateTime.tryParse(map["publicBanExpiration"] ?? ""),
|
||||
publicBanType: map["publicBanType"],
|
||||
storageQuotas: (map["storageQuotas"] as List? ?? []).map((e) => StorageQuotas.fromMap(e)).toList(),
|
||||
quotaBytesSource: (map["quotaBytesSources"] as Map? ?? {}).map((key, value) => MapEntry(key, value as int)),
|
||||
quotaBytes: map["quotaBytes"] ?? 0,
|
||||
usedBytes: map["usedBytes"] ?? 0,
|
||||
twoFactor: map["2fa_login"] ?? false,
|
||||
isPatreonSupporter: map["patreonData"]?["isPatreonSupporter"] ?? false,
|
||||
userProfile: UserProfile.fromMap(map["profile"]),
|
||||
entitlements: ((map["entitlements"] ?? []) as List).map((e) => Entitlement.fromMap(e)).toList(),
|
||||
supporterMetadata: ((map["supporterMetadata"] ?? []) as List).map((e) => SupporterMetadata.fromMap(e)).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
bool get isPatreonSupporter =>
|
||||
supporterMetadata.whereType<PatreonSupporter>().any((element) => element.isActiveSupporter);
|
||||
}
|
||||
|
||||
class StorageQuota {
|
||||
final String id;
|
||||
final int usedBytes;
|
||||
final int quotaBytes;
|
||||
final int fullQuotaBytes;
|
||||
|
||||
StorageQuota({
|
||||
required this.id,
|
||||
required this.usedBytes,
|
||||
required this.quotaBytes,
|
||||
required this.fullQuotaBytes,
|
||||
});
|
||||
|
||||
factory StorageQuota.fromMap(Map map) {
|
||||
return StorageQuota(
|
||||
id: map["id"] ?? "",
|
||||
usedBytes: map["usedBytes"] ?? 0,
|
||||
quotaBytes: map["quotaBytes"] ?? 0,
|
||||
fullQuotaBytes: map["fullQuotaBytes"] ?? 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class StorageQuotas {
|
||||
final String id;
|
||||
final int bytes;
|
||||
final DateTime addedOn;
|
||||
final DateTime expiresOn;
|
||||
final String giftedByUserId;
|
||||
class SupporterMetadata {
|
||||
SupporterMetadata();
|
||||
|
||||
StorageQuotas({required this.id, required this.bytes, required this.addedOn, required this.expiresOn,
|
||||
required this.giftedByUserId});
|
||||
factory SupporterMetadata.fromMap(Map map) {
|
||||
final type = map["\$type"];
|
||||
return switch (type) {
|
||||
"patreon" => PatreonSupporter.fromMap(map),
|
||||
_ => SupporterMetadata(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
factory StorageQuotas.fromMap(Map map) {
|
||||
return StorageQuotas(
|
||||
id: map["id"] ?? "",
|
||||
bytes: map["bytes"] ?? 0,
|
||||
addedOn: DateTime.tryParse(map["addedOn"]) ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
expiresOn: DateTime.tryParse(map["expiresOn"]) ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
giftedByUserId: map["giftedByUserId"] ?? "",
|
||||
class PatreonSupporter extends SupporterMetadata {
|
||||
final bool isActiveSupporter;
|
||||
final int totalSupportMonths;
|
||||
final int totalSupportCents;
|
||||
final int lastTierCents;
|
||||
final int highestTierCents;
|
||||
final int lowestTierCents;
|
||||
final DateTime firstSupportTimestamp;
|
||||
final DateTime lastSupportTimestamp;
|
||||
|
||||
PatreonSupporter({
|
||||
required this.isActiveSupporter,
|
||||
required this.totalSupportMonths,
|
||||
required this.totalSupportCents,
|
||||
required this.lastTierCents,
|
||||
required this.highestTierCents,
|
||||
required this.lowestTierCents,
|
||||
required this.firstSupportTimestamp,
|
||||
required this.lastSupportTimestamp,
|
||||
});
|
||||
|
||||
factory PatreonSupporter.fromMap(Map map) {
|
||||
return PatreonSupporter(
|
||||
isActiveSupporter: map["isActiveSupporter"],
|
||||
totalSupportMonths: map["totalSupportMonths"],
|
||||
totalSupportCents: map["totalSupportCents"],
|
||||
lastTierCents: map["lastTierCents"],
|
||||
highestTierCents: map["highestTierCents"],
|
||||
lowestTierCents: map["lowestTierCents"],
|
||||
firstSupportTimestamp: DateTime.tryParse(map["firstSupportTimestamp"] ?? "") ?? DateTimeX.epoch,
|
||||
lastSupportTimestamp: DateTime.tryParse(map["lastSupportTimestamp"] ?? "") ?? DateTimeX.epoch,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
49
lib/models/users/entitlement.dart
Normal file
49
lib/models/users/entitlement.dart
Normal file
|
@ -0,0 +1,49 @@
|
|||
import 'package:recon/auxiliary.dart';
|
||||
|
||||
class Entitlement {
|
||||
Entitlement();
|
||||
|
||||
factory Entitlement.fromMap(Map map) {
|
||||
final type = map["\$type"];
|
||||
|
||||
return switch (type) {
|
||||
"storageSpace" => StorageSpace.fromMap(map),
|
||||
_ => Entitlement(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class StorageSpace extends Entitlement {
|
||||
final int bytes;
|
||||
final int maximumShareLevel;
|
||||
final String storageId;
|
||||
final String group;
|
||||
final DateTime startsOn;
|
||||
final DateTime expiresOn;
|
||||
final String name;
|
||||
final String description;
|
||||
|
||||
StorageSpace({
|
||||
required this.bytes,
|
||||
required this.maximumShareLevel,
|
||||
required this.storageId,
|
||||
required this.group,
|
||||
required this.startsOn,
|
||||
required this.expiresOn,
|
||||
required this.name,
|
||||
required this.description,
|
||||
});
|
||||
|
||||
factory StorageSpace.fromMap(Map map) {
|
||||
return StorageSpace(
|
||||
bytes: map["bytes"],
|
||||
maximumShareLevel: map["maximumShareLevel"],
|
||||
storageId: map["storageId"],
|
||||
group: map["group"],
|
||||
startsOn: DateTime.tryParse(map["startsOn"] ?? "") ?? DateTimeX.epoch,
|
||||
expiresOn: DateTime.tryParse(map["expiresOn"] ?? "") ?? DateTimeX.epoch,
|
||||
name: map["name"],
|
||||
description: map["description"],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ class MyProfileDialog extends StatefulWidget {
|
|||
class _MyProfileDialogState extends State<MyProfileDialog> {
|
||||
ClientHolder? _clientHolder;
|
||||
Future<PersonalProfile>? _personalProfileFuture;
|
||||
Future<StorageQuota>? _storageQuotaFuture;
|
||||
|
||||
|
||||
@override
|
||||
|
@ -27,6 +28,7 @@ class _MyProfileDialogState extends State<MyProfileDialog> {
|
|||
_clientHolder = clientHolder;
|
||||
final apiClient = _clientHolder!.apiClient;
|
||||
_personalProfileFuture = UserApi.getPersonalProfile(apiClient);
|
||||
_storageQuotaFuture = UserApi.getStorageQuota(apiClient);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +89,13 @@ class _MyProfileDialogState extends State<MyProfileDialog> {
|
|||
children: [Text("Ban Expiration: ", style: tt.labelLarge,),
|
||||
Text(dateFormat.format(profile.publicBanExpiration!))],
|
||||
),
|
||||
StorageIndicator(usedBytes: profile.usedBytes, maxBytes: profile.quotaBytes,),
|
||||
FutureBuilder(
|
||||
future: _storageQuotaFuture,
|
||||
builder: (context, snapshot) {
|
||||
final storage = snapshot.data;
|
||||
return StorageIndicator(usedBytes: storage?.usedBytes ?? 0, maxBytes: storage?.fullQuotaBytes ?? 1,);
|
||||
}
|
||||
),
|
||||
const SizedBox(height: 12,),
|
||||
],
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue