mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-06-23 13:54:10 -04:00
1.0.2
This commit is contained in:
parent
d965f674fc
commit
e76e3cf0ba
11 changed files with 148 additions and 66 deletions
|
@ -2,6 +2,8 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import '../providers/account.dart';
|
||||||
import '../providers/chat.dart';
|
import '../providers/chat.dart';
|
||||||
import '../providers/conversation.dart';
|
import '../providers/conversation.dart';
|
||||||
import '../tools/theme_service.dart';
|
import '../tools/theme_service.dart';
|
||||||
|
import '../tools/widget_helpers.dart';
|
||||||
import '../veilid_support/veilid_support.dart';
|
import '../veilid_support/veilid_support.dart';
|
||||||
|
|
||||||
class ChatComponent extends ConsumerStatefulWidget {
|
class ChatComponent extends ConsumerStatefulWidget {
|
||||||
|
@ -32,7 +33,6 @@ class ChatComponent extends ConsumerStatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChatComponentState extends ConsumerState<ChatComponent> {
|
class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
List<types.Message> _messages = [];
|
|
||||||
final _unfocusNode = FocusNode();
|
final _unfocusNode = FocusNode();
|
||||||
late final types.User _localUser;
|
late final types.User _localUser;
|
||||||
late final types.User _remoteUser;
|
late final types.User _remoteUser;
|
||||||
|
@ -52,8 +52,6 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
widget.activeChatContact.identityPublicKey)
|
widget.activeChatContact.identityPublicKey)
|
||||||
.toString(),
|
.toString(),
|
||||||
firstName: widget.activeChatContact.remoteProfile.name);
|
firstName: widget.activeChatContact.remoteProfile.name);
|
||||||
|
|
||||||
unawaited(_loadMessages());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -62,29 +60,6 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
externalize messages so they auto refresh and fix speed.
|
|
||||||
|
|
||||||
Future<void> _loadMessages() async {
|
|
||||||
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
|
||||||
widget.activeChatContact.localConversationRecordKey);
|
|
||||||
final remoteIdentityPublicKey = proto.TypedKeyProto.fromProto(
|
|
||||||
widget.activeChatContact.identityPublicKey);
|
|
||||||
final protoMessages = await getLocalConversationMessages(
|
|
||||||
activeAccountInfo: widget.activeAccountInfo,
|
|
||||||
localConversationRecordKey: localConversationRecordKey,
|
|
||||||
remoteIdentityPublicKey: remoteIdentityPublicKey);
|
|
||||||
if (protoMessages == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_messages = [];
|
|
||||||
for (final protoMessage in protoMessages) {
|
|
||||||
final message = protoMessageToMessage(protoMessage);
|
|
||||||
_messages.insert(0, message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
types.Message protoMessageToMessage(proto.Message message) {
|
types.Message protoMessageToMessage(proto.Message message) {
|
||||||
final isLocal = message.author ==
|
final isLocal = message.author ==
|
||||||
widget.activeAccountInfo.localAccount.identityMaster
|
widget.activeAccountInfo.localAccount.identityMaster
|
||||||
|
@ -107,9 +82,9 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
|
|
||||||
final message = protoMessageToMessage(protoMessage);
|
final message = protoMessageToMessage(protoMessage);
|
||||||
|
|
||||||
setState(() {
|
// setState(() {
|
||||||
_messages.insert(0, message);
|
// _messages.insert(0, message);
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Now add the message to the conversation messages
|
// Now add the message to the conversation messages
|
||||||
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||||
|
@ -122,6 +97,8 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
localConversationRecordKey: localConversationRecordKey,
|
localConversationRecordKey: localConversationRecordKey,
|
||||||
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||||
message: protoMessage);
|
message: protoMessage);
|
||||||
|
|
||||||
|
ref.invalidate(activeConversationMessagesProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _handleSendPressed(types.PartialText message) async {
|
Future<void> _handleSendPressed(types.PartialText message) async {
|
||||||
|
@ -149,6 +126,17 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
final contactName = widget.activeChatContact.editedProfile.name;
|
final contactName = widget.activeChatContact.editedProfile.name;
|
||||||
|
|
||||||
|
final protoMessages =
|
||||||
|
ref.watch(activeConversationMessagesProvider).asData?.value;
|
||||||
|
if (protoMessages == null) {
|
||||||
|
return waitingPage(context);
|
||||||
|
}
|
||||||
|
final messages = <types.Message>[];
|
||||||
|
for (final protoMessage in protoMessages) {
|
||||||
|
final message = protoMessageToMessage(protoMessage);
|
||||||
|
messages.insert(0, message);
|
||||||
|
}
|
||||||
|
|
||||||
return DefaultTextStyle(
|
return DefaultTextStyle(
|
||||||
style: textTheme.bodySmall!,
|
style: textTheme.bodySmall!,
|
||||||
child: Align(
|
child: Align(
|
||||||
|
@ -185,7 +173,7 @@ class ChatComponentState extends ConsumerState<ChatComponent> {
|
||||||
decoration: const BoxDecoration(),
|
decoration: const BoxDecoration(),
|
||||||
child: Chat(
|
child: Chat(
|
||||||
theme: chatTheme,
|
theme: chatTheme,
|
||||||
messages: _messages,
|
messages: messages,
|
||||||
//onAttachmentPressed: _handleAttachmentPressed,
|
//onAttachmentPressed: _handleAttachmentPressed,
|
||||||
//onMessageTap: _handleMessageTap,
|
//onMessageTap: _handleMessageTap,
|
||||||
//onPreviewDataFetched: _handlePreviewDataFetched,
|
//onPreviewDataFetched: _handlePreviewDataFetched,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||||
import 'package:basic_utils/basic_utils.dart';
|
import 'package:basic_utils/basic_utils.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -76,13 +77,12 @@ class ContactInvitationDisplayDialogState
|
||||||
final textTheme = theme.textTheme;
|
final textTheme = theme.textTheme;
|
||||||
|
|
||||||
final signedContactInvitationBytesV = ref.watch(_generateFutureProvider);
|
final signedContactInvitationBytesV = ref.watch(_generateFutureProvider);
|
||||||
final cardsize = MediaQuery.of(context).size.shortestSide - 24;
|
final cardsize = MediaQuery.of(context).size.shortestSide - 48;
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
child: SizedBox(
|
child: FittedBox(
|
||||||
width: cardsize,
|
fit: BoxFit.scaleDown,
|
||||||
height: cardsize,
|
|
||||||
child: signedContactInvitationBytesV.when(
|
child: signedContactInvitationBytesV.when(
|
||||||
loading: () => waitingPage(context),
|
loading: () => waitingPage(context),
|
||||||
data: (data) {
|
data: (data) {
|
||||||
|
@ -96,16 +96,16 @@ class ContactInvitationDisplayDialogState
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
|
FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: Text(
|
||||||
|
translate(
|
||||||
|
'send_invite_dialog.contact_invitation'),
|
||||||
|
style: textTheme.headlineMedium!
|
||||||
|
.copyWith(color: Colors.black)))
|
||||||
|
.paddingAll(8),
|
||||||
FittedBox(
|
FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Text(
|
|
||||||
translate(
|
|
||||||
'send_invite_dialog.contact_invitation'),
|
|
||||||
style: textTheme.headlineMedium!
|
|
||||||
.copyWith(color: Colors.black))),
|
|
||||||
ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(
|
|
||||||
minWidth: 300, minHeight: 300),
|
|
||||||
child: QrImageView.withQr(
|
child: QrImageView.withQr(
|
||||||
size: 300,
|
size: 300,
|
||||||
qr: QrCode.fromUint8List(
|
qr: QrCode.fromUint8List(
|
||||||
|
@ -113,11 +113,12 @@ class ContactInvitationDisplayDialogState
|
||||||
errorCorrectLevel:
|
errorCorrectLevel:
|
||||||
QrErrorCorrectLevel.L))),
|
QrErrorCorrectLevel.L))),
|
||||||
FittedBox(
|
FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Text(widget.message,
|
child: Text(widget.message,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
style: textTheme.headlineSmall!
|
style: textTheme.headlineSmall!
|
||||||
.copyWith(color: Colors.black))),
|
.copyWith(color: Colors.black)))
|
||||||
|
.paddingAll(8),
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
icon: const Icon(Icons.copy),
|
icon: const Icon(Icons.copy),
|
||||||
label: Text(translate(
|
label: Text(translate(
|
||||||
|
@ -131,7 +132,7 @@ class ContactInvitationDisplayDialogState
|
||||||
text:
|
text:
|
||||||
makeTextInvite(widget.message, data)));
|
makeTextInvite(widget.message, data)));
|
||||||
},
|
},
|
||||||
),
|
).paddingAll(8),
|
||||||
]));
|
]));
|
||||||
},
|
},
|
||||||
error: (e, s) {
|
error: (e, s) {
|
||||||
|
|
|
@ -114,9 +114,12 @@ class ContactInvitationItemWidget extends ConsumerWidget {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
subtitle: Text(contactInvitationRecord.message.isEmpty
|
title: Text(
|
||||||
? translate('contact_list.invitation')
|
contactInvitationRecord.message.isEmpty
|
||||||
: contactInvitationRecord.message),
|
? translate('contact_list.invitation')
|
||||||
|
: contactInvitationRecord.message,
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
iconColor: scale.tertiaryScale.background,
|
iconColor: scale.tertiaryScale.background,
|
||||||
textColor: scale.tertiaryScale.text,
|
textColor: scale.tertiaryScale.text,
|
||||||
//Text(Timestamp.fromInt64(contactInvitationRecord.expiration) / ),
|
//Text(Timestamp.fromInt64(contactInvitationRecord.expiration) / ),
|
||||||
|
|
|
@ -143,7 +143,7 @@ class SendInviteDialogState extends ConsumerState<SendInviteDialog> {
|
||||||
TextField(
|
TextField(
|
||||||
controller: _messageTextController,
|
controller: _messageTextController,
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
LengthLimitingTextInputFormatter(256),
|
LengthLimitingTextInputFormatter(128),
|
||||||
],
|
],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
import '../entities/identity.dart';
|
import '../entities/identity.dart';
|
||||||
import '../entities/proto.dart' as proto;
|
import '../entities/proto.dart' as proto;
|
||||||
import '../entities/proto.dart' show Conversation;
|
import '../entities/proto.dart' show Conversation, Message;
|
||||||
|
|
||||||
import '../log/loggy.dart';
|
import '../log/loggy.dart';
|
||||||
|
import '../tools/external_stream_state.dart';
|
||||||
import '../veilid_support/veilid_support.dart';
|
import '../veilid_support/veilid_support.dart';
|
||||||
import 'account.dart';
|
import 'account.dart';
|
||||||
|
import 'chat.dart';
|
||||||
|
import 'contact.dart';
|
||||||
|
|
||||||
//part 'conversation.g.dart';
|
part 'conversation.g.dart';
|
||||||
|
|
||||||
Future<DHTRecordCrypto> getConversationCrypto({
|
Future<DHTRecordCrypto> getConversationCrypto({
|
||||||
required ActiveAccountInfo activeAccountInfo,
|
required ActiveAccountInfo activeAccountInfo,
|
||||||
|
@ -173,7 +178,7 @@ Future<void> addLocalConversationMessage(
|
||||||
{required ActiveAccountInfo activeAccountInfo,
|
{required ActiveAccountInfo activeAccountInfo,
|
||||||
required TypedKey localConversationRecordKey,
|
required TypedKey localConversationRecordKey,
|
||||||
required TypedKey remoteIdentityPublicKey,
|
required TypedKey remoteIdentityPublicKey,
|
||||||
required proto.Message message}) async {
|
required Message message}) async {
|
||||||
final conversation = await readLocalConversation(
|
final conversation = await readLocalConversation(
|
||||||
activeAccountInfo: activeAccountInfo,
|
activeAccountInfo: activeAccountInfo,
|
||||||
localConversationRecordKey: localConversationRecordKey,
|
localConversationRecordKey: localConversationRecordKey,
|
||||||
|
@ -199,7 +204,7 @@ Future<bool> mergeLocalConversationMessages(
|
||||||
{required ActiveAccountInfo activeAccountInfo,
|
{required ActiveAccountInfo activeAccountInfo,
|
||||||
required TypedKey localConversationRecordKey,
|
required TypedKey localConversationRecordKey,
|
||||||
required TypedKey remoteIdentityPublicKey,
|
required TypedKey remoteIdentityPublicKey,
|
||||||
required IList<proto.Message> newMessages}) async {
|
required IList<Message> newMessages}) async {
|
||||||
final conversation = await readLocalConversation(
|
final conversation = await readLocalConversation(
|
||||||
activeAccountInfo: activeAccountInfo,
|
activeAccountInfo: activeAccountInfo,
|
||||||
localConversationRecordKey: localConversationRecordKey,
|
localConversationRecordKey: localConversationRecordKey,
|
||||||
|
@ -207,7 +212,7 @@ Future<bool> mergeLocalConversationMessages(
|
||||||
if (conversation == null) {
|
if (conversation == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool changed = false;
|
var changed = false;
|
||||||
final messagesRecordKey =
|
final messagesRecordKey =
|
||||||
proto.TypedKeyProto.fromProto(conversation.messages);
|
proto.TypedKeyProto.fromProto(conversation.messages);
|
||||||
final crypto = await getConversationCrypto(
|
final crypto = await getConversationCrypto(
|
||||||
|
@ -260,7 +265,7 @@ Future<bool> mergeLocalConversationMessages(
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<IList<proto.Message>?> getLocalConversationMessages({
|
Future<IList<Message>?> getLocalConversationMessages({
|
||||||
required ActiveAccountInfo activeAccountInfo,
|
required ActiveAccountInfo activeAccountInfo,
|
||||||
required TypedKey localConversationRecordKey,
|
required TypedKey localConversationRecordKey,
|
||||||
required TypedKey remoteIdentityPublicKey,
|
required TypedKey remoteIdentityPublicKey,
|
||||||
|
@ -281,9 +286,9 @@ Future<IList<proto.Message>?> getLocalConversationMessages({
|
||||||
return (await DHTShortArray.openRead(messagesRecordKey,
|
return (await DHTShortArray.openRead(messagesRecordKey,
|
||||||
parent: localConversationRecordKey, crypto: crypto))
|
parent: localConversationRecordKey, crypto: crypto))
|
||||||
.scope((messages) async {
|
.scope((messages) async {
|
||||||
var out = IList<proto.Message>();
|
var out = IList<Message>();
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (var i = 0; i < messages.length; i++) {
|
||||||
final msg = await messages.getItemProtobuf(proto.Message.fromBuffer, i);
|
final msg = await messages.getItemProtobuf(Message.fromBuffer, i);
|
||||||
if (msg == null) {
|
if (msg == null) {
|
||||||
throw Exception('Failed to get message');
|
throw Exception('Failed to get message');
|
||||||
}
|
}
|
||||||
|
@ -293,7 +298,7 @@ Future<IList<proto.Message>?> getLocalConversationMessages({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<IList<proto.Message>?> getRemoteConversationMessages({
|
Future<IList<Message>?> getRemoteConversationMessages({
|
||||||
required ActiveAccountInfo activeAccountInfo,
|
required ActiveAccountInfo activeAccountInfo,
|
||||||
required TypedKey remoteConversationRecordKey,
|
required TypedKey remoteConversationRecordKey,
|
||||||
required TypedKey remoteIdentityPublicKey,
|
required TypedKey remoteIdentityPublicKey,
|
||||||
|
@ -314,9 +319,9 @@ Future<IList<proto.Message>?> getRemoteConversationMessages({
|
||||||
return (await DHTShortArray.openRead(messagesRecordKey,
|
return (await DHTShortArray.openRead(messagesRecordKey,
|
||||||
parent: remoteConversationRecordKey, crypto: crypto))
|
parent: remoteConversationRecordKey, crypto: crypto))
|
||||||
.scope((messages) async {
|
.scope((messages) async {
|
||||||
var out = IList<proto.Message>();
|
var out = IList<Message>();
|
||||||
for (var i = 0; i < messages.length; i++) {
|
for (var i = 0; i < messages.length; i++) {
|
||||||
final msg = await messages.getItemProtobuf(proto.Message.fromBuffer, i);
|
final msg = await messages.getItemProtobuf(Message.fromBuffer, i);
|
||||||
if (msg == null) {
|
if (msg == null) {
|
||||||
throw Exception('Failed to get message');
|
throw Exception('Failed to get message');
|
||||||
}
|
}
|
||||||
|
@ -325,3 +330,46 @@ Future<IList<proto.Message>?> getRemoteConversationMessages({
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
class ActiveConversationMessages extends _$ActiveConversationMessages {
|
||||||
|
/// Get message for active converation
|
||||||
|
@override
|
||||||
|
FutureOr<IList<Message>?> build() async {
|
||||||
|
final activeChat = activeChatState.currentState;
|
||||||
|
if (activeChat == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final activeAccountInfo =
|
||||||
|
await ref.watch(fetchActiveAccountProvider.future);
|
||||||
|
if (activeAccountInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final contactList = ref.watch(fetchContactListProvider).asData?.value ??
|
||||||
|
const IListConst([]);
|
||||||
|
|
||||||
|
final activeChatContactIdx = contactList.indexWhere(
|
||||||
|
(c) =>
|
||||||
|
proto.TypedKeyProto.fromProto(c.remoteConversationRecordKey) ==
|
||||||
|
activeChat,
|
||||||
|
);
|
||||||
|
if (activeChatContactIdx == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final activeChatContact = contactList[activeChatContactIdx];
|
||||||
|
final remoteIdentityPublicKey =
|
||||||
|
proto.TypedKeyProto.fromProto(activeChatContact.identityPublicKey);
|
||||||
|
// final remoteConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||||
|
// activeChatContact.remoteConversationRecordKey);
|
||||||
|
final localConversationRecordKey = proto.TypedKeyProto.fromProto(
|
||||||
|
activeChatContact.localConversationRecordKey);
|
||||||
|
|
||||||
|
return await getLocalConversationMessages(
|
||||||
|
activeAccountInfo: activeAccountInfo,
|
||||||
|
localConversationRecordKey: localConversationRecordKey,
|
||||||
|
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
lib/providers/conversation.g.dart
Normal file
27
lib/providers/conversation.g.dart
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'conversation.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$activeConversationMessagesHash() =>
|
||||||
|
r'd65cd8bf71122806320325e7f0e5f8e751d13b55';
|
||||||
|
|
||||||
|
/// See also [ActiveConversationMessages].
|
||||||
|
@ProviderFor(ActiveConversationMessages)
|
||||||
|
final activeConversationMessagesProvider = AutoDisposeAsyncNotifierProvider<
|
||||||
|
ActiveConversationMessages, IList<Message>?>.internal(
|
||||||
|
ActiveConversationMessages.new,
|
||||||
|
name: r'activeConversationMessagesProvider',
|
||||||
|
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$activeConversationMessagesHash,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef _$ActiveConversationMessages
|
||||||
|
= AutoDisposeAsyncNotifier<IList<Message>?>;
|
||||||
|
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
|
@ -6,7 +6,7 @@ part of 'router_notifier.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$routerNotifierHash() => r'8e7b9debfa144253e25871edf920bf315f28a861';
|
String _$routerNotifierHash() => r'6493fee7e11afead973a5bece304b3c94f7fa1c6';
|
||||||
|
|
||||||
/// See also [RouterNotifier].
|
/// See also [RouterNotifier].
|
||||||
@ProviderFor(RouterNotifier)
|
@ProviderFor(RouterNotifier)
|
||||||
|
|
|
@ -155,11 +155,14 @@ class BackgroundTickerState extends ConsumerState<BackgroundTicker> {
|
||||||
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||||
remoteConversationRecordKey: remoteConversationRecordKey);
|
remoteConversationRecordKey: remoteConversationRecordKey);
|
||||||
if (newMessages != null) {
|
if (newMessages != null) {
|
||||||
await mergeLocalConversationMessages(
|
final changed = await mergeLocalConversationMessages(
|
||||||
activeAccountInfo: activeAccountInfo,
|
activeAccountInfo: activeAccountInfo,
|
||||||
localConversationRecordKey: localConversationRecordKey,
|
localConversationRecordKey: localConversationRecordKey,
|
||||||
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
remoteIdentityPublicKey: remoteIdentityPublicKey,
|
||||||
newMessages: newMessages);
|
newMessages: newMessages);
|
||||||
|
if (changed) {
|
||||||
|
ref.invalidate(activeConversationMessagesProvider);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:charcode/charcode.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
Future<VeilidConfig> getVeilidChatConfig() async {
|
Future<VeilidConfig> getVeilidChatConfig() async {
|
||||||
|
@ -18,5 +19,14 @@ Future<VeilidConfig> getVeilidChatConfig() async {
|
||||||
config.copyWith(blockStore: config.blockStore.copyWith(delete: true));
|
config.copyWith(blockStore: config.blockStore.copyWith(delete: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// xxx hack
|
||||||
|
config = config.copyWith(
|
||||||
|
network: config.network.copyWith(
|
||||||
|
dht: config.network.dht.copyWith(
|
||||||
|
getValueCount: 2,
|
||||||
|
getValueTimeoutMs: 5000,
|
||||||
|
setValueCount: 2,
|
||||||
|
setValueTimeoutMs: 5000)));
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: veilidchat
|
name: veilidchat
|
||||||
description: VeilidChat
|
description: VeilidChat
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.0.0+1
|
version: 1.0.1+2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.0.5 <4.0.0'
|
sdk: '>=3.0.5 <4.0.0'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue