Merge pull request #1583 from GetStream/feat/offline-connect
This commit is contained in:
@@ -14,6 +14,9 @@
|
|||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support for `ChatPersistenceClient.isConnected` for checking if the client is connected to the database.
|
- Added support for `ChatPersistenceClient.isConnected` for checking if the client is connected to the database.
|
||||||
|
- Added support for `ChatPersistenceClient.userId` for getting the current connected user id.
|
||||||
|
- Added two new methods `ChatPersistenceClient.disconnect` and `ChatPersistenceClient.connect` for disconnecting and
|
||||||
|
connecting to the database.
|
||||||
|
|
||||||
## 6.1.0
|
## 6.1.0
|
||||||
|
|
||||||
|
|||||||
@@ -1379,13 +1379,14 @@ class Channel {
|
|||||||
this.state?.updateChannelState(updatedState);
|
this.state?.updateChannelState(updatedState);
|
||||||
return updatedState;
|
return updatedState;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!_client.persistenceEnabled) {
|
if (_client.persistenceEnabled) {
|
||||||
rethrow;
|
return _client.chatPersistenceClient!.getChannelStateByCid(
|
||||||
|
cid!,
|
||||||
|
messagePagination: messagesPagination,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return _client.chatPersistenceClient!.getChannelStateByCid(
|
|
||||||
cid!,
|
rethrow;
|
||||||
messagePagination: messagesPagination,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1841,9 +1842,7 @@ class ChannelClientState {
|
|||||||
|
|
||||||
/// [isUpToDate] flag count as a stream.
|
/// [isUpToDate] flag count as a stream.
|
||||||
Stream<bool> get isUpToDateStream => _isUpToDateController.stream;
|
Stream<bool> get isUpToDateStream => _isUpToDateController.stream;
|
||||||
|
final _isUpToDateController = BehaviorSubject.seeded(true);
|
||||||
final BehaviorSubject<bool> _isUpToDateController =
|
|
||||||
BehaviorSubject.seeded(true);
|
|
||||||
|
|
||||||
/// The retry queue associated to this channel.
|
/// The retry queue associated to this channel.
|
||||||
late final RetryQueue _retryQueue;
|
late final RetryQueue _retryQueue;
|
||||||
|
|||||||
@@ -125,10 +125,6 @@ class StreamChatClient {
|
|||||||
final _tokenManager = TokenManager();
|
final _tokenManager = TokenManager();
|
||||||
final _connectionIdManager = ConnectionIdManager();
|
final _connectionIdManager = ConnectionIdManager();
|
||||||
|
|
||||||
set chatPersistenceClient(ChatPersistenceClient? value) {
|
|
||||||
_originalChatPersistenceClient = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Default user agent for all requests
|
/// Default user agent for all requests
|
||||||
static String defaultUserAgent =
|
static String defaultUserAgent =
|
||||||
'stream-chat-dart-client-${CurrentPlatform.name}';
|
'stream-chat-dart-client-${CurrentPlatform.name}';
|
||||||
@@ -139,15 +135,15 @@ class StreamChatClient {
|
|||||||
/// The current package version
|
/// The current package version
|
||||||
static const packageVersion = PACKAGE_VERSION;
|
static const packageVersion = PACKAGE_VERSION;
|
||||||
|
|
||||||
ChatPersistenceClient? _originalChatPersistenceClient;
|
|
||||||
|
|
||||||
/// Chat persistence client
|
/// Chat persistence client
|
||||||
ChatPersistenceClient? get chatPersistenceClient => _chatPersistenceClient;
|
ChatPersistenceClient? chatPersistenceClient;
|
||||||
|
|
||||||
ChatPersistenceClient? _chatPersistenceClient;
|
/// Returns `True` if the [chatPersistenceClient] is available and connected.
|
||||||
|
/// Otherwise, returns `False`.
|
||||||
/// Whether the chat persistence is available or not
|
bool get persistenceEnabled {
|
||||||
bool get persistenceEnabled => _chatPersistenceClient != null;
|
final client = chatPersistenceClient;
|
||||||
|
return client != null && client.isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
late final RetryPolicy _retryPolicy;
|
late final RetryPolicy _retryPolicy;
|
||||||
|
|
||||||
@@ -324,20 +320,27 @@ class StreamChatClient {
|
|||||||
final ownUser = OwnUser.fromUser(user);
|
final ownUser = OwnUser.fromUser(user);
|
||||||
state.currentUser = ownUser;
|
state.currentUser = ownUser;
|
||||||
|
|
||||||
if (!connectWebSocket) return ownUser;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (_originalChatPersistenceClient != null) {
|
// Connect to persistence client if its set.
|
||||||
_chatPersistenceClient = _originalChatPersistenceClient;
|
if (chatPersistenceClient != null) {
|
||||||
await _chatPersistenceClient!.connect(ownUser.id);
|
await openPersistenceConnection(ownUser);
|
||||||
}
|
}
|
||||||
final connectedUser = await openConnection(
|
|
||||||
includeUserDetailsInConnectCall: true,
|
// Connect to websocket if [connectWebSocket] is true.
|
||||||
);
|
//
|
||||||
return state.currentUser = connectedUser;
|
// This is useful when you want to connect to websocket
|
||||||
|
// at a later stage or use the client in connection-less mode.
|
||||||
|
if (connectWebSocket) {
|
||||||
|
final connectedUser = await openConnection(
|
||||||
|
includeUserDetailsInConnectCall: true,
|
||||||
|
);
|
||||||
|
state.currentUser = connectedUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.currentUser!;
|
||||||
} catch (e, stk) {
|
} catch (e, stk) {
|
||||||
if (e is StreamWebSocketError && e.isRetriable) {
|
if (e is StreamWebSocketError && e.isRetriable) {
|
||||||
final event = await _chatPersistenceClient?.getConnectionInfo();
|
final event = await chatPersistenceClient?.getConnectionInfo();
|
||||||
if (event != null) return ownUser.merge(event.me);
|
if (event != null) return ownUser.merge(event.me);
|
||||||
}
|
}
|
||||||
logger.severe('error connecting user : ${ownUser.id}', e, stk);
|
logger.severe('error connecting user : ${ownUser.id}', e, stk);
|
||||||
@@ -345,6 +348,40 @@ class StreamChatClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Connects the [chatPersistenceClient] to the given [user].
|
||||||
|
Future<void> openPersistenceConnection(User user) async {
|
||||||
|
final client = chatPersistenceClient;
|
||||||
|
if (client == null) {
|
||||||
|
throw const StreamChatError('Chat persistence client is not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.isConnected) {
|
||||||
|
// If the persistence client is already connected to the userId,
|
||||||
|
// we don't need to connect again.
|
||||||
|
if (client.userId == user.id) return;
|
||||||
|
|
||||||
|
throw const StreamChatError('''
|
||||||
|
Chat persistence client is already connected to a different user,
|
||||||
|
please close the connection before connecting a new one.''');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect the persistence client to the userId.
|
||||||
|
return client.connect(user.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disconnects the [chatPersistenceClient] from the current user.
|
||||||
|
Future<void> closePersistenceConnection({bool flush = false}) async {
|
||||||
|
final client = chatPersistenceClient;
|
||||||
|
// If the persistence client is never connected, we don't need to close it.
|
||||||
|
if (client == null || !client.isConnected) {
|
||||||
|
logger.info('Chat persistence client is not connected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect the persistence client.
|
||||||
|
return client.disconnect(flush: flush);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new WebSocket connection with the current user.
|
/// Creates a new WebSocket connection with the current user.
|
||||||
/// If [includeUserDetailsInConnectCall] is true it will include the current
|
/// If [includeUserDetailsInConnectCall] is true it will include the current
|
||||||
/// user details in the connect call.
|
/// user details in the connect call.
|
||||||
@@ -422,7 +459,7 @@ class StreamChatClient {
|
|||||||
final connectionId = event.connectionId;
|
final connectionId = event.connectionId;
|
||||||
if (connectionId != null) {
|
if (connectionId != null) {
|
||||||
_connectionIdManager.setConnectionId(connectionId);
|
_connectionIdManager.setConnectionId(connectionId);
|
||||||
_chatPersistenceClient?.updateConnectionInfo(event);
|
chatPersistenceClient?.updateConnectionInfo(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,9 +497,9 @@ class StreamChatClient {
|
|||||||
// channels are empty, assuming it's a fresh start
|
// channels are empty, assuming it's a fresh start
|
||||||
// and making sure `lastSyncAt` is initialized
|
// and making sure `lastSyncAt` is initialized
|
||||||
if (persistenceEnabled) {
|
if (persistenceEnabled) {
|
||||||
final lastSyncAt = await _chatPersistenceClient?.getLastSyncAt();
|
final lastSyncAt = await chatPersistenceClient?.getLastSyncAt();
|
||||||
if (lastSyncAt == null) {
|
if (lastSyncAt == null) {
|
||||||
await _chatPersistenceClient?.updateLastSyncAt(DateTime.now());
|
await chatPersistenceClient?.updateLastSyncAt(DateTime.now());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,13 +530,12 @@ class StreamChatClient {
|
|||||||
/// Will automatically fetch [cids] and [lastSyncedAt] if [persistenceEnabled]
|
/// Will automatically fetch [cids] and [lastSyncedAt] if [persistenceEnabled]
|
||||||
Future<void> sync({List<String>? cids, DateTime? lastSyncAt}) {
|
Future<void> sync({List<String>? cids, DateTime? lastSyncAt}) {
|
||||||
return synchronized(() async {
|
return synchronized(() async {
|
||||||
final channels = cids ?? await _chatPersistenceClient?.getChannelCids();
|
final channels = cids ?? await chatPersistenceClient?.getChannelCids();
|
||||||
if (channels == null || channels.isEmpty) {
|
if (channels == null || channels.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final syncAt =
|
final syncAt = lastSyncAt ?? await chatPersistenceClient?.getLastSyncAt();
|
||||||
lastSyncAt ?? await _chatPersistenceClient?.getLastSyncAt();
|
|
||||||
if (syncAt == null) {
|
if (syncAt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -520,7 +556,7 @@ class StreamChatClient {
|
|||||||
|
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
_lastSyncedAt = now;
|
_lastSyncedAt = now;
|
||||||
_chatPersistenceClient?.updateLastSyncAt(now);
|
chatPersistenceClient?.updateLastSyncAt(now);
|
||||||
} catch (e, stk) {
|
} catch (e, stk) {
|
||||||
logger.severe('Error during sync', e, stk);
|
logger.severe('Error during sync', e, stk);
|
||||||
}
|
}
|
||||||
@@ -679,7 +715,7 @@ class StreamChatClient {
|
|||||||
|
|
||||||
final updateData = _mapChannelStateToChannel(channels);
|
final updateData = _mapChannelStateToChannel(channels);
|
||||||
|
|
||||||
await _chatPersistenceClient?.updateChannelQueries(
|
await chatPersistenceClient?.updateChannelQueries(
|
||||||
filter,
|
filter,
|
||||||
channels.map((c) => c.channel!.cid).toList(),
|
channels.map((c) => c.channel!.cid).toList(),
|
||||||
clearQueryCache: paginationParams.offset == 0,
|
clearQueryCache: paginationParams.offset == 0,
|
||||||
@@ -698,7 +734,7 @@ class StreamChatClient {
|
|||||||
List<SortOption<ChannelState>>? channelStateSort,
|
List<SortOption<ChannelState>>? channelStateSort,
|
||||||
PaginationParams paginationParams = const PaginationParams(),
|
PaginationParams paginationParams = const PaginationParams(),
|
||||||
}) async {
|
}) async {
|
||||||
final offlineChannels = (await _chatPersistenceClient?.getChannelStates(
|
final offlineChannels = (await chatPersistenceClient?.getChannelStates(
|
||||||
filter: filter,
|
filter: filter,
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
sort: sort,
|
sort: sort,
|
||||||
@@ -1362,7 +1398,7 @@ class StreamChatClient {
|
|||||||
final response =
|
final response =
|
||||||
await _chatApi.message.deleteMessage(messageId, hard: hard);
|
await _chatApi.message.deleteMessage(messageId, hard: hard);
|
||||||
if (hard == true) {
|
if (hard == true) {
|
||||||
await _chatPersistenceClient?.deleteMessageById(messageId);
|
await chatPersistenceClient?.deleteMessageById(messageId);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -1468,34 +1504,33 @@ class StreamChatClient {
|
|||||||
Future<void> disconnectUser({bool flushChatPersistence = false}) async {
|
Future<void> disconnectUser({bool flushChatPersistence = false}) async {
|
||||||
logger.info('Disconnecting user : ${state.currentUser?.id}');
|
logger.info('Disconnecting user : ${state.currentUser?.id}');
|
||||||
|
|
||||||
// resetting state
|
// resetting state.
|
||||||
state.dispose();
|
state.dispose();
|
||||||
state = ClientState(this);
|
state = ClientState(this);
|
||||||
_lastSyncedAt = null;
|
_lastSyncedAt = null;
|
||||||
|
|
||||||
// resetting credentials
|
// resetting credentials.
|
||||||
_tokenManager.reset();
|
_tokenManager.reset();
|
||||||
_connectionIdManager.reset();
|
_connectionIdManager.reset();
|
||||||
|
|
||||||
// disconnecting persistence client
|
// closing persistence connection.
|
||||||
await _chatPersistenceClient?.disconnect(flush: flushChatPersistence);
|
await closePersistenceConnection(flush: flushChatPersistence);
|
||||||
_chatPersistenceClient = null;
|
|
||||||
|
|
||||||
// closing web-socket connection
|
// closing web-socket connection
|
||||||
closeConnection();
|
return closeConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call this function to dispose the client
|
/// Call this function to dispose the client
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
logger.info('Disposing new StreamChatClient');
|
logger.info('Disposing new StreamChatClient');
|
||||||
|
|
||||||
// disposing state
|
// disposing state.
|
||||||
state.dispose();
|
state.dispose();
|
||||||
|
|
||||||
// disconnecting persistence client
|
// closing persistence connection.
|
||||||
await _chatPersistenceClient?.disconnect();
|
await closePersistenceConnection();
|
||||||
|
|
||||||
// closing web-socket connection
|
// closing web-socket connection.
|
||||||
closeConnection();
|
closeConnection();
|
||||||
|
|
||||||
await _eventController.close();
|
await _eventController.close();
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ abstract class ChatPersistenceClient {
|
|||||||
/// Whether the connection is established.
|
/// Whether the connection is established.
|
||||||
bool get isConnected;
|
bool get isConnected;
|
||||||
|
|
||||||
|
/// The current user id to which the client is connected.
|
||||||
|
///
|
||||||
|
/// Returns `null` if the client is not connected.
|
||||||
|
String? get userId;
|
||||||
|
|
||||||
/// Creates a new connection to the client
|
/// Creates a new connection to the client
|
||||||
Future<void> connect(String userId);
|
Future<void> connect(String userId);
|
||||||
|
|
||||||
|
|||||||
@@ -2544,4 +2544,124 @@ void main() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('PersistenceConnectionTests', () {
|
||||||
|
const apiKey = 'test-api-key';
|
||||||
|
late final api = FakeChatApi();
|
||||||
|
late final ws = FakeWebSocket();
|
||||||
|
|
||||||
|
final user = User(id: 'test-user-id');
|
||||||
|
final token = Token.development(user.id).rawValue;
|
||||||
|
|
||||||
|
late StreamChatClient client;
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
client = StreamChatClient(apiKey, chatApi: api, ws: ws);
|
||||||
|
expect(client.persistenceEnabled, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() {
|
||||||
|
client.chatPersistenceClient = null;
|
||||||
|
expect(client.persistenceEnabled, isFalse);
|
||||||
|
client.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('openPersistenceConnection connects the client to the user', () async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user);
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''multiple call to openPersistenceConnection does not throws an error if already connected to the same user''',
|
||||||
|
() async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user);
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
|
||||||
|
await expectLater(client.openPersistenceConnection(user), completes);
|
||||||
|
await expectLater(client.openPersistenceConnection(user), completes);
|
||||||
|
await expectLater(client.openPersistenceConnection(user), completes);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''openPersistenceConnection throws an error if client is already connected to a different user''',
|
||||||
|
() async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user);
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
client.openPersistenceConnection(user.copyWith(id: 'new-id')),
|
||||||
|
throwsA(const TypeMatcher<StreamChatError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''openPersistenceConnection throws an error if chatPersistenceClient is not set''',
|
||||||
|
() async {
|
||||||
|
await expectLater(
|
||||||
|
client.openPersistenceConnection(user),
|
||||||
|
throwsA(const TypeMatcher<StreamChatError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('closePersistenceConnection disconnects the client', () async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user);
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
|
||||||
|
await client.closePersistenceConnection();
|
||||||
|
expect(client.persistenceEnabled, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''closePersistenceConnection compeletes normally if chatPersistenceClient is not connected''',
|
||||||
|
() async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
expect(client.chatPersistenceClient!.isConnected, isFalse);
|
||||||
|
|
||||||
|
await expectLater(client.closePersistenceConnection(), completes);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''closePersistenceConnection completes normally if chatPersistenceClient is not set''',
|
||||||
|
() async {
|
||||||
|
expect(client.persistenceEnabled, isFalse);
|
||||||
|
await expectLater(client.closePersistenceConnection(), completes);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''connectUser completes normally if the persistence connection is already connected to the same user''',
|
||||||
|
() async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user);
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
client.connectUser(user, token, connectWebSocket: false),
|
||||||
|
completes,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''connectUser should throw if the persistence connection if already connected to a different user''',
|
||||||
|
() async {
|
||||||
|
client.chatPersistenceClient = MockPersistenceClient();
|
||||||
|
await client.openPersistenceConnection(user.copyWith(id: 'new-id'));
|
||||||
|
expect(client.persistenceEnabled, isTrue);
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
client.connectUser(user, token, connectWebSocket: false),
|
||||||
|
throwsA(const TypeMatcher<StreamChatError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ class TestPersistenceClient extends ChatPersistenceClient {
|
|||||||
@override
|
@override
|
||||||
bool get isConnected => throw UnimplementedError();
|
bool get isConnected => throw UnimplementedError();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get userId => throw UnimplementedError();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> connect(String userId) => throw UnimplementedError();
|
Future<void> connect(String userId) => throw UnimplementedError();
|
||||||
|
|
||||||
|
|||||||
@@ -64,11 +64,26 @@ class MockAttachmentFileUploader extends Mock
|
|||||||
implements AttachmentFileUploader {}
|
implements AttachmentFileUploader {}
|
||||||
|
|
||||||
class MockPersistenceClient extends Mock implements ChatPersistenceClient {
|
class MockPersistenceClient extends Mock implements ChatPersistenceClient {
|
||||||
@override
|
String? _userId;
|
||||||
Future<void> connect(String userId) => Future.value();
|
bool _isConnected = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> disconnect({bool flush = false}) => Future.value();
|
bool get isConnected => _isConnected;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get userId => _userId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> connect(String userId) async {
|
||||||
|
_userId = userId;
|
||||||
|
_isConnected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> disconnect({bool flush = false}) async {
|
||||||
|
_userId = null;
|
||||||
|
_isConnected = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockStreamChatClient extends Mock implements StreamChatClient {
|
class MockStreamChatClient extends Mock implements StreamChatClient {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
- [[#1422]](https://github.com/GetStream/stream-chat-flutter/issues/1422) Removed default values
|
- [[#1422]](https://github.com/GetStream/stream-chat-flutter/issues/1422) Removed default values
|
||||||
from `UserEntity` `createdAt` and `updatedAt` fields.
|
from `UserEntity` `createdAt` and `updatedAt` fields.
|
||||||
- Updated `stream_chat` dependency to [`6.2.0`](https://pub.dev/packages/stream_chat/changelog).
|
- Updated `stream_chat` dependency to [`6.2.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
- Added support for `StreamChatPersistenceClient.openPersistenceConnection`
|
||||||
|
and `StreamChatPersistenceClient.closePersistenceConnection` for opening and closing the database connection.
|
||||||
|
|
||||||
## 6.1.0
|
## 6.1.0
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ class StreamChatPersistenceClient extends ChatPersistenceClient {
|
|||||||
@override
|
@override
|
||||||
bool get isConnected => db != null;
|
bool get isConnected => db != null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get userId => db?.userId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> connect(
|
Future<void> connect(
|
||||||
String userId, {
|
String userId, {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void main() {
|
|||||||
await client.connect(userId, databaseProvider: testDatabaseProvider);
|
await client.connect(userId, databaseProvider: testDatabaseProvider);
|
||||||
expect(client.isConnected, true);
|
expect(client.isConnected, true);
|
||||||
expect(client.db, isA<DriftChatDatabase>());
|
expect(client.db, isA<DriftChatDatabase>());
|
||||||
expect(client.db!.userId, userId);
|
expect(client.userId, userId);
|
||||||
|
|
||||||
addTearDown(() async {
|
addTearDown(() async {
|
||||||
await client.disconnect();
|
await client.disconnect();
|
||||||
@@ -33,7 +33,7 @@ void main() {
|
|||||||
await client.connect(userId, databaseProvider: testDatabaseProvider);
|
await client.connect(userId, databaseProvider: testDatabaseProvider);
|
||||||
expect(client.isConnected, true);
|
expect(client.isConnected, true);
|
||||||
expect(client.db, isA<DriftChatDatabase>());
|
expect(client.db, isA<DriftChatDatabase>());
|
||||||
expect(client.db!.userId, userId);
|
expect(client.userId, userId);
|
||||||
expect(
|
expect(
|
||||||
() => client.connect(userId, databaseProvider: testDatabaseProvider),
|
() => client.connect(userId, databaseProvider: testDatabaseProvider),
|
||||||
throwsException,
|
throwsException,
|
||||||
|
|||||||
Reference in New Issue
Block a user