mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-18 11:13:31 +00:00
Initial Connections Repo implementation with memory version ported into MemoryConnectionsRepo
This commit is contained in:
parent
3d6ab6998f
commit
b1e4dbf4cc
6 changed files with 275 additions and 107 deletions
61
lib/data/interfaces/connections_repo_intf.dart
Normal file
61
lib/data/interfaces/connections_repo_intf.dart
Normal file
|
@ -0,0 +1,61 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:result_monad/result_monad.dart';
|
||||
|
||||
import '../../models/connection.dart';
|
||||
import '../../models/exec_error.dart';
|
||||
import '../../models/group_data.dart';
|
||||
|
||||
class IConnectionsRepo {
|
||||
void addAllGroups(List<GroupData> groups) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool updateConnectionGroupData(String id, List<GroupData> currentGroups) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
void clearGroups() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
UnmodifiableListView<GroupData> getMyGroups() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Result<List<GroupData>, ExecError> getGroupsForUser(String id) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool addConnection(Connection connection) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool addAllConnections(Iterable<Connection> newConnections) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
bool updateConnection(Connection connection) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Result<Connection, ExecError> getById(String id) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Result<Connection, ExecError> getByName(String name) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
Result<Connection, ExecError> getByProfileUrl(String url) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
UnmodifiableListView<Connection> getMyContacts() {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
UnmodifiableListView<Connection> getKnownUsersByName(String name) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
149
lib/data/memory/memory_connections_repo.dart
Normal file
149
lib/data/memory/memory_connections_repo.dart
Normal file
|
@ -0,0 +1,149 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:result_monad/result_monad.dart';
|
||||
|
||||
import '../../models/connection.dart';
|
||||
import '../../models/exec_error.dart';
|
||||
import '../../models/group_data.dart';
|
||||
import '../interfaces/connections_repo_intf.dart';
|
||||
|
||||
class MemoryConnectionsRepo implements IConnectionsRepo {
|
||||
final _connectionsById = <String, Connection>{};
|
||||
final _connectionsByName = <String, Connection>{};
|
||||
final _connectionsByProfileUrl = <String, Connection>{};
|
||||
final _groupsForConnection = <String, List<GroupData>>{};
|
||||
final _myGroups = <GroupData>{};
|
||||
final _myContacts = <Connection>[];
|
||||
|
||||
@override
|
||||
bool addAllConnections(Iterable<Connection> newConnections) {
|
||||
bool result = true;
|
||||
|
||||
for (final connection in newConnections) {
|
||||
result &= addConnection(connection);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
bool addConnection(Connection connection) {
|
||||
if (_connectionsById.containsKey(connection.id)) {
|
||||
return false;
|
||||
}
|
||||
return updateConnection(connection);
|
||||
}
|
||||
|
||||
@override
|
||||
UnmodifiableListView<Connection> getKnownUsersByName(String name) {
|
||||
return UnmodifiableListView(_connectionsByName.values.where((it) {
|
||||
final normalizedHandle = it.handle.toLowerCase();
|
||||
final normalizedName = it.name.toLowerCase();
|
||||
final normalizedQuery = name.toLowerCase();
|
||||
return normalizedHandle.contains(normalizedQuery) ||
|
||||
normalizedName.contains(normalizedQuery);
|
||||
}));
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateConnection(Connection connection) {
|
||||
_connectionsById[connection.id] = connection;
|
||||
_connectionsByName[connection.name] = connection;
|
||||
_connectionsByProfileUrl[connection.profileUrl.toString()] = connection;
|
||||
int index = _myContacts.indexWhere((c) => c.id == connection.id);
|
||||
if (index >= 0) {
|
||||
_myContacts.removeAt(index);
|
||||
}
|
||||
switch (connection.status) {
|
||||
case ConnectionStatus.youFollowThem:
|
||||
case ConnectionStatus.theyFollowYou:
|
||||
case ConnectionStatus.mutual:
|
||||
if (index > 0) {
|
||||
_myContacts.insert(index, connection);
|
||||
} else {
|
||||
_myContacts.add(connection);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
UnmodifiableListView<Connection> getMyContacts() {
|
||||
return UnmodifiableListView(_myContacts);
|
||||
}
|
||||
|
||||
@override
|
||||
Result<List<GroupData>, ExecError> getGroupsForUser(String id) {
|
||||
if (!_groupsForConnection.containsKey(id)) {
|
||||
return Result.error(ExecError(
|
||||
type: ErrorType.notFound,
|
||||
message: '$id not a known user ID',
|
||||
));
|
||||
}
|
||||
|
||||
return Result.ok(UnmodifiableListView(_groupsForConnection[id]!));
|
||||
}
|
||||
|
||||
@override
|
||||
Result<Connection, ExecError> getById(String id) {
|
||||
final result = _connectionsById[id];
|
||||
if (result == null) {
|
||||
return Result.error(ExecError(
|
||||
type: ErrorType.notFound,
|
||||
message: '$id not found',
|
||||
));
|
||||
}
|
||||
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Result<Connection, ExecError> getByName(String name) {
|
||||
final result = _connectionsByName[name];
|
||||
if (result == null) {
|
||||
return Result.error(ExecError(
|
||||
type: ErrorType.notFound,
|
||||
message: '$name not found',
|
||||
));
|
||||
}
|
||||
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
@override
|
||||
UnmodifiableListView<GroupData> getMyGroups() {
|
||||
return UnmodifiableListView(_myGroups);
|
||||
}
|
||||
|
||||
@override
|
||||
Result<Connection, ExecError> getByProfileUrl(String url) {
|
||||
final result = _connectionsByProfileUrl[url];
|
||||
if (result == null) {
|
||||
return Result.error(ExecError(
|
||||
type: ErrorType.notFound,
|
||||
message: '$url not found',
|
||||
));
|
||||
}
|
||||
return Result.ok(result);
|
||||
}
|
||||
|
||||
@override
|
||||
void clearGroups() {
|
||||
_myGroups.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
void addAllGroups(List<GroupData> groups) {
|
||||
_myGroups.addAll(groups);
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateConnectionGroupData(String id, List<GroupData> currentGroups) {
|
||||
_groupsForConnection[id] = currentGroups;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:result_monad/result_monad.dart';
|
||||
|
||||
import 'data/interfaces/connections_repo_intf.dart';
|
||||
import 'data/memory/memory_connections_repo.dart';
|
||||
import 'globals.dart';
|
||||
import 'models/TimelineIdentifiers.dart';
|
||||
import 'routes.dart';
|
||||
|
@ -44,6 +46,7 @@ void main() async {
|
|||
await service.initialize();
|
||||
return service;
|
||||
});
|
||||
getIt.registerSingleton<IConnectionsRepo>(MemoryConnectionsRepo());
|
||||
getIt.registerLazySingleton<ConnectionsManager>(() => ConnectionsManager());
|
||||
getIt.registerLazySingleton<HashtagService>(() => HashtagService());
|
||||
getIt.registerSingleton(galleryService);
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:result_monad/result_monad.dart';
|
||||
|
||||
import '../data/interfaces/connections_repo_intf.dart';
|
||||
import '../globals.dart';
|
||||
import '../models/connection.dart';
|
||||
import '../models/exec_error.dart';
|
||||
|
@ -12,75 +14,26 @@ import 'auth_service.dart';
|
|||
|
||||
class ConnectionsManager extends ChangeNotifier {
|
||||
static final _logger = Logger('$ConnectionsManager');
|
||||
final _connectionsById = <String, Connection>{};
|
||||
final _connectionsByName = <String, Connection>{};
|
||||
final _connectionsByProfileUrl = <Uri, Connection>{};
|
||||
final _groupsForConnection = <String, List<GroupData>>{};
|
||||
final _myGroups = <GroupData>{};
|
||||
final _myContacts = <Connection>[];
|
||||
var _myContactsInitialized = false;
|
||||
late final IConnectionsRepo repo;
|
||||
|
||||
int get length => _connectionsById.length;
|
||||
|
||||
void clearCaches() {
|
||||
_connectionsById.clear();
|
||||
_connectionsByName.clear();
|
||||
_connectionsByProfileUrl.clear();
|
||||
_groupsForConnection.clear();
|
||||
_myGroups.clear();
|
||||
_myContacts.clear();
|
||||
ConnectionsManager() {
|
||||
repo = getIt<IConnectionsRepo>();
|
||||
}
|
||||
|
||||
bool addConnection(Connection connection) {
|
||||
if (_connectionsById.containsKey(connection.id)) {
|
||||
return false;
|
||||
}
|
||||
return updateConnection(connection);
|
||||
return repo.addConnection(connection);
|
||||
}
|
||||
|
||||
List<Connection> getKnownUsersByName(String name) {
|
||||
return _connectionsByName.values.where((it) {
|
||||
final normalizedHandle = it.handle.toLowerCase();
|
||||
final normalizedName = it.name.toLowerCase();
|
||||
final normalizedQuery = name.toLowerCase();
|
||||
return normalizedHandle.contains(normalizedQuery) ||
|
||||
normalizedName.contains(normalizedQuery);
|
||||
}).toList();
|
||||
return repo.getKnownUsersByName(name);
|
||||
}
|
||||
|
||||
bool updateConnection(Connection connection) {
|
||||
_connectionsById[connection.id] = connection;
|
||||
_connectionsByName[connection.name] = connection;
|
||||
_connectionsByProfileUrl[connection.profileUrl] = connection;
|
||||
int index = _myContacts.indexWhere((c) => c.id == connection.id);
|
||||
if (index >= 0) {
|
||||
_myContacts.removeAt(index);
|
||||
}
|
||||
switch (connection.status) {
|
||||
case ConnectionStatus.youFollowThem:
|
||||
case ConnectionStatus.theyFollowYou:
|
||||
case ConnectionStatus.mutual:
|
||||
if (index > 0) {
|
||||
_myContacts.insert(index, connection);
|
||||
} else {
|
||||
_myContacts.add(connection);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
return repo.updateConnection(connection);
|
||||
}
|
||||
|
||||
bool addAllConnections(Iterable<Connection> newConnections) {
|
||||
bool result = true;
|
||||
|
||||
for (final connection in newConnections) {
|
||||
result &= addConnection(connection);
|
||||
}
|
||||
|
||||
return result;
|
||||
return repo.addAllConnections(newConnections);
|
||||
}
|
||||
|
||||
Future<void> acceptFollowRequest(Connection connection) async {
|
||||
|
@ -178,13 +131,8 @@ class ConnectionsManager extends ChangeNotifier {
|
|||
);
|
||||
}
|
||||
|
||||
List<Connection> getMyContacts() {
|
||||
if (!_myContactsInitialized) {
|
||||
updateAllContacts();
|
||||
_myContactsInitialized = true;
|
||||
}
|
||||
|
||||
return _myContacts.toList(growable: false);
|
||||
UnmodifiableListView<Connection> getMyContacts() {
|
||||
return repo.getMyContacts();
|
||||
}
|
||||
|
||||
Future<void> updateAllContacts() async {
|
||||
|
@ -234,29 +182,34 @@ class ConnectionsManager extends ChangeNotifier {
|
|||
});
|
||||
}
|
||||
|
||||
_myContacts.clear();
|
||||
_myContacts.addAll(results.values);
|
||||
addAllConnections(results.values);
|
||||
_myContacts.sort((c1, c2) => c1.name.compareTo(c2.name));
|
||||
_logger.finest('# Contacts:${_myContacts.length}');
|
||||
final myContacts = repo.getMyContacts().toList();
|
||||
myContacts.sort((c1, c2) => c1.name.compareTo(c2.name));
|
||||
_logger.finest('# Contacts:${myContacts.length}');
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<GroupData> getMyGroups() {
|
||||
if (_myGroups.isNotEmpty) {
|
||||
return _myGroups.toList(growable: false);
|
||||
UnmodifiableListView<GroupData> getMyGroups() {
|
||||
final myGroups = repo.getMyGroups();
|
||||
if (myGroups.isEmpty) {
|
||||
_updateMyGroups(true);
|
||||
}
|
||||
_updateMyGroups(true);
|
||||
return [];
|
||||
|
||||
return myGroups;
|
||||
}
|
||||
|
||||
Result<List<GroupData>, ExecError> getGroupsForUser(String id) {
|
||||
if (!_groupsForConnection.containsKey(id)) {
|
||||
_refreshGroupListData(id, true);
|
||||
return Result.ok([]);
|
||||
final result = repo.getGroupsForUser(id);
|
||||
if (result.isSuccess) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return Result.ok(_groupsForConnection[id]!);
|
||||
if (result.isFailure && result.error.type != ErrorType.notFound) {
|
||||
return result;
|
||||
}
|
||||
|
||||
_refreshGroupListData(id, true);
|
||||
return Result.ok(UnmodifiableListView([]));
|
||||
}
|
||||
|
||||
FutureResult<bool, ExecError> addUserToGroup(
|
||||
|
@ -291,37 +244,31 @@ class ConnectionsManager extends ChangeNotifier {
|
|||
return result.execErrorCast();
|
||||
}
|
||||
|
||||
Result<Connection, String> getById(String id) {
|
||||
final result = _connectionsById[id];
|
||||
if (result == null) {
|
||||
return Result.error('$id not found');
|
||||
}
|
||||
if (result.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(result, true);
|
||||
}
|
||||
return Result.ok(result);
|
||||
Result<Connection, ExecError> getById(String id) {
|
||||
return repo.getById(id).andThenSuccess((c) {
|
||||
if (c.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(c, true);
|
||||
}
|
||||
return c;
|
||||
}).execErrorCast();
|
||||
}
|
||||
|
||||
Result<Connection, String> getByName(String name) {
|
||||
final result = _connectionsByName[name];
|
||||
if (result == null) {
|
||||
Result.error('$name not found');
|
||||
}
|
||||
if (result!.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(result, true);
|
||||
}
|
||||
return Result.ok(result);
|
||||
Result<Connection, ExecError> getByName(String name) {
|
||||
return repo.getByName(name).andThenSuccess((c) {
|
||||
if (c.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(c, true);
|
||||
}
|
||||
return c;
|
||||
}).execErrorCast();
|
||||
}
|
||||
|
||||
Result<Connection, String> getByProfileUrl(Uri url) {
|
||||
final result = _connectionsByProfileUrl[url];
|
||||
if (result == null) {
|
||||
Result.error('$url not found');
|
||||
}
|
||||
if (result!.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(result, true);
|
||||
}
|
||||
return Result.ok(result);
|
||||
Result<Connection, ExecError> getByProfileUrl(Uri url) {
|
||||
return repo.getByProfileUrl(url.toString()).andThenSuccess((c) {
|
||||
if (c.status == ConnectionStatus.unknown) {
|
||||
_refreshConnection(c, true);
|
||||
}
|
||||
return c;
|
||||
}).execErrorCast();
|
||||
}
|
||||
|
||||
Future<void> fullRefresh(Connection connection) async {
|
||||
|
@ -337,8 +284,8 @@ class ConnectionsManager extends ChangeNotifier {
|
|||
.currentClient
|
||||
.andThenAsync((client) => client.getMemberGroupsForConnection(id))
|
||||
.match(
|
||||
onSuccess: (lists) {
|
||||
_groupsForConnection[id] = lists;
|
||||
onSuccess: (groups) {
|
||||
repo.updateConnectionGroupData(id, groups);
|
||||
if (withNotification) {
|
||||
notifyListeners();
|
||||
}
|
||||
|
@ -376,8 +323,8 @@ class ConnectionsManager extends ChangeNotifier {
|
|||
.match(
|
||||
onSuccess: (groups) {
|
||||
_logger.finest('Got updated groups:${groups.map((e) => e.name)}');
|
||||
_myGroups.clear();
|
||||
_myGroups.addAll(groups);
|
||||
repo.clearGroups();
|
||||
repo.addAllGroups(groups);
|
||||
if (withNotification) {
|
||||
notifyListeners();
|
||||
}
|
||||
|
|
|
@ -644,6 +644,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
sqlite3:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -34,6 +34,7 @@ dependencies:
|
|||
result_monad: ^2.0.2
|
||||
scrollable_positioned_list: ^0.3.5
|
||||
shared_preferences: ^2.0.15
|
||||
sqlite3: ^1.9.1
|
||||
time_machine: ^0.9.17
|
||||
url_launcher: ^6.1.6
|
||||
uuid: ^3.0.6
|
||||
|
|
Loading…
Reference in a new issue