Make stream_chat_persistence a add on dependency instead of shipping it with the llc
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -419,7 +419,7 @@ class Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await _client.chatPersistence?.deleteMessageById(messageId);
|
await _client.chatPersistenceClient?.deleteMessageById(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -487,7 +487,7 @@ class Channel {
|
|||||||
PaginationParams options, {
|
PaginationParams options, {
|
||||||
bool preferOffline = false,
|
bool preferOffline = false,
|
||||||
}) async {
|
}) async {
|
||||||
final cachedReplies = await _client.chatPersistence?.getReplies(
|
final cachedReplies = await _client.chatPersistenceClient?.getReplies(
|
||||||
parentId,
|
parentId,
|
||||||
lessThan: options?.lessThan,
|
lessThan: options?.lessThan,
|
||||||
);
|
);
|
||||||
@@ -603,7 +603,8 @@ class Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (preferOffline && cid != null) {
|
if (preferOffline && cid != null) {
|
||||||
final updatedState = await _client.chatPersistence?.getChannelStateByCid(
|
final updatedState =
|
||||||
|
await _client.chatPersistenceClient?.getChannelStateByCid(
|
||||||
cid,
|
cid,
|
||||||
messagePagination: messagesPagination,
|
messagePagination: messagesPagination,
|
||||||
);
|
);
|
||||||
@@ -730,7 +731,7 @@ class Channel {
|
|||||||
|
|
||||||
if (clearHistory == true) {
|
if (clearHistory == true) {
|
||||||
state.truncate();
|
state.truncate();
|
||||||
await _client.chatPersistence?.deleteMessageByCid(_cid);
|
await _client.chatPersistenceClient?.deleteMessageByCid(_cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _client.decode(response.data, EmptyResponse.fromJson);
|
return _client.decode(response.data, EmptyResponse.fromJson);
|
||||||
@@ -869,7 +870,7 @@ class ChannelClientState {
|
|||||||
|
|
||||||
_computeInitialUnread();
|
_computeInitialUnread();
|
||||||
|
|
||||||
_channel._client.chatPersistence
|
_channel._client.chatPersistenceClient
|
||||||
?.getChannelThreads(_channel.cid)
|
?.getChannelThreads(_channel.cid)
|
||||||
?.then((threads) {
|
?.then((threads) {
|
||||||
_threads = threads;
|
_threads = threads;
|
||||||
@@ -947,7 +948,8 @@ class ChannelClientState {
|
|||||||
.on(EventType.channelTruncated, EventType.notificationChannelTruncated)
|
.on(EventType.channelTruncated, EventType.notificationChannelTruncated)
|
||||||
.listen((event) async {
|
.listen((event) async {
|
||||||
final channel = event.channel;
|
final channel = event.channel;
|
||||||
await _channel._client.chatPersistence?.deleteMessageByCid(channel.cid);
|
await _channel._client.chatPersistenceClient
|
||||||
|
?.deleteMessageByCid(channel.cid);
|
||||||
truncate();
|
truncate();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -1401,7 +1403,7 @@ class ChannelClientState {
|
|||||||
|
|
||||||
set _channelState(ChannelState v) {
|
set _channelState(ChannelState v) {
|
||||||
_channelStateController.add(v);
|
_channelStateController.add(v);
|
||||||
_channel._client.chatPersistence?.updateChannelState(v);
|
_channel._client.chatPersistenceClient?.updateChannelState(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The channel threads related to this channel
|
/// The channel threads related to this channel
|
||||||
@@ -1414,7 +1416,7 @@ class ChannelClientState {
|
|||||||
BehaviorSubject.seeded({});
|
BehaviorSubject.seeded({});
|
||||||
|
|
||||||
set _threads(Map<String, List<Message>> v) {
|
set _threads(Map<String, List<Message>> v) {
|
||||||
_channel._client.chatPersistence?.updateMessages(
|
_channel._client.chatPersistenceClient?.updateMessages(
|
||||||
_channel.cid,
|
_channel.cid,
|
||||||
v.values.expand((v) => v).toList(),
|
v.values.expand((v) => v).toList(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:dio/dio.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:stream_chat/src/api/retry_policy.dart';
|
import 'package:stream_chat/src/api/retry_policy.dart';
|
||||||
import 'package:stream_chat/src/event_type.dart';
|
import 'package:stream_chat/src/event_type.dart';
|
||||||
@@ -21,7 +20,7 @@ import 'api/connection_status.dart';
|
|||||||
import 'api/requests.dart';
|
import 'api/requests.dart';
|
||||||
import 'api/responses.dart';
|
import 'api/responses.dart';
|
||||||
import 'api/websocket.dart';
|
import 'api/websocket.dart';
|
||||||
import 'db/stream_chat_persistence.dart';
|
import 'db/chat_persistence_client.dart';
|
||||||
import 'exceptions.dart';
|
import 'exceptions.dart';
|
||||||
import 'models/event.dart';
|
import 'models/event.dart';
|
||||||
import 'models/message.dart';
|
import 'models/message.dart';
|
||||||
@@ -87,7 +86,6 @@ class Client {
|
|||||||
this.baseURL = _defaultBaseURL,
|
this.baseURL = _defaultBaseURL,
|
||||||
this.logLevel = Level.WARNING,
|
this.logLevel = Level.WARNING,
|
||||||
this.logHandlerFunction,
|
this.logHandlerFunction,
|
||||||
this.persistenceEnabled = true,
|
|
||||||
Duration connectTimeout = const Duration(seconds: 6),
|
Duration connectTimeout = const Duration(seconds: 6),
|
||||||
Duration receiveTimeout = const Duration(seconds: 6),
|
Duration receiveTimeout = const Duration(seconds: 6),
|
||||||
Dio httpClient,
|
Dio httpClient,
|
||||||
@@ -111,10 +109,11 @@ class Client {
|
|||||||
logger.info('instantiating new client');
|
logger.info('instantiating new client');
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamChatPersistence _chatPersistence;
|
/// Client chat persistence client
|
||||||
|
ChatPersistenceClient chatPersistenceClient;
|
||||||
|
|
||||||
/// If true chat data will persist on disk
|
/// Whether the chat persistence is available or not
|
||||||
final bool persistenceEnabled;
|
bool get persistenceEnabled => chatPersistenceClient != null;
|
||||||
|
|
||||||
RetryPolicy _retryPolicy;
|
RetryPolicy _retryPolicy;
|
||||||
|
|
||||||
@@ -131,9 +130,6 @@ class Client {
|
|||||||
/// The amount of time that will pass before disconnecting the client in the background
|
/// The amount of time that will pass before disconnecting the client in the background
|
||||||
final Duration backgroundKeepAlive;
|
final Duration backgroundKeepAlive;
|
||||||
|
|
||||||
/// Client offline database
|
|
||||||
StreamChatPersistence get chatPersistence => _chatPersistence;
|
|
||||||
|
|
||||||
/// This client state
|
/// This client state
|
||||||
ClientState state;
|
ClientState state;
|
||||||
|
|
||||||
@@ -345,7 +341,7 @@ class Client {
|
|||||||
|
|
||||||
/// Call this function to dispose the client
|
/// Call this function to dispose the client
|
||||||
void dispose() async {
|
void dispose() async {
|
||||||
await _chatPersistence?.disconnect();
|
await chatPersistenceClient?.disconnect();
|
||||||
await _disconnect();
|
await _disconnect();
|
||||||
httpClient.close();
|
httpClient.close();
|
||||||
await _controller.close();
|
await _controller.close();
|
||||||
@@ -427,8 +423,8 @@ class Client {
|
|||||||
|
|
||||||
if (!event.isLocal) {
|
if (!event.isLocal) {
|
||||||
if (_synced && event.createdAt != null) {
|
if (_synced && event.createdAt != null) {
|
||||||
await _chatPersistence?.updateConnectionInfo(event);
|
await chatPersistenceClient?.updateConnectionInfo(event);
|
||||||
await _chatPersistence?.updateLastSyncAt(event.createdAt);
|
await chatPersistenceClient?.updateLastSyncAt(event.createdAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,12 +455,8 @@ class Client {
|
|||||||
|
|
||||||
wsConnectionStatus.value = ConnectionStatus.connecting;
|
wsConnectionStatus.value = ConnectionStatus.connecting;
|
||||||
|
|
||||||
if (persistenceEnabled && _chatPersistence == null) {
|
if (persistenceEnabled) {
|
||||||
_chatPersistence = StreamChatPersistenceImpl(
|
await chatPersistenceClient.connect('db_${state.user.id}');
|
||||||
state.user.id,
|
|
||||||
logger: _detachedLogger('💽'),
|
|
||||||
);
|
|
||||||
await _chatPersistence.connect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ws = WebSocket(
|
_ws = WebSocket(
|
||||||
@@ -514,10 +506,10 @@ class Client {
|
|||||||
|
|
||||||
_ws.connectionStatus.addListener(_connectionStatusListener);
|
_ws.connectionStatus.addListener(_connectionStatusListener);
|
||||||
|
|
||||||
var event = await _chatPersistence?.getConnectionInfo();
|
var event = await chatPersistenceClient?.getConnectionInfo();
|
||||||
|
|
||||||
await _ws.connect().then((e) async {
|
await _ws.connect().then((e) async {
|
||||||
await _chatPersistence?.updateConnectionInfo(e);
|
await chatPersistenceClient?.updateConnectionInfo(e);
|
||||||
event = e;
|
event = e;
|
||||||
await resync();
|
await resync();
|
||||||
}).catchError((err, stacktrace) {
|
}).catchError((err, stacktrace) {
|
||||||
@@ -532,14 +524,14 @@ class Client {
|
|||||||
|
|
||||||
/// Get the events missed while offline to sync the offline storage
|
/// Get the events missed while offline to sync the offline storage
|
||||||
Future<void> resync([List<String> cids]) async {
|
Future<void> resync([List<String> cids]) async {
|
||||||
final lastSyncAt = await chatPersistence?.getLastSyncAt();
|
final lastSyncAt = await chatPersistenceClient?.getLastSyncAt();
|
||||||
|
|
||||||
if (lastSyncAt == null) {
|
if (lastSyncAt == null) {
|
||||||
_synced = true;
|
_synced = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cids ??= await chatPersistence?.getChannelCids();
|
cids ??= await chatPersistenceClient?.getChannelCids();
|
||||||
|
|
||||||
if (cids?.isEmpty == true) {
|
if (cids?.isEmpty == true) {
|
||||||
return;
|
return;
|
||||||
@@ -568,7 +560,7 @@ class Client {
|
|||||||
handleEvent(event);
|
handleEvent(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
await _chatPersistence?.updateLastSyncAt(DateTime.now());
|
await chatPersistenceClient?.updateLastSyncAt(DateTime.now());
|
||||||
_synced = true;
|
_synced = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.severe('Error during resync $error');
|
logger.severe('Error during resync $error');
|
||||||
@@ -714,7 +706,7 @@ class Client {
|
|||||||
channels.add(channel);
|
channels.add(channel);
|
||||||
} else {
|
} else {
|
||||||
final newChannel = Channel.fromState(this, channelState);
|
final newChannel = Channel.fromState(this, channelState);
|
||||||
await _chatPersistence
|
await chatPersistenceClient
|
||||||
?.updateChannelState(newChannel.state.channelState);
|
?.updateChannelState(newChannel.state.channelState);
|
||||||
newChannel.state?.updateChannelState(channelState);
|
newChannel.state?.updateChannelState(channelState);
|
||||||
newChannels[newChannel.cid] = newChannel;
|
newChannels[newChannel.cid] = newChannel;
|
||||||
@@ -725,7 +717,7 @@ class Client {
|
|||||||
|
|
||||||
state.channels = newChannels;
|
state.channels = newChannels;
|
||||||
|
|
||||||
await _chatPersistence?.updateChannelQueries(
|
await chatPersistenceClient?.updateChannelQueries(
|
||||||
filter,
|
filter,
|
||||||
res.channels.map((c) => c.channel.cid).toList(),
|
res.channels.map((c) => c.channel.cid).toList(),
|
||||||
paginationParams?.offset == null || paginationParams.offset == 0,
|
paginationParams?.offset == null || paginationParams.offset == 0,
|
||||||
@@ -760,7 +752,7 @@ class Client {
|
|||||||
@required List<SortOption> sort,
|
@required List<SortOption> sort,
|
||||||
PaginationParams paginationParams = const PaginationParams(limit: 10),
|
PaginationParams paginationParams = const PaginationParams(limit: 10),
|
||||||
}) async {
|
}) async {
|
||||||
final offlineChannels = await _chatPersistence?.getChannelStates(
|
final offlineChannels = await chatPersistenceClient?.getChannelStates(
|
||||||
filter: filter,
|
filter: filter,
|
||||||
sort: sort,
|
sort: sort,
|
||||||
paginationParams: paginationParams,
|
paginationParams: paginationParams,
|
||||||
@@ -775,7 +767,8 @@ class Client {
|
|||||||
return channel;
|
return channel;
|
||||||
} else {
|
} else {
|
||||||
final newChannel = Channel.fromState(this, channelState);
|
final newChannel = Channel.fromState(this, channelState);
|
||||||
_chatPersistence?.updateChannelState(newChannel.state.channelState);
|
chatPersistenceClient
|
||||||
|
?.updateChannelState(newChannel.state.channelState);
|
||||||
newChannels[newChannel.cid] = newChannel;
|
newChannels[newChannel.cid] = newChannel;
|
||||||
return newChannel;
|
return newChannel;
|
||||||
}
|
}
|
||||||
@@ -938,8 +931,8 @@ class Client {
|
|||||||
logger.info(
|
logger.info(
|
||||||
'Disconnecting flushOfflineStorage: $flushChatPersistence; clearUser: $clearUser');
|
'Disconnecting flushOfflineStorage: $flushChatPersistence; clearUser: $clearUser');
|
||||||
|
|
||||||
await _chatPersistence?.disconnect(flush: flushChatPersistence);
|
await chatPersistenceClient?.disconnect(flush: flushChatPersistence);
|
||||||
_chatPersistence = null;
|
chatPersistenceClient = null;
|
||||||
|
|
||||||
if (clearUser == true) {
|
if (clearUser == true) {
|
||||||
state.dispose();
|
state.dispose();
|
||||||
@@ -1328,7 +1321,7 @@ class ClientState {
|
|||||||
|
|
||||||
void _listenChannelHidden() {
|
void _listenChannelHidden() {
|
||||||
_subscriptions.add(_client.on(EventType.channelHidden).listen((event) {
|
_subscriptions.add(_client.on(EventType.channelHidden).listen((event) {
|
||||||
_client._chatPersistence?.deleteChannels([event.cid]);
|
_client.chatPersistenceClient?.deleteChannels([event.cid]);
|
||||||
if (channels != null) {
|
if (channels != null) {
|
||||||
channels = channels..removeWhere((cid, ch) => cid == event.cid);
|
channels = channels..removeWhere((cid, ch) => cid == event.cid);
|
||||||
}
|
}
|
||||||
@@ -1353,7 +1346,7 @@ class ClientState {
|
|||||||
)
|
)
|
||||||
.listen((Event event) async {
|
.listen((Event event) async {
|
||||||
final eventChannel = event.channel;
|
final eventChannel = event.channel;
|
||||||
await _client._chatPersistence?.deleteChannels([eventChannel.cid]);
|
await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]);
|
||||||
if (channels != null) {
|
if (channels != null) {
|
||||||
channels = channels..remove(eventChannel.cid);
|
channels = channels..remove(eventChannel.cid);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-8
@@ -9,15 +9,12 @@ import 'package:stream_chat/src/models/read.dart';
|
|||||||
import 'package:stream_chat/src/models/user.dart';
|
import 'package:stream_chat/src/models/user.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
abstract class StreamChatPersistence {
|
abstract class ChatPersistenceClient {
|
||||||
/// Creates a new connection to the database
|
/// Creates a new connection to the client
|
||||||
Future<void> connect({
|
Future<void> connect(String name);
|
||||||
bool connectBackground = false,
|
|
||||||
bool logStatements = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Closes the database instance
|
/// Closes the client connection
|
||||||
/// If [flush] is true, the database data will be deleted
|
/// If [flush] is true, the data will also be deleted
|
||||||
Future<void> disconnect({bool flush = false});
|
Future<void> disconnect({bool flush = false});
|
||||||
|
|
||||||
/// Get stored replies by messageId
|
/// Get stored replies by messageId
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:stream_chat/src/api/responses.dart';
|
import 'package:stream_chat/src/api/responses.dart';
|
||||||
import 'package:stream_chat/src/models/channel_model.dart';
|
import 'package:stream_chat/src/models/channel_model.dart';
|
||||||
import 'package:stream_chat/src/models/channel_state.dart';
|
import 'package:stream_chat/src/models/channel_state.dart';
|
||||||
import 'package:stream_chat/src/models/message.dart';
|
import 'package:stream_chat/src/models/message.dart';
|
||||||
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
import 'client.dart';
|
import 'client.dart';
|
||||||
import 'models/own_user.dart';
|
import 'models/own_user.dart';
|
||||||
@@ -20,21 +19,13 @@ class NotificationService {
|
|||||||
) async {
|
) async {
|
||||||
if (message != null && client.persistenceEnabled) {
|
if (message != null && client.persistenceEnabled) {
|
||||||
if (client?.state?.channels == null) {
|
if (client?.state?.channels == null) {
|
||||||
final sharedPreferences = await _getSharedPreferences();
|
final chatPersistenceClient = client.chatPersistenceClient;
|
||||||
final userId = sharedPreferences.getString(KEY_USER_ID);
|
await chatPersistenceClient.updateChannelState(
|
||||||
|
|
||||||
final chatPersistence = StreamChatPersistenceImpl(
|
|
||||||
userId,
|
|
||||||
logger: Logger('💽'),
|
|
||||||
);
|
|
||||||
await chatPersistence.connect();
|
|
||||||
await chatPersistence.updateChannelState(
|
|
||||||
ChannelState(
|
ChannelState(
|
||||||
channel: channelModel,
|
channel: channelModel,
|
||||||
messages: [message],
|
messages: [message],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await chatPersistence.disconnect();
|
|
||||||
} else {
|
} else {
|
||||||
final channel = client.state.channels[channelModel.cid];
|
final channel = client.state.channels[channelModel.cid];
|
||||||
channel.state.updateChannelState(
|
channel.state.updateChannelState(
|
||||||
@@ -56,14 +47,11 @@ class NotificationService {
|
|||||||
|
|
||||||
/// Gets the message using the client without storing it in the offline storage
|
/// Gets the message using the client without storing it in the offline storage
|
||||||
/// It returns an object containing the information about the message and the channel
|
/// It returns an object containing the information about the message and the channel
|
||||||
static Future<GetMessageResponse> getMessage(String messageId) async {
|
static Future<GetMessageResponse> _getMessage(String messageId) async {
|
||||||
final sharedPreferences = await _getSharedPreferences();
|
final sharedPreferences = await _getSharedPreferences();
|
||||||
final apiKey = sharedPreferences.getString(KEY_API_KEY);
|
final apiKey = sharedPreferences.getString(KEY_API_KEY);
|
||||||
|
|
||||||
final client = Client(
|
final client = Client(apiKey);
|
||||||
apiKey,
|
|
||||||
persistenceEnabled: false,
|
|
||||||
);
|
|
||||||
final userId = sharedPreferences.getString(KEY_USER_ID);
|
final userId = sharedPreferences.getString(KEY_USER_ID);
|
||||||
final token = sharedPreferences.getString(KEY_TOKEN);
|
final token = sharedPreferences.getString(KEY_TOKEN);
|
||||||
|
|
||||||
@@ -74,30 +62,16 @@ class NotificationService {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores the message in the offline storage
|
/// Gets the message using the client and calls a [storeMessageHandler] callback
|
||||||
static Future<void> storeMessage(GetMessageResponse messageResponse) async {
|
/// with the message if the user wants to save the message in db
|
||||||
final sharedPreferences = await _getSharedPreferences();
|
///
|
||||||
final userId = sharedPreferences.getString(KEY_USER_ID);
|
|
||||||
|
|
||||||
final chatPersistence = StreamChatPersistenceImpl(
|
|
||||||
userId,
|
|
||||||
logger: Logger('💽'),
|
|
||||||
);
|
|
||||||
await chatPersistence.connect();
|
|
||||||
|
|
||||||
await chatPersistence.updateChannelState(ChannelState(
|
|
||||||
messages: [messageResponse.message],
|
|
||||||
channel: messageResponse.channel,
|
|
||||||
));
|
|
||||||
|
|
||||||
await chatPersistence.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the message using the client and stores it in the offline storage
|
|
||||||
/// It returns an object containing the information about the message and the channel
|
/// It returns an object containing the information about the message and the channel
|
||||||
static Future<GetMessageResponse> getAndStoreMessage(String messageId) async {
|
static Future<GetMessageResponse> getAndStoreMessage({
|
||||||
final getMessageResponse = await getMessage(messageId);
|
@required String messageId,
|
||||||
await storeMessage(getMessageResponse);
|
@required Future<void> Function(GetMessageResponse) storeMessageHandler,
|
||||||
|
}) async {
|
||||||
|
final getMessageResponse = await _getMessage(messageId);
|
||||||
|
await storeMessageHandler(getMessageResponse);
|
||||||
return getMessageResponse;
|
return getMessageResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ export './src/models/reaction.dart';
|
|||||||
export './src/models/read.dart';
|
export './src/models/read.dart';
|
||||||
export './src/models/user.dart';
|
export './src/models/user.dart';
|
||||||
export './src/notifications.dart';
|
export './src/notifications.dart';
|
||||||
export './src/db/stream_chat_persistence.dart';
|
export './src/db/chat_persistence_client.dart';
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
|
||||||
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
|
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
|
||||||
|
|
||||||
import 'choose_user_page.dart';
|
import 'choose_user_page.dart';
|
||||||
|
import 'main.dart';
|
||||||
import 'notifications_service.dart';
|
import 'notifications_service.dart';
|
||||||
|
|
||||||
class AdvancedOptionsPage extends StatefulWidget {
|
class AdvancedOptionsPage extends StatefulWidget {
|
||||||
@@ -278,8 +280,7 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
|
|||||||
showLocalNotification: (!kIsWeb && Platform.isAndroid)
|
showLocalNotification: (!kIsWeb && Platform.isAndroid)
|
||||||
? showLocalNotification
|
? showLocalNotification
|
||||||
: null,
|
: null,
|
||||||
persistenceEnabled: true,
|
)..chatPersistenceClient = chatPersistentClient;
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await client.setUser(
|
await client.setUser(
|
||||||
@@ -320,72 +321,13 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kIsWeb) {
|
|
||||||
initNotifications(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
Navigator.pop(context);
|
|
||||||
await Navigator.pushReplacement(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) {
|
|
||||||
return FutureBuilder<StreamingSharedPreferences>(
|
|
||||||
future: StreamingSharedPreferences.instance,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
if (!snapshot.hasData) {
|
|
||||||
return SizedBox();
|
|
||||||
}
|
|
||||||
return PreferenceBuilder<int>(
|
|
||||||
preference: snapshot.data.getInt(
|
|
||||||
'theme',
|
|
||||||
defaultValue: 0,
|
|
||||||
),
|
|
||||||
builder: (context, snapshot) => MaterialApp(
|
|
||||||
builder: (context, child) {
|
|
||||||
return StreamChat(
|
|
||||||
client: client,
|
|
||||||
child: Builder(
|
|
||||||
builder: (context) =>
|
|
||||||
AnnotatedRegion<
|
|
||||||
SystemUiOverlayStyle>(
|
|
||||||
child: child,
|
|
||||||
value: SystemUiOverlayStyle(
|
|
||||||
systemNavigationBarColor:
|
|
||||||
StreamChatTheme.of(context)
|
|
||||||
.colorTheme
|
|
||||||
.white,
|
|
||||||
systemNavigationBarIconBrightness:
|
|
||||||
Theme.of(context)
|
|
||||||
.brightness ==
|
|
||||||
Brightness.dark
|
|
||||||
? Brightness.light
|
|
||||||
: Brightness.dark,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
theme: ThemeData.light(),
|
|
||||||
darkTheme: ThemeData.dark(),
|
|
||||||
themeMode: {
|
|
||||||
-1: ThemeMode.dark,
|
|
||||||
0: ThemeMode.system,
|
|
||||||
1: ThemeMode.light,
|
|
||||||
}[snapshot],
|
|
||||||
onGenerateRoute: AppRoutes.generateRoute,
|
|
||||||
initialRoute: client.state.user == null
|
|
||||||
? Routes.CHOOSE_USER
|
|
||||||
: Routes.HOME,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
loading = false;
|
loading = false;
|
||||||
|
await Navigator.pushReplacementNamed(
|
||||||
|
context,
|
||||||
|
Routes.APP,
|
||||||
|
arguments: client,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
import 'package:stream_chat_persistence/stream_chat_persistence.dart';
|
||||||
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
|
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
|
||||||
|
|
||||||
import 'notifications_service.dart';
|
import 'notifications_service.dart';
|
||||||
@@ -17,6 +18,11 @@ import 'routes/app_routes.dart';
|
|||||||
import 'routes/routes.dart';
|
import 'routes/routes.dart';
|
||||||
import 'search_text_field.dart';
|
import 'search_text_field.dart';
|
||||||
|
|
||||||
|
final chatPersistentClient = StreamChatPersistenceClient(
|
||||||
|
logLevel: Level.INFO,
|
||||||
|
connectionMode: ConnectionMode.background,
|
||||||
|
);
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
final secureStorage = FlutterSecureStorage();
|
final secureStorage = FlutterSecureStorage();
|
||||||
@@ -29,8 +35,7 @@ void main() async {
|
|||||||
logLevel: Level.INFO,
|
logLevel: Level.INFO,
|
||||||
showLocalNotification:
|
showLocalNotification:
|
||||||
(!kIsWeb && Platform.isAndroid) ? showLocalNotification : null,
|
(!kIsWeb && Platform.isAndroid) ? showLocalNotification : null,
|
||||||
persistenceEnabled: true,
|
)..chatPersistenceClient = chatPersistentClient;
|
||||||
);
|
|
||||||
|
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
final token = await secureStorage.read(key: kStreamToken);
|
final token = await secureStorage.read(key: kStreamToken);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:example/main.dart';
|
||||||
import 'package:flutter_apns/flutter_apns.dart';
|
import 'package:flutter_apns/flutter_apns.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart'
|
||||||
hide Message;
|
hide Message;
|
||||||
@@ -36,8 +37,17 @@ Future backgroundHandler(Map<String, dynamic> notification) async {
|
|||||||
print('new notification ${notification}');
|
print('new notification ${notification}');
|
||||||
final messageId = notification['data']['id'];
|
final messageId = notification['data']['id'];
|
||||||
|
|
||||||
final notificationData =
|
final notificationData = await NotificationService.getAndStoreMessage(
|
||||||
await NotificationService.getAndStoreMessage(messageId);
|
messageId: messageId,
|
||||||
|
storeMessageHandler: (messageResponse) {
|
||||||
|
return chatPersistentClient.updateChannelState(
|
||||||
|
ChannelState(
|
||||||
|
messages: [messageResponse.message],
|
||||||
|
channel: messageResponse.channel,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
showLocalNotification(
|
showLocalNotification(
|
||||||
notificationData.message,
|
notificationData.message,
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ class AppRoutes {
|
|||||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
final args = settings.arguments;
|
final args = settings.arguments;
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
|
case Routes.APP:
|
||||||
|
return MaterialPageRoute(
|
||||||
|
settings: const RouteSettings(name: Routes.APP),
|
||||||
|
builder: (_) {
|
||||||
|
return MyApp(args);
|
||||||
|
});
|
||||||
case Routes.HOME:
|
case Routes.HOME:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
settings: const RouteSettings(name: Routes.HOME),
|
settings: const RouteSettings(name: Routes.HOME),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/// Define all the route names here
|
/// Define all the route names here
|
||||||
class Routes {
|
class Routes {
|
||||||
|
static const String APP = '/app';
|
||||||
static const String HOME = '/home';
|
static const String HOME = '/home';
|
||||||
static const String CHOOSE_USER = '/choose_user';
|
static const String CHOOSE_USER = '/choose_user';
|
||||||
static const String ADVANCED_OPTIONS = '/advance_options';
|
static const String ADVANCED_OPTIONS = '/advance_options';
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter:
|
stream_chat_flutter:
|
||||||
path: ../
|
path: ../
|
||||||
|
stream_chat_persistence:
|
||||||
|
path: ../../stream_chat_persistence
|
||||||
flutter_apns: ^1.4.1
|
flutter_apns: ^1.4.1
|
||||||
flutter_local_notifications: ^2.0.2
|
flutter_local_notifications: ^2.0.2
|
||||||
flutter_svg: ^0.19.1
|
flutter_svg: ^0.19.1
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class SharedDB {
|
|||||||
|
|
||||||
static constructOfflineStorage(
|
static constructOfflineStorage(
|
||||||
String dbName, {
|
String dbName, {
|
||||||
logStatements = false,
|
bool logStatements = false,
|
||||||
}) {
|
}) {
|
||||||
throw 'Unsupported Platform';
|
throw 'Unsupported Platform';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
import 'user_mapper.dart';
|
|
||||||
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
|
import 'package:stream_chat_persistence/src/db/moor_chat_database.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
+32
-25
@@ -3,18 +3,30 @@ import 'package:stream_chat/stream_chat.dart';
|
|||||||
import 'db/moor_chat_database.dart';
|
import 'db/moor_chat_database.dart';
|
||||||
import 'db/shared/shared_db.dart';
|
import 'db/shared/shared_db.dart';
|
||||||
|
|
||||||
|
/// Various connection modes on which [StreamChatPersistenceClient] can work
|
||||||
|
enum ConnectionMode {
|
||||||
|
/// Connects the [StreamChatPersistenceClient] on a regular/default isolate
|
||||||
|
regular,
|
||||||
|
|
||||||
|
/// Connects the [StreamChatPersistenceClient] on a background isolate
|
||||||
|
background,
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
class StreamChatPersistenceImpl extends StreamChatPersistence {
|
class StreamChatPersistenceClient extends ChatPersistenceClient {
|
||||||
///
|
///
|
||||||
StreamChatPersistenceImpl(
|
StreamChatPersistenceClient({
|
||||||
this._userId, {
|
/// Connection mode on which the client will work
|
||||||
Logger logger,
|
ConnectionMode connectionMode = ConnectionMode.regular,
|
||||||
}) : _logger = logger,
|
Level logLevel = Level.WARNING,
|
||||||
assert(_userId != null);
|
}) : assert(connectionMode != null),
|
||||||
|
assert(logLevel != null),
|
||||||
|
_connectionMode = connectionMode,
|
||||||
|
_logger = Logger.detached('💽')..level = logLevel;
|
||||||
|
|
||||||
final String _userId;
|
|
||||||
final Logger _logger;
|
|
||||||
MoorChatDatabase _db;
|
MoorChatDatabase _db;
|
||||||
|
final Logger _logger;
|
||||||
|
final ConnectionMode _connectionMode;
|
||||||
|
|
||||||
bool get _debugAssertConnected {
|
bool get _debugAssertConnected {
|
||||||
assert(() {
|
assert(() {
|
||||||
@@ -30,27 +42,22 @@ class StreamChatPersistenceImpl extends StreamChatPersistence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> connect({
|
Future<void> connect(String name) async {
|
||||||
bool connectBackground = false,
|
|
||||||
bool logStatements = false,
|
|
||||||
}) async {
|
|
||||||
if (_db != null) {
|
if (_db != null) {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
'An instance of StreamChatDatabase is already connected.\n'
|
'An instance of StreamChatDatabase is already connected.\n'
|
||||||
'disconnect the previous instance before connecting again.',
|
'disconnect the previous instance before connecting again.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
switch (_connectionMode) {
|
||||||
final dbName = 'db_$_userId';
|
case ConnectionMode.regular:
|
||||||
if (connectBackground) {
|
_logger.info('Connecting on a regular isolate');
|
||||||
_logger?.info('Connecting on background isolate');
|
_db = MoorChatDatabase(name);
|
||||||
_db = await SharedDB.constructOfflineStorage(
|
return;
|
||||||
dbName,
|
case ConnectionMode.background:
|
||||||
logStatements: logStatements,
|
_logger.info('Connecting on background isolate');
|
||||||
);
|
_db = await SharedDB.constructOfflineStorage(name);
|
||||||
} else {
|
return;
|
||||||
_logger?.info('Connecting on a regular isolate');
|
|
||||||
_db = MoorChatDatabase(dbName, logStatements: logStatements);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,9 +209,9 @@ class StreamChatPersistenceImpl extends StreamChatPersistence {
|
|||||||
@override
|
@override
|
||||||
Future<void> disconnect({bool flush = false}) async {
|
Future<void> disconnect({bool flush = false}) async {
|
||||||
if (_db != null) {
|
if (_db != null) {
|
||||||
_logger?.info('Disconnecting');
|
_logger.info('Disconnecting');
|
||||||
if (flush) {
|
if (flush) {
|
||||||
_logger?.info('Flushing');
|
_logger.info('Flushing');
|
||||||
await _db.batch((batch) {
|
await _db.batch((batch) {
|
||||||
_db.allTables.forEach((table) {
|
_db.allTables.forEach((table) {
|
||||||
_db.delete(table).go();
|
_db.delete(table).go();
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
library stream_chat_persistence;
|
library stream_chat_persistence;
|
||||||
|
|
||||||
export 'src/stream_chat_persistence_impl.dart';
|
export 'src/stream_chat_persistence_client.dart';
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ dependencies:
|
|||||||
moor: ^3.4.0
|
moor: ^3.4.0
|
||||||
path: ^1.7.0
|
path: ^1.7.0
|
||||||
path_provider: ^1.6.27
|
path_provider: ^1.6.27
|
||||||
|
sqlite3_flutter_libs: ^0.3.0
|
||||||
stream_chat:
|
stream_chat:
|
||||||
path: ../dart_client
|
path: ../dart_client
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user