103 lines
2.8 KiB
Dart
103 lines
2.8 KiB
Dart
|
|
import 'dart:typed_data';
|
||
|
|
|
||
|
|
import 'package:halkyon_learn_flutter/src/feature/profile/data/profile_gateway.dart';
|
||
|
|
import 'package:halkyon_learn_flutter/src/feature/profile/model/public_profile.dart';
|
||
|
|
|
||
|
|
/// A [ProfileGateway] in memory, on an instance whose account domain is
|
||
|
|
/// `halkyon.eu`: one profile, refusing the handles others have (whatever
|
||
|
|
/// their case) and, once its handle is fixed, any other handle.
|
||
|
|
class FakeProfileGateway({
|
||
|
|
/// The person's profile; null while they have none.
|
||
|
|
var PublicProfile? profile,
|
||
|
|
|
||
|
|
/// Handles others have.
|
||
|
|
final Set<String> taken = const {},
|
||
|
|
}) implements ProfileGateway {
|
||
|
|
/// When set, every request fails with it.
|
||
|
|
Exception? fail;
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<PublicProfile?> mine() async {
|
||
|
|
if (fail case final error?) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
return profile;
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<PublicProfile> save({
|
||
|
|
required String handle,
|
||
|
|
required String displayName,
|
||
|
|
required String bio,
|
||
|
|
required List<String> links,
|
||
|
|
}) async {
|
||
|
|
if (fail case final error?) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
final current = profile;
|
||
|
|
if (!RegExp(r'^[A-Za-z0-9_]{1,30}$').hasMatch(handle)) {
|
||
|
|
throw ProfileRefused(ProfileProblem.handleInvalid);
|
||
|
|
}
|
||
|
|
if (taken.any((other) => other.toLowerCase() == handle.toLowerCase())) {
|
||
|
|
throw ProfileRefused(ProfileProblem.handleTaken);
|
||
|
|
}
|
||
|
|
if (current != null &&
|
||
|
|
current.handleFixed &&
|
||
|
|
current.handle.toLowerCase() != handle.toLowerCase()) {
|
||
|
|
throw ProfileRefused(ProfileProblem.published);
|
||
|
|
}
|
||
|
|
return profile = PublicProfile(
|
||
|
|
handle: handle,
|
||
|
|
address: '$handle@halkyon.eu',
|
||
|
|
displayName: displayName,
|
||
|
|
bio: bio,
|
||
|
|
links: links,
|
||
|
|
handleFixed: current?.handleFixed ?? false,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// The avatars set, in order.
|
||
|
|
final avatars = <Uint8List>[];
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<PublicProfile> setAvatar(Uint8List png) async {
|
||
|
|
if (fail case final error?) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
avatars.add(png);
|
||
|
|
final current = profile!;
|
||
|
|
return profile = PublicProfile(
|
||
|
|
handle: current.handle,
|
||
|
|
address: current.address,
|
||
|
|
displayName: current.displayName,
|
||
|
|
bio: current.bio,
|
||
|
|
links: current.links,
|
||
|
|
avatarUrl: 'https://learn.halkyon.eu/avatars/${avatars.length}.png',
|
||
|
|
handleFixed: current.handleFixed,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<PublicProfile> removeAvatar() async {
|
||
|
|
final current = profile!;
|
||
|
|
return profile = PublicProfile(
|
||
|
|
handle: current.handle,
|
||
|
|
address: current.address,
|
||
|
|
displayName: current.displayName,
|
||
|
|
bio: current.bio,
|
||
|
|
links: current.links,
|
||
|
|
handleFixed: current.handleFixed,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
@override
|
||
|
|
Future<void> remove() async {
|
||
|
|
if (fail case final error?) {
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
if (profile?.handleFixed ?? false) {
|
||
|
|
throw ProfileRefused(ProfileProblem.published);
|
||
|
|
}
|
||
|
|
profile = null;
|
||
|
|
}
|
||
|
|
}
|