fix callback issue and increase minimum threshold

This commit is contained in:
otsmr 2026-06-07 12:10:10 +02:00
parent da97fe5f3d
commit d1eb5d5be6
17 changed files with 243 additions and 96 deletions

View file

@ -1,5 +1,9 @@
# Changelog # Changelog
## 0.2.30
- Fix: Changed minimum threshold for the user discovery to 3
## 0.2.28 ## 0.2.28
- Improved: Design of some UI components - Improved: Design of some UI components

View file

@ -9,8 +9,10 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
// These functions are ignored because they are not marked as `pub`: `get_callbacks` // These functions are ignored because they are not marked as `pub`: `get_callbacks`
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `FlutterCallbacks`, `Logging`, `UserDiscoveryCallbacks` // These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `FlutterCallbacks`, `Logging`, `UserDiscoveryCallbacks`
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `clone`
Future<void> initFlutterCallbacks({ Future<void> initFlutterCallbacks({
required int callbackId,
required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink, required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink,
required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData, required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData,
required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List) required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List)
@ -39,6 +41,7 @@ Future<void> initFlutterCallbacks({
required FutureOr<Uint8List?> Function(PlatformInt64) required FutureOr<Uint8List?> Function(PlatformInt64)
userDiscoveryGetContactPromotion, userDiscoveryGetContactPromotion,
}) => RustLib.instance.api.crateBridgeCallbacksInitFlutterCallbacks( }) => RustLib.instance.api.crateBridgeCallbacksInitFlutterCallbacks(
callbackId: callbackId,
loggingGetStreamSink: loggingGetStreamSink, loggingGetStreamSink: loggingGetStreamSink,
userDiscoverySignData: userDiscoverySignData, userDiscoverySignData: userDiscoverySignData,
userDiscoveryVerifySignature: userDiscoveryVerifySignature, userDiscoveryVerifySignature: userDiscoveryVerifySignature,

View file

@ -9,36 +9,45 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
class FlutterUserDiscovery { class FlutterUserDiscovery {
const FlutterUserDiscovery(); const FlutterUserDiscovery();
static Future<Uint8List> getCurrentVersion() => RustLib.instance.api static Future<Uint8List> getCurrentVersion({required int callbackId}) =>
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion(); RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion(
callbackId: callbackId,
);
static Future<List<Uint8List>> getNewMessages({ static Future<List<Uint8List>> getNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> receivedVersion, required List<int> receivedVersion,
}) => RustLib.instance.api }) => RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages( .crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages(
callbackId: callbackId,
contactId: contactId, contactId: contactId,
receivedVersion: receivedVersion, receivedVersion: receivedVersion,
); );
static Future<void> handleNewMessages({ static Future<void> handleNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
required List<Uint8List> messages, required List<Uint8List> messages,
}) => RustLib.instance.api }) => RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages( .crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages(
callbackId: callbackId,
contactId: contactId, contactId: contactId,
publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp, publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp,
messages: messages, messages: messages,
); );
static Future<void> initializeOrUpdate({ static Future<void> initializeOrUpdate({
required int callbackId,
required int threshold, required int threshold,
required PlatformInt64 userId, required PlatformInt64 userId,
required List<int> publicKey, required List<int> publicKey,
required bool sharePromotion, required bool sharePromotion,
}) => RustLib.instance.api }) => RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate( .crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate(
callbackId: callbackId,
threshold: threshold, threshold: threshold,
userId: userId, userId: userId,
publicKey: publicKey, publicKey: publicKey,
@ -46,19 +55,23 @@ class FlutterUserDiscovery {
); );
static Future<Uint8List?> shouldRequestNewMessages({ static Future<Uint8List?> shouldRequestNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> version, required List<int> version,
}) => RustLib.instance.api }) => RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages( .crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages(
callbackId: callbackId,
contactId: contactId, contactId: contactId,
version: version, version: version,
); );
static Future<void> updateVerificationStateForUser({ static Future<void> updateVerificationStateForUser({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
}) => RustLib.instance.api }) => RustLib.instance.api
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser( .crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser(
callbackId: callbackId,
contactId: contactId, contactId: contactId,
publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp, publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp,
); );

View file

