relatica/lib/riverpod_controllers/blocks_services.dart

169 wiersze
4.9 KiB
Dart
Czysty Zwykły widok Historia

import 'package:logging/logging.dart';
import 'package:relatica/models/auth/profile.dart';
import 'package:result_monad/result_monad.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../friendica_client/friendica_client.dart';
import '../friendica_client/paged_response.dart';
import '../friendica_client/paging_data.dart';
import '../globals.dart';
import '../models/connection.dart';
import '../services/connections_manager.dart';
import '../utils/active_profile_selector.dart';
part 'blocks_services.g.dart';
final _logger = Logger('BlocksManager');
@Riverpod(keepAlive: true)
class BlocksManager extends _$BlocksManager {
late Profile userProfile;
final _pages = <PagedResponse>[];
@override
Future<List<Connection>> build(Profile profile) async {
userProfile = profile;
final result = await updateBlocks(withUpdate: false);
return result;
}
Future<void> blockConnection(Connection connection) async {
_logger
2024-11-26 22:12:43 +00:00
.fine('Attempting to block ${connection.name}: ${connection.status}');
final blocks = List<Connection>.from(state.value ?? []);
await RelationshipsClient(profile)
.blockConnection(connection)
.withResult((blockedUser) {
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult(
(cm) => cm.upsertConnection(blockedUser),
);
}).match(
onSuccess: (blockedUser) {
2023-11-27 19:16:11 +00:00
_logger.fine(
'Successfully blocked ${blockedUser.name}: ${blockedUser.status}');
final existingIndex = blocks.indexOf(connection);
if (existingIndex < 0) {
blocks.add(blockedUser);
_sortBlocks(blocks);
} else {
blocks.removeAt(existingIndex);
blocks.insert(existingIndex, blockedUser);
}
},
onError: (error) {
_logger.severe('Error blocking ${connection.name}: $error');
},
);
state = AsyncData(blocks);
}
Future<void> unblockConnection(Connection connection) async {
2023-11-27 19:16:11 +00:00
_logger
.fine('Attempting to unblock ${connection.name}: ${connection.status}');
final blocks = List<Connection>.from(state.value ?? []);
await RelationshipsClient(profile)
.unblockConnection(connection)
.withResult((blockedUser) {
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult(
(cm) => cm.upsertConnection(blockedUser),
);
}).match(
onSuccess: (unblockedUser) {
2023-11-27 19:16:11 +00:00
_logger.fine(
'Successfully unblocked ${unblockedUser.name}: ${unblockedUser.status}');
final existingIndex = blocks.indexOf(connection);
if (existingIndex >= 0) {
blocks.removeAt(existingIndex);
_sortBlocks(blocks);
}
},
onError: (error) {
_logger.severe('Error unblocking ${connection.name}: $error');
},
);
state = AsyncData(blocks);
}
Future<void> updateBlock(Connection connection) async {
final blocks = List<Connection>.from(state.value ?? []);
final id = int.parse(connection.id);
final page = PagingData(minId: id - 1, maxId: id + 1);
await RelationshipsClient(profile)
.getBlocks(page)
.withResult((returnedBlocks) {
final conBlock =
returnedBlocks.data.where((b) => b.id == connection.id).toList();
if (conBlock.isEmpty) {
blocks.remove(connection);
} else {
blocks.add(conBlock.first);
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult((cm) => cm.upsertConnection(conBlock.first));
}
});
state = AsyncData(blocks);
}
Future<List<Connection>> updateBlocks({
bool nextOnly = false,
bool withUpdate = true,
}) async {
final blocks = state.value ?? [];
if (!nextOnly) {
blocks.clear();
_pages.clear();
}
final client = RelationshipsClient(profile);
final bootstrapping = _pages.isEmpty;
var page = bootstrapping ? PagingData() : _pages.last.next;
while (page != null) {
page = await client
.getBlocks(page)
.withResult((result) {
blocks.addAll(result.data);
_pages.add(result);
})
.withError(
(error) => _logger.severe('Error getting blocks data: $error'),
)
.fold<PagingData?>(
onSuccess: (result) => result.next,
onError: (error) => null,
);
if (nextOnly) {
break;
}
}
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult((cm) => cm.upsertAllConnections(blocks));
_sortBlocks(blocks);
if (withUpdate) {
state = AsyncData(blocks);
}
return blocks;
}
}
void _sortBlocks(List<Connection> blocks) {
blocks.sort(
(b1, b2) => b1.name.toLowerCase().compareTo(
b2.name.toLowerCase(),
),
);
}