✨ Basic message sending and listing
This commit is contained in:
@ -28,8 +28,11 @@ class ChatChannelProvider extends ChangeNotifier {
|
||||
});
|
||||
}
|
||||
|
||||
Future<List<SnChannel>> _fetchChannelsFromServer(
|
||||
{scope = 'global', direct = false}) async {
|
||||
Future<List<SnChannel>> _fetchChannelsFromServer({
|
||||
String scope = 'global',
|
||||
bool direct = false,
|
||||
bool doNotSave = false,
|
||||
}) async {
|
||||
final resp = await _sn.client.get(
|
||||
'/cgi/im/channels/$scope/me/available',
|
||||
queryParameters: {
|
||||
@ -39,15 +42,37 @@ class ChatChannelProvider extends ChangeNotifier {
|
||||
final out = List<SnChannel>.from(
|
||||
resp.data?.map((e) => SnChannel.fromJson(e)) ?? [],
|
||||
);
|
||||
_saveChannelToLocal(out);
|
||||
if (!doNotSave) _saveChannelToLocal(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
// The fetch channel method return a stream, which will emit twice.
|
||||
// The first time is when the data was fetched from the local storage.
|
||||
// And the second time is when the data was fetched from the server.
|
||||
// But there is some exception that will only cause one of them to be emitted.
|
||||
// Like the local storage is broken or the server is down.
|
||||
/// The get channel method will return the channel with the given alias.
|
||||
/// It will use the local storage as much as possible.
|
||||
/// The alias should include the scope, formatted as `scope:alias`.
|
||||
Future<SnChannel> getChannel(String key) async {
|
||||
if (_channelBox != null) {
|
||||
final local = _channelBox!.get(key);
|
||||
if (local != null) return local;
|
||||
}
|
||||
|
||||
var resp = await _sn.client.get('/cgi/im/channels/$key');
|
||||
var out = SnChannel.fromJson(resp.data);
|
||||
|
||||
// Preload realm of the channel
|
||||
if (out.realmId != null) {
|
||||
resp = await _sn.client.get('/cgi/id/realms/${out.realmId}');
|
||||
out = out.copyWith(realm: SnRealm.fromJson(resp.data));
|
||||
}
|
||||
|
||||
_saveChannelToLocal([out]);
|
||||
return out;
|
||||
}
|
||||
|
||||
/// The fetch channel method return a stream, which will emit twice.
|
||||
/// The first time is when the data was fetched from the local storage.
|
||||
/// And the second time is when the data was fetched from the server.
|
||||
/// But there is some exception that will only cause one of them to be emitted.
|
||||
/// Like the local storage is broken or the server is down.
|
||||
Stream<List<SnChannel>> fetchChannels() async* {
|
||||
if (_channelBox != null) yield _channelBox!.values.toList();
|
||||
|
||||
@ -55,18 +80,34 @@ class ChatChannelProvider extends ChangeNotifier {
|
||||
final realms = List<SnRealm>.from(
|
||||
resp.data?.map((e) => SnRealm.fromJson(e)) ?? [],
|
||||
);
|
||||
final realmMap = {
|
||||
for (final realm in realms) realm.alias: realm,
|
||||
};
|
||||
|
||||
final scopeToFetch = {'global', ...realms.map((e) => e.alias)};
|
||||
|
||||
final List<SnChannel> result = List.empty(growable: true);
|
||||
final dm =
|
||||
await _fetchChannelsFromServer(scope: scopeToFetch.first, direct: true);
|
||||
result.addAll(dm);
|
||||
final directMessages = await _fetchChannelsFromServer(
|
||||
scope: scopeToFetch.first,
|
||||
direct: true,
|
||||
);
|
||||
result.addAll(directMessages);
|
||||
|
||||
for (final scope in scopeToFetch) {
|
||||
final channel =
|
||||
await _fetchChannelsFromServer(scope: scope, direct: false);
|
||||
result.addAll(channel);
|
||||
final nonBelongsChannels = await _fetchChannelsFromServer(
|
||||
scope: scopeToFetch.first,
|
||||
direct: false,
|
||||
);
|
||||
result.addAll(nonBelongsChannels);
|
||||
|
||||
for (final scope in scopeToFetch.skip(1)) {
|
||||
final channel = await _fetchChannelsFromServer(
|
||||
scope: scope,
|
||||
direct: false,
|
||||
doNotSave: true,
|
||||
);
|
||||
final out = channel.map((ele) => ele.copyWith(realm: realmMap[scope]));
|
||||
_saveChannelToLocal(out);
|
||||
result.addAll(out);
|
||||
}
|
||||
|
||||
yield result;
|
||||
|
Reference in New Issue
Block a user