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 = []; final _pages = []; var mayHaveMore = true; var initialized = false; BlocksManager(this.profile); void clear() { _blocks.clear(); _pages.clear(); mayHaveMore = true; } List getBlocks() { if (!initialized) { updateBlocks(nextOnly: false); } return UnmodifiableListView(_blocks); } Future blockConnection(Connection connection) async { _logger .finest('Attempting to block ${connection.name}: ${connection.status}'); await RelationshipsClient(profile) .blockConnection(connection) .withResult((blockedUser) { getIt>() .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 unblockConnection(Connection connection) async { _logger .fine('Attempting to unblock ${connection.name}: ${connection.status}'); await RelationshipsClient(profile) .unblockConnection(connection) .withResult((blockedUser) { getIt>() .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 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>() .getForProfile(profile) .withResult((cm) => cm.upsertConnection(conBlock.first)); } notifyListeners(); }); } Future 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( onSuccess: (result) => result.next, onError: (error) => null, ); if (nextOnly) { break; } } getIt>() .getForProfile(profile) .withResult((cm) => cm.upsertAllConnections(_blocks)); _sortBlocks(); notifyListeners(); } void _sortBlocks() { _blocks.sort( (b1, b2) => b1.name.toLowerCase().compareTo( b2.name.toLowerCase(), ), ); } }