@ -87,16 +87,20 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
abstract class RustLibApi extends BaseApi { abstract class RustLibApi extends BaseApi {
Future<Uint8List> Future<Uint8List>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion(); crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion({
required int callbackId,
});
Future<List<Uint8List>> Future<List<Uint8List>>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> receivedVersion, required List<int> receivedVersion,
}); });
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
required List<Uint8List> messages, required List<Uint8List> messages,
@ -104,6 +108,7 @@ abstract class RustLibApi extends BaseApi {
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate({
required int callbackId,
required int threshold, required int threshold,
required PlatformInt64 userId, required PlatformInt64 userId,
required List<int> publicKey, required List<int> publicKey,
@ -112,17 +117,20 @@ abstract class RustLibApi extends BaseApi {
Future<Uint8List?> Future<Uint8List?>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> version, required List<int> version,
}); });
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
}); });
Future<void> crateBridgeCallbacksInitFlutterCallbacks({ Future<void> crateBridgeCallbacksInitFlutterCallbacks({
required int callbackId,
required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink, required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink,
required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData, required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData,
required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List) required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List)
@ -242,11 +250,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@override @override
Future<Uint8List> Future<Uint8List>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion() { crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersion({
required int callbackId,
}) {
return handler.executeNormal( return handler.executeNormal(
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
pdeCallFfi( pdeCallFfi(
generalizedFrbRustBinding, generalizedFrbRustBinding,
serializer, serializer,
@ -260,7 +271,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersionConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersionConstMeta,
argValues: [], argValues: [callbackId],
apiImpl: this, apiImpl: this,
), ),
); );
@ -270,12 +281,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersionConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetCurrentVersionConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_get_current_version", debugName: "flutter_user_discovery_get_current_version",
argNames: [], argNames: ["callbackId"],
); );
@override @override
Future<List<Uint8List>> Future<List<Uint8List>>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> receivedVersion, required List<int> receivedVersion,
}) { }) {
@ -283,6 +295,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_i_64(contactId, serializer); sse_encode_i_64(contactId, serializer);
sse_encode_list_prim_u_8_loose(receivedVersion, serializer); sse_encode_list_prim_u_8_loose(receivedVersion, serializer);
pdeCallFfi( pdeCallFfi(
@ -298,7 +311,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessagesConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessagesConstMeta,
argValues: [contactId, receivedVersion], argValues: [callbackId, contactId, receivedVersion],
apiImpl: this, apiImpl: this,
), ),
); );
@ -308,12 +321,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessagesConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryGetNewMessagesConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_get_new_messages", debugName: "flutter_user_discovery_get_new_messages",
argNames: ["contactId", "receivedVersion"], argNames: ["callbackId", "contactId", "receivedVersion"],
); );
@override @override
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
required List<Uint8List> messages, required List<Uint8List> messages,
@ -322,6 +336,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_i_64(contactId, serializer); sse_encode_i_64(contactId, serializer);
sse_encode_opt_box_autoadd_i_64( sse_encode_opt_box_autoadd_i_64(
publicKeyVerifiedTimestamp, publicKeyVerifiedTimestamp,
@ -341,7 +356,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta,
argValues: [contactId, publicKeyVerifiedTimestamp, messages], argValues: [
callbackId,
contactId,
publicKeyVerifiedTimestamp,
messages,
],
apiImpl: this, apiImpl: this,
), ),
); );
@ -351,12 +371,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_handle_new_messages", debugName: "flutter_user_discovery_handle_new_messages",
argNames: ["contactId", "publicKeyVerifiedTimestamp", "messages"], argNames: [
"callbackId",
"contactId",
"publicKeyVerifiedTimestamp",
"messages",
],
); );
@override @override
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdate({
required int callbackId,
required int threshold, required int threshold,
required PlatformInt64 userId, required PlatformInt64 userId,
required List<int> publicKey, required List<int> publicKey,
@ -366,6 +392,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_u_8(threshold, serializer); sse_encode_u_8(threshold, serializer);
sse_encode_i_64(userId, serializer); sse_encode_i_64(userId, serializer);
sse_encode_list_prim_u_8_loose(publicKey, serializer); sse_encode_list_prim_u_8_loose(publicKey, serializer);
@ -383,7 +410,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdateConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdateConstMeta,
argValues: [threshold, userId, publicKey, sharePromotion], argValues: [callbackId, threshold, userId, publicKey, sharePromotion],
apiImpl: this, apiImpl: this,
), ),
); );
@ -393,12 +420,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdateConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryInitializeOrUpdateConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_initialize_or_update", debugName: "flutter_user_discovery_initialize_or_update",
argNames: ["threshold", "userId", "publicKey", "sharePromotion"], argNames: [
"callbackId",
"threshold",
"userId",
"publicKey",
"sharePromotion",
],
); );
@override @override
Future<Uint8List?> Future<Uint8List?>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
required List<int> version, required List<int> version,
}) { }) {
@ -406,6 +440,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_i_64(contactId, serializer); sse_encode_i_64(contactId, serializer);
sse_encode_list_prim_u_8_loose(version, serializer); sse_encode_list_prim_u_8_loose(version, serializer);
pdeCallFfi( pdeCallFfi(
@ -421,7 +456,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessagesConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessagesConstMeta,
argValues: [contactId, version], argValues: [callbackId, contactId, version],
apiImpl: this, apiImpl: this,
), ),
); );
@ -431,12 +466,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessagesConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessagesConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_should_request_new_messages", debugName: "flutter_user_discovery_should_request_new_messages",
argNames: ["contactId", "version"], argNames: ["callbackId", "contactId", "version"],
); );
@override @override
Future<void> Future<void>
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser({ crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUser({
required int callbackId,
required PlatformInt64 contactId, required PlatformInt64 contactId,
PlatformInt64? publicKeyVerifiedTimestamp, PlatformInt64? publicKeyVerifiedTimestamp,
}) { }) {
@ -444,6 +480,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_i_64(contactId, serializer); sse_encode_i_64(contactId, serializer);
sse_encode_opt_box_autoadd_i_64( sse_encode_opt_box_autoadd_i_64(
publicKeyVerifiedTimestamp, publicKeyVerifiedTimestamp,
@ -462,7 +499,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: constMeta:
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUserConstMeta, kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUserConstMeta,
argValues: [contactId, publicKeyVerifiedTimestamp], argValues: [callbackId, contactId, publicKeyVerifiedTimestamp],
apiImpl: this, apiImpl: this,
), ),
); );
@ -472,11 +509,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUserConstMeta => get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryUpdateVerificationStateForUserConstMeta =>
const TaskConstMeta( const TaskConstMeta(
debugName: "flutter_user_discovery_update_verification_state_for_user", debugName: "flutter_user_discovery_update_verification_state_for_user",
argNames: ["contactId", "publicKeyVerifiedTimestamp"], argNames: ["callbackId", "contactId", "publicKeyVerifiedTimestamp"],
); );
@override @override
Future<void> crateBridgeCallbacksInitFlutterCallbacks({ Future<void> crateBridgeCallbacksInitFlutterCallbacks({
required int callbackId,
required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink, required FutureOr<RustStreamSink<String>> Function() loggingGetStreamSink,
required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData, required FutureOr<Uint8List?> Function(Uint8List) userDiscoverySignData,
required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List) required FutureOr<bool> Function(Uint8List, Uint8List, Uint8List)
@ -513,6 +551,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
NormalTask( NormalTask(
callFfi: (port_) { callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding); final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_u_32(callbackId, serializer);
sse_encode_DartFn_Inputs__Output_StreamSink_String_Sse_AnyhowException( sse_encode_DartFn_Inputs__Output_StreamSink_String_Sse_AnyhowException(
loggingGetStreamSink, loggingGetStreamSink,
serializer, serializer,
@ -586,6 +625,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
), ),
constMeta: kCrateBridgeCallbacksInitFlutterCallbacksConstMeta, constMeta: kCrateBridgeCallbacksInitFlutterCallbacksConstMeta,
argValues: [ argValues: [
callbackId,
loggingGetStreamSink, loggingGetStreamSink,
userDiscoverySignData, userDiscoverySignData,
userDiscoveryVerifySignature, userDiscoveryVerifySignature,
@ -611,6 +651,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
const TaskConstMeta( const TaskConstMeta(
debugName: "init_flutter_callbacks", debugName: "init_flutter_callbacks",
argNames: [ argNames: [
"callbackId",
"loggingGetStreamSink", "loggingGetStreamSink",
"userDiscoverySignData", "userDiscoverySignData",
"userDiscoveryVerifySignature", "userDiscoveryVerifySignature",

View file

@ -1,8 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:math';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
final int isolateCallbackId = Random().nextInt(0x7FFFFFFF);
class AppEnvironment { class AppEnvironment {
static late String cacheDir; static late String cacheDir;
static late String supportDir; static late String supportDir;

View file

@ -1,9 +1,11 @@
import 'package:twonly/core/bridge/callbacks.dart'; import 'package:twonly/core/bridge/callbacks.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/callbacks/logging.callbacks.dart'; import 'package:twonly/src/callbacks/logging.callbacks.dart';
import 'package:twonly/src/callbacks/user_discovery.callbacks.dart'; import 'package:twonly/src/callbacks/user_discovery.callbacks.dart';
Future<void> initFlutterCallbacksForRust() async { Future<void> initFlutterCallbacksForRust() async {
await initFlutterCallbacks( await initFlutterCallbacks(
callbackId: isolateCallbackId,
loggingGetStreamSink: LoggingCallbacks.getStreamSink, loggingGetStreamSink: LoggingCallbacks.getStreamSink,
userDiscoverySetShares: UserDiscoveryCallbacks.setShares, userDiscoverySetShares: UserDiscoveryCallbacks.setShares,
userDiscoveryGetShareForContact: userDiscoveryGetShareForContact:

View file

@ -1,6 +1,7 @@
import 'package:clock/clock.dart'; import 'package:clock/clock.dart';
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:twonly/core/bridge/wrapper/user_discovery.dart'; import 'package:twonly/core/bridge/wrapper/user_discovery.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart'; import 'package:twonly/locator.dart';
import 'package:twonly/src/database/tables/contacts.table.dart'; import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/tables/groups.table.dart'; import 'package:twonly/src/database/tables/groups.table.dart';
@ -216,6 +217,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
); );
if (userService.currentUser.isUserDiscoveryEnabled) { if (userService.currentUser.isUserDiscoveryEnabled) {
await FlutterUserDiscovery.updateVerificationStateForUser( await FlutterUserDiscovery.updateVerificationStateForUser(
callbackId: isolateCallbackId,
contactId: contactId, contactId: contactId,
publicKeyVerifiedTimestamp: clock.now().millisecondsSinceEpoch, publicKeyVerifiedTimestamp: clock.now().millisecondsSinceEpoch,
); );
@ -232,6 +234,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
)..where((kv) => kv.contactId.equals(contactId))).go(); )..where((kv) => kv.contactId.equals(contactId))).go();
if (userService.currentUser.isUserDiscoveryEnabled) { if (userService.currentUser.isUserDiscoveryEnabled) {
await FlutterUserDiscovery.updateVerificationStateForUser( await FlutterUserDiscovery.updateVerificationStateForUser(
callbackId: isolateCallbackId,
contactId: contactId, contactId: contactId,
); );
} }
@ -251,6 +254,7 @@ class KeyVerificationDao extends DatabaseAccessor<TwonlyDB>
final remaining = await getContactVerification(contactId); final remaining = await getContactVerification(contactId);
if (remaining.isEmpty && userService.currentUser.isUserDiscoveryEnabled) { if (remaining.isEmpty && userService.currentUser.isUserDiscoveryEnabled) {
await FlutterUserDiscovery.updateVerificationStateForUser( await FlutterUserDiscovery.updateVerificationStateForUser(
callbackId: isolateCallbackId,
contactId: contactId, contactId: contactId,
); );
} }

View file

@ -114,8 +114,8 @@ class UserData {
@JsonKey(defaultValue: 4) @JsonKey(defaultValue: 4)
int requiredSendImages = 4; int requiredSendImages = 4;
@JsonKey(defaultValue: 2) @JsonKey(defaultValue: 3)
int userDiscoveryThreshold = 2; int userDiscoveryThreshold = 3;
@JsonKey(defaultValue: false) @JsonKey(defaultValue: false)
bool userDiscoveryRequiresManualApproval = false; bool userDiscoveryRequiresManualApproval = false;

View file

@ -62,7 +62,7 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) =>
), ),
) )
..storeMediaFilesInGallery = ..storeMediaFilesInGallery =
json['storeMediaFilesInGallery'] as bool? ?? false json['storeMediaFilesInGallery'] as bool? ?? true
..autoStoreAllSendUnlimitedMediaFiles = ..autoStoreAllSendUnlimitedMediaFiles =
json['autoStoreAllSendUnlimitedMediaFiles'] as bool? ?? false json['autoStoreAllSendUnlimitedMediaFiles'] as bool? ?? false
..typingIndicators = json['typingIndicators'] as bool? ?? true ..typingIndicators = json['typingIndicators'] as bool? ?? true
@ -78,7 +78,7 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) =>
json['isUserDiscoveryEnabled'] as bool? ?? false json['isUserDiscoveryEnabled'] as bool? ?? false
..requiredSendImages = (json['requiredSendImages'] as num?)?.toInt() ?? 4 ..requiredSendImages = (json['requiredSendImages'] as num?)?.toInt() ?? 4
..userDiscoveryThreshold = ..userDiscoveryThreshold =
(json['userDiscoveryThreshold'] as num?)?.toInt() ?? 2 (json['userDiscoveryThreshold'] as num?)?.toInt() ?? 3
..userDiscoveryRequiresManualApproval = ..userDiscoveryRequiresManualApproval =
json['userDiscoveryRequiresManualApproval'] as bool? ?? false json['userDiscoveryRequiresManualApproval'] as bool? ?? false
..userDiscoverySharePromotion = ..userDiscoverySharePromotion =

View file

@ -14,6 +14,7 @@ import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/json/signal_identity.model.dart'; import 'package:twonly/src/model/json/signal_identity.model.dart';
import 'package:twonly/src/services/api/mediafiles/download.api.dart'; import 'package:twonly/src/services/api/mediafiles/download.api.dart';
import 'package:twonly/src/services/user.service.dart'; import 'package:twonly/src/services/user.service.dart';
import 'package:twonly/src/services/user_discovery.service.dart';
import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/secure_storage.dart'; import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/visual/views/onboarding/setup.view.dart'; import 'package:twonly/src/visual/views/onboarding/setup.view.dart';
@ -144,6 +145,19 @@ Future<void> runMigrations() async {
} }
} }
if (userService.currentUser.appVersion < 116) {
if (userService.currentUser.userDiscoveryThreshold == 2) {
if (userService.currentUser.isUserDiscoveryEnabled) {
await UserDiscoveryService.initializeOrUpdate(
threshold: 3,
sharePromotion: userService.currentUser.userDiscoverySharePromotion,
);
} else {
await UserService.update((u) => u..userDiscoveryThreshold = 3);
}
}
await UserService.update((u) => u.appVersion = 116);
}
if (kDebugMode) { if (kDebugMode) {
assert( assert(
AppState.latestAppVersionId == 116, AppState.latestAppVersionId == 116,

View file

@ -84,6 +84,7 @@ class UserDiscoveryService {
final publicKey = await getUserPublicKey(); final publicKey = await getUserPublicKey();
Log.info('UserDiscoveryService: initializing Rust bridge'); Log.info('UserDiscoveryService: initializing Rust bridge');
await FlutterUserDiscovery.initializeOrUpdate( await FlutterUserDiscovery.initializeOrUpdate(
callbackId: isolateCallbackId,
threshold: threshold, threshold: threshold,
userId: userId, userId: userId,
publicKey: publicKey, publicKey: publicKey,
@ -104,7 +105,7 @@ class UserDiscoveryService {
static Future<Uint8List?> getCurrentVersion() async { static Future<Uint8List?> getCurrentVersion() async {
try { try {
return await FlutterUserDiscovery.getCurrentVersion() return await FlutterUserDiscovery.getCurrentVersion(callbackId: isolateCallbackId)
.timeout(const Duration(seconds: 5)); .timeout(const Duration(seconds: 5));
} catch (e) { } catch (e) {
Log.error(e); Log.error(e);
@ -139,6 +140,7 @@ class UserDiscoveryService {
) async { ) async {
try { try {
return await FlutterUserDiscovery.shouldRequestNewMessages( return await FlutterUserDiscovery.shouldRequestNewMessages(
callbackId: isolateCallbackId,
contactId: fromUserId, contactId: fromUserId,
version: receivedVersion, version: receivedVersion,
).timeout(const Duration(seconds: 5)); ).timeout(const Duration(seconds: 5));
@ -154,6 +156,7 @@ class UserDiscoveryService {
) async { ) async {
try { try {
return await FlutterUserDiscovery.getNewMessages( return await FlutterUserDiscovery.getNewMessages(
callbackId: isolateCallbackId,
contactId: fromUserId, contactId: fromUserId,
receivedVersion: receivedVersion, receivedVersion: receivedVersion,
).timeout(const Duration(seconds: 5)); ).timeout(const Duration(seconds: 5));
@ -172,6 +175,7 @@ class UserDiscoveryService {
.getContactVerification(fromUserId); .getContactVerification(fromUserId);
return await FlutterUserDiscovery.handleNewMessages( return await FlutterUserDiscovery.handleNewMessages(
callbackId: isolateCallbackId,
contactId: fromUserId, contactId: fromUserId,
messages: messages, messages: messages,
publicKeyVerifiedTimestamp: publicKeyVerifiedTimestamp:

View file

@ -108,7 +108,8 @@ class UserDiscoverySetupComp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final showShareYourFriends = final showShareYourFriends =
showOnlySpecificPage == UserDiscoveryPages.all || showOnlySpecificPage == UserDiscoveryPages.shareYourFriends; showOnlySpecificPage == UserDiscoveryPages.all ||
showOnlySpecificPage == UserDiscoveryPages.shareYourFriends;
final showLetYourFriendsFindYou = final showLetYourFriendsFindYou =
showOnlySpecificPage == UserDiscoveryPages.all || showOnlySpecificPage == UserDiscoveryPages.all ||
showOnlySpecificPage == UserDiscoveryPages.letYourFriendsFindYou; showOnlySpecificPage == UserDiscoveryPages.letYourFriendsFindYou;
@ -336,7 +337,9 @@ class UserDiscoverySetupComp extends StatelessWidget {
), ),
), ),
subtitle: Text( subtitle: Text(
context.lang.userDiscoverySettingsManualApprovalDesc, context
.lang
.userDiscoverySettingsManualApprovalDesc,
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
color: context.color.onSurfaceVariant, color: context.color.onSurfaceVariant,
@ -350,13 +353,16 @@ class UserDiscoverySetupComp extends StatelessWidget {
), ),
], ],
), ),
crossFadeState: state.isUserDiscoveryEnabled ? CrossFadeState.showSecond : CrossFadeState.showFirst, crossFadeState: state.isUserDiscoveryEnabled
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
), ),
], ],
), ),
), ),
if (showOnlySpecificPage == UserDiscoveryPages.all) const SizedBox(height: 48), if (showOnlySpecificPage == UserDiscoveryPages.all)
const SizedBox(height: 48),
], ],
if (showLetYourFriendsFindYou) ...[ if (showLetYourFriendsFindYou) ...[
Text( Text(
@ -587,7 +593,9 @@ class UserDiscoverySetupComp extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
context.lang.userDiscoverySettingsMutualFriends, context
.lang
.userDiscoverySettingsMutualFriends,
style: const TextStyle( style: const TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -603,7 +611,8 @@ class UserDiscoverySetupComp extends StatelessWidget {
color: context.color.surface, color: context.color.surface,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
color: context.color.outlineVariant.withValues( color: context.color.outlineVariant
.withValues(
alpha: 0.5, alpha: 0.5,
), ),
), ),
@ -616,9 +625,9 @@ class UserDiscoverySetupComp extends StatelessWidget {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
items: List.generate( items: List.generate(
9, 8,
(index) { (index) {
final value = index + 2; final value = index + 3;
return DropdownMenuItem<int>( return DropdownMenuItem<int>(
value: value, value: value,
child: Text('$value'), child: Text('$value'),
@ -640,7 +649,9 @@ class UserDiscoverySetupComp extends StatelessWidget {
), ),
], ],
), ),
crossFadeState: state.sharePromotion ? CrossFadeState.showSecond : CrossFadeState.showFirst, crossFadeState: state.sharePromotion
? CrossFadeState.showSecond
: CrossFadeState.showFirst,
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
), ),
], ],

View file

@ -26,7 +26,7 @@ class _UserDiscoverySettingsViewState extends State<UserDiscoverySettingsView> {
isUserDiscoveryEnabled: u.isUserDiscoveryEnabled, isUserDiscoveryEnabled: u.isUserDiscoveryEnabled,
sharePromotion: u.userDiscoverySharePromotion, sharePromotion: u.userDiscoverySharePromotion,
isManualApprovalEnabled: u.userDiscoveryRequiresManualApproval, isManualApprovalEnabled: u.userDiscoveryRequiresManualApproval,
threshold: u.userDiscoveryThreshold, threshold: u.userDiscoveryThreshold < 3 ? 3 : u.userDiscoveryThreshold,
); );
} }

View file

@ -9,7 +9,13 @@ use crate::error::{Result, TwonlyError};
use crate::{callback_generator, frb_generated::StreamSink}; use crate::{callback_generator, frb_generated::StreamSink};
use std::sync::Arc; use std::sync::Arc;
static FLUTTER_CALLBACKS: std::sync::RwLock<Option<FlutterCallbacks>> = use std::collections::HashMap;
tokio::task_local! {
pub(crate) static CURRENT_CALLBACK_ID: u32;
}
pub(crate) static FLUTTER_CALLBACKS: std::sync::RwLock<Option<HashMap<u32, FlutterCallbacks>>> =
std::sync::RwLock::new(None); std::sync::RwLock::new(None);
// This will also generate the function init_flutter_callbacks which MUST be called from Flutter to initialize the callbacks // This will also generate the function init_flutter_callbacks which MUST be called from Flutter to initialize the callbacks
@ -41,9 +47,24 @@ callback_generator! {
} }
pub(crate) fn get_callbacks() -> Result<FlutterCallbacks> { pub(crate) fn get_callbacks() -> Result<FlutterCallbacks> {
FLUTTER_CALLBACKS let caller_opt = CURRENT_CALLBACK_ID.try_with(|&c| c).ok();
.read()
.unwrap() let lock = FLUTTER_CALLBACKS.read().unwrap();
.clone() let map = lock.as_ref().ok_or(TwonlyError::MissingCallbackInitialization)?;
.ok_or(TwonlyError::MissingCallbackInitialization)
if let Some(id) = caller_opt {
if let Some(cb) = map.get(&id) {
return Ok(cb.clone());
}
}
// Fallback: if not in a scoped tokio task or if the specific callback_id isn't found,
// we pick the first available callbacks from the map. This gracefully handles
// tracing initialization which happens outside of any scoped task.
if let Some((_, cb)) = map.iter().next() {
tracing::error!("FlutterCallbacks fallback used: No CURRENT_CALLBACK_ID scope was found, or the ID was missing from the map. Using an arbitrary callback. This may lead to race conditions if multiple isolates are active.");
return Ok(cb.clone());
}
Err(TwonlyError::MissingCallbackInitialization)
} }

View file

@ -32,6 +32,7 @@ macro_rules! callback_generator {
// 3. Generate the Automated Init Function // 3. Generate the Automated Init Function
paste::paste! { paste::paste! {
pub fn init_flutter_callbacks( pub fn init_flutter_callbacks(
callback_id: u32,
$( $(
$( $(
// Parameters: sub-struct_field + _ + fn_name // Parameters: sub-struct_field + _ + fn_name
@ -49,9 +50,11 @@ macro_rules! callback_generator {
)* )*
}; };
// Use the static global strictly named FLUTTER_CALLBACKS
let mut lock = FLUTTER_CALLBACKS.write().unwrap(); let mut lock = FLUTTER_CALLBACKS.write().unwrap();
*lock = Some(callbacks); if lock.is_none() {
*lock = Some(std::collections::HashMap::new());
}
lock.as_mut().unwrap().insert(callback_id, callbacks);
} }
} }
}; };

View file

@ -1,3 +1,4 @@
use crate::bridge::callbacks::CURRENT_CALLBACK_ID;
use crate::bridge::get_twonly_flutter; use crate::bridge::get_twonly_flutter;
use crate::error::Result; use crate::error::Result;
@ -5,11 +6,13 @@ pub struct FlutterUserDiscovery {}
impl FlutterUserDiscovery { impl FlutterUserDiscovery {
pub async fn initialize_or_update( pub async fn initialize_or_update(
callback_id: u32,
threshold: u8, threshold: u8,
user_id: i64, user_id: i64,
public_key: Vec<u8>, public_key: Vec<u8>,
share_promotion: bool, share_promotion: bool,
) -> Result<()> { ) -> Result<()> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
tracing::info!("Rust bridge: initialize_or_update started"); tracing::info!("Rust bridge: initialize_or_update started");
let twonly = get_twonly_flutter()?; let twonly = get_twonly_flutter()?;
tracing::info!("Rust bridge: getting user_discovery lock"); tracing::info!("Rust bridge: getting user_discovery lock");
@ -20,63 +23,78 @@ impl FlutterUserDiscovery {
.await; .await;
tracing::info!("Rust bridge: initialize_or_update on protocols finished"); tracing::info!("Rust bridge: initialize_or_update on protocols finished");
Ok(res?) Ok(res?)
}).await
} }
pub async fn get_current_version() -> Result<Vec<u8>> { pub async fn get_current_version(callback_id: u32) -> Result<Vec<u8>> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
Ok(get_twonly_flutter()? Ok(get_twonly_flutter()?
.user_discovery .user_discovery
.get() .get()
.await .await
.get_current_version() .get_current_version()
.await?) .await?)
}).await
} }
pub async fn get_new_messages( pub async fn get_new_messages(
callback_id: u32,
contact_id: i64, contact_id: i64,
received_version: &[u8], received_version: &[u8],
) -> Result<Vec<Vec<u8>>> { ) -> Result<Vec<Vec<u8>>> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
Ok(get_twonly_flutter()? Ok(get_twonly_flutter()?
.user_discovery .user_discovery
.get() .get()
.await .await
.get_new_messages(contact_id, received_version) .get_new_messages(contact_id, received_version)
.await?) .await?)
}).await
} }
pub async fn should_request_new_messages( pub async fn should_request_new_messages(
callback_id: u32,
contact_id: i64, contact_id: i64,
version: &[u8], version: &[u8],
) -> Result<Option<Vec<u8>>> { ) -> Result<Option<Vec<u8>>> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
Ok(get_twonly_flutter()? Ok(get_twonly_flutter()?
.user_discovery .user_discovery
.get() .get()
.await .await
.should_request_new_messages(contact_id, version) .should_request_new_messages(contact_id, version)
.await?) .await?)
}).await
} }
pub async fn handle_new_messages( pub async fn handle_new_messages(
callback_id: u32,
contact_id: i64, contact_id: i64,
public_key_verified_timestamp: Option<i64>, public_key_verified_timestamp: Option<i64>,
messages: Vec<Vec<u8>>, messages: Vec<Vec<u8>>,
) -> Result<()> { ) -> Result<()> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
Ok(get_twonly_flutter()? Ok(get_twonly_flutter()?
.user_discovery .user_discovery
.get() .get()
.await .await
.handle_new_messages(contact_id, public_key_verified_timestamp, messages) .handle_new_messages(contact_id, public_key_verified_timestamp, messages)
.await?) .await?)
}).await
} }
pub async fn update_verification_state_for_user( pub async fn update_verification_state_for_user(
callback_id: u32,
contact_id: i64, contact_id: i64,
public_key_verified_timestamp: Option<i64>, public_key_verified_timestamp: Option<i64>,
) -> Result<()> { ) -> Result<()> {
CURRENT_CALLBACK_ID.scope(callback_id, async move {
Ok(get_twonly_flutter()? Ok(get_twonly_flutter()?
.user_discovery .user_discovery
.get() .get()
.await .await
.update_verification_state_for_user(contact_id, public_key_verified_timestamp) .update_verification_state_for_user(contact_id, public_key_verified_timestamp)
.await?) .await?)
}).await
} }
} }

