relatica/lib/services/blocks_manager.dart

164 wiersze
4.6 KiB
Dart

import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:result_monad/result_monad.dart';
import '../friendica_client/friendica_client.dart';
import '../friendica_client/paged_response.dart';
import '../friendica_client/paging_data.dart';
import '../globals.dart';
import '../models/auth/profile.dart';
import '../models/connection.dart';
import '../utils/active_profile_selector.dart';
import 'connections_manager.dart';
class BlocksManager extends ChangeNotifier {
static final _logger = Logger('$BlocksManager');
final Profile profile;
final _blocks = <Connection>[];
final _pages = <PagedResponse>[];
var mayHaveMore = true;
var initialized = false;
BlocksManager(this.profile);
void clear() {
_blocks.clear();
_pages.clear();
mayHaveMore = true;
}
List<Connection> getBlocks() {
if (!initialized) {
updateBlocks(nextOnly: false);
}
return UnmodifiableListView(_blocks);
}
Future<void> blockConnection(Connection connection) async {
_logger
.finest('Attempting to block ${connection.name}: ${connection.status}');
await RelationshipsClient(profile)
.blockConnection(connection)
.withResult((blockedUser) {
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult(
(cm) => cm.upsertConnection(blockedUser),
);
}).match(
onSuccess: (blockedUser) {
_logger.fine(
'Successfully blocked ${blockedUser.name}: ${blockedUser.status}');
final existingIndex = _blocks.indexOf(connection);
if (existingIndex < 0) {
_blocks.add(blockedUser);
_sortBlocks();
} else {
_blocks.removeAt(existingIndex);
_blocks.insert(existingIndex, blockedUser);
}
notifyListeners();
},
onError: (error) {
_logger.severe('Error blocking ${connection.name}: $error');
},
);
}
Future<void> unblockConnection(Connection connection) async {
_logger
.fine('Attempting to unblock ${connection.name}: ${connection.status}');
await RelationshipsClient(profile)
.unblockConnection(connection)
.withResult((blockedUser) {
getIt<ActiveProfileSelector<ConnectionsManager>>()
.getForProfile(profile)
.withResult(
(cm) => cm.upsertConnection(blockedUser),
);
}).match(
onSuccess: (unblockedUser) {
_logger.fine(
'Successfully unblocked ${unblockedUser.name}: ${unblockedUser.status}');
final existingIndex = _blocks.indexOf(connection);
if (existingIndex >= 0) {
_blocks.removeAt(existingIndex);
_sortBlocks();
}
notifyListeners();
},
onError: (error) {
_logger.severe('Error unblocking ${connection.name}: $error');
},
);
}
Future<void> updateBlock(Connection connection) async {
final id = int.parse(connection.id);
final page = PagingData(minId: id - 1, maxId: id + 1);
await RelationshipsClient(profile).getBlocks(page).withResult((blocks) {
final conBlock = blocks.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));
}
notifyListeners();
});
}
Future<void> updateBlocks({required bool nextOnly}) async {
if (nextOnly) {
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();
notifyListeners();
}
void _sortBlocks() {
_blocks.sort(
(b1, b2) => b1.name.toLowerCase().compareTo(
b2.name.toLowerCase(),
),
);
}
}