View file

@ -55,9 +55,9 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_curr
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_get_current_version", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_get_current_version", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
deserializer.end(); move |context| async move { let api_callback_id = <u32>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::get_current_version().await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::get_current_version(api_callback_id).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -70,10 +70,11 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_new_
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_get_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_get_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_contact_id = <i64>::sse_decode(&mut deserializer); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_contact_id = <i64>::sse_decode(&mut deserializer);
let api_received_version = <Vec<u8>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move { let api_received_version = <Vec<u8>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::get_new_messages(api_contact_id, &api_received_version).await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::get_new_messages(api_callback_id, api_contact_id, &api_received_version).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -86,11 +87,12 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_handle_n
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_handle_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_handle_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_contact_id = <i64>::sse_decode(&mut deserializer); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_contact_id = <i64>::sse_decode(&mut deserializer);
let api_public_key_verified_timestamp = <Option<i64>>::sse_decode(&mut deserializer); let api_public_key_verified_timestamp = <Option<i64>>::sse_decode(&mut deserializer);
let api_messages = <Vec<Vec<u8>>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move { let api_messages = <Vec<Vec<u8>>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::handle_new_messages(api_contact_id, api_public_key_verified_timestamp, api_messages).await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::handle_new_messages(api_callback_id, api_contact_id, api_public_key_verified_timestamp, api_messages).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -103,12 +105,13 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_initiali
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_initialize_or_update", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_initialize_or_update", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_threshold = <u8>::sse_decode(&mut deserializer); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_threshold = <u8>::sse_decode(&mut deserializer);
let api_user_id = <i64>::sse_decode(&mut deserializer); let api_user_id = <i64>::sse_decode(&mut deserializer);
let api_public_key = <Vec<u8>>::sse_decode(&mut deserializer); let api_public_key = <Vec<u8>>::sse_decode(&mut deserializer);
let api_share_promotion = <bool>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move { let api_share_promotion = <bool>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::initialize_or_update(api_threshold, api_user_id, api_public_key, api_share_promotion).await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::initialize_or_update(api_callback_id, api_threshold, api_user_id, api_public_key, api_share_promotion).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -121,10 +124,11 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_should_r
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_should_request_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_should_request_new_messages", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_contact_id = <i64>::sse_decode(&mut deserializer); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_contact_id = <i64>::sse_decode(&mut deserializer);
let api_version = <Vec<u8>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move { let api_version = <Vec<u8>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::should_request_new_messages(api_contact_id, &api_version).await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::should_request_new_messages(api_callback_id, api_contact_id, &api_version).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -137,10 +141,11 @@ fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_update_v
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_update_verification_state_for_user", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_update_verification_state_for_user", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_contact_id = <i64>::sse_decode(&mut deserializer); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_contact_id = <i64>::sse_decode(&mut deserializer);
let api_public_key_verified_timestamp = <Option<i64>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move { let api_public_key_verified_timestamp = <Option<i64>>::sse_decode(&mut deserializer);deserializer.end(); move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move { transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>((move || async move {
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::update_verification_state_for_user(api_contact_id, api_public_key_verified_timestamp).await?; Ok(output_ok) let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::update_verification_state_for_user(api_callback_id, api_contact_id, api_public_key_verified_timestamp).await?; Ok(output_ok)
})().await) })().await)
} }) } })
} }
@ -153,7 +158,8 @@ fn wire__crate__bridge__callbacks__init_flutter_callbacks_impl(
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "init_flutter_callbacks", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || { FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "init_flutter_callbacks", port: Some(port_), mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal }, move || {
let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) }; let message = unsafe { flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_, rust_vec_len_, data_len_) };
let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message); let mut deserializer = flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_logging_get_stream_sink = decode_DartFn_Inputs__Output_StreamSink_String_Sse_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer)); let api_callback_id = <u32>::sse_decode(&mut deserializer);
let api_logging_get_stream_sink = decode_DartFn_Inputs__Output_StreamSink_String_Sse_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
let api_user_discovery_sign_data = decode_DartFn_Inputs_list_prim_u_8_strict_Output_opt_list_prim_u_8_strict_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer)); let api_user_discovery_sign_data = decode_DartFn_Inputs_list_prim_u_8_strict_Output_opt_list_prim_u_8_strict_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
let api_user_discovery_verify_signature = decode_DartFn_Inputs_list_prim_u_8_strict_list_prim_u_8_strict_list_prim_u_8_strict_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer)); let api_user_discovery_verify_signature = decode_DartFn_Inputs_list_prim_u_8_strict_list_prim_u_8_strict_list_prim_u_8_strict_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
let api_user_discovery_verify_stored_pubkey = decode_DartFn_Inputs_i_64_list_prim_u_8_strict_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer)); let api_user_discovery_verify_stored_pubkey = decode_DartFn_Inputs_i_64_list_prim_u_8_strict_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
@ -169,7 +175,7 @@ let api_user_discovery_set_contact_version = decode_DartFn_Inputs_i_64_list_prim
let api_user_discovery_push_new_user_relation = decode_DartFn_Inputs_i_64_announced_user_opt_box_autoadd_i_64_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer)); let api_user_discovery_push_new_user_relation = decode_DartFn_Inputs_i_64_announced_user_opt_box_autoadd_i_64_Output_bool_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));
let api_user_discovery_get_contact_promotion = decode_DartFn_Inputs_i_64_Output_opt_list_prim_u_8_strict_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));deserializer.end(); move |context| { let api_user_discovery_get_contact_promotion = decode_DartFn_Inputs_i_64_Output_opt_list_prim_u_8_strict_AnyhowException(<flutter_rust_bridge::DartOpaque>::sse_decode(&mut deserializer));deserializer.end(); move |context| {
transform_result_sse::<_, ()>((move || { transform_result_sse::<_, ()>((move || {
let output_ok = Result::<_,()>::Ok({ crate::bridge::callbacks::init_flutter_callbacks(api_logging_get_stream_sink, api_user_discovery_sign_data, api_user_discovery_verify_signature, api_user_discovery_verify_stored_pubkey, api_user_discovery_set_shares, api_user_discovery_get_share_for_contact, api_user_discovery_push_own_promotion_and_clear_old_version, api_user_discovery_get_own_promotions_after_version, api_user_discovery_store_other_promotion, api_user_discovery_get_other_promotions_by_public_id, api_user_discovery_get_announced_user_by_public_id, api_user_discovery_get_contact_version, api_user_discovery_set_contact_version, api_user_discovery_push_new_user_relation, api_user_discovery_get_contact_promotion); })?; Ok(output_ok) let output_ok = Result::<_,()>::Ok({ crate::bridge::callbacks::init_flutter_callbacks(api_callback_id, api_logging_get_stream_sink, api_user_discovery_sign_data, api_user_discovery_verify_signature, api_user_discovery_verify_stored_pubkey, api_user_discovery_set_shares, api_user_discovery_get_share_for_contact, api_user_discovery_push_own_promotion_and_clear_old_version, api_user_discovery_get_own_promotions_after_version, api_user_discovery_store_other_promotion, api_user_discovery_get_other_promotions_by_public_id, api_user_discovery_get_announced_user_by_public_id, api_user_discovery_get_contact_version, api_user_discovery_set_contact_version, api_user_discovery_push_new_user_relation, api_user_discovery_get_contact_promotion); })?; Ok(output_ok)
})()) })())
} }) } })
} }