mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-05-25 03:42:13 +00:00
handling server messages
This commit is contained in:
parent
6517473603
commit
f2493a2b56
27 changed files with 13369 additions and 70 deletions
|
|
@ -1,13 +1,12 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:twonly/core/frb_generated.dart';
|
import 'package:twonly/core/frb_generated.dart';
|
||||||
import 'package:twonly/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
setUpAll(() async => RustLib.init());
|
setUpAll(() async => RustLib.init());
|
||||||
testWidgets('Can call rust function', (tester) async {
|
// testWidgets('Can call rust function', (tester) async {
|
||||||
await tester.pumpWidget(const MyApp());
|
// await tester.pumpWidget(const MyApp());
|
||||||
expect(find.textContaining('Result: `Hello, Tom!`'), findsOneWidget);
|
// expect(find.textContaining('Result: `Hello, Tom!`'), findsOneWidget);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
@ -22,11 +22,11 @@ class FlutterUserDiscovery {
|
||||||
receivedVersion: receivedVersion,
|
receivedVersion: receivedVersion,
|
||||||
);
|
);
|
||||||
|
|
||||||
static Future<void> handleUserDiscoveryMessages({
|
static Future<void> handleNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<Uint8List> messages,
|
required List<Uint8List> messages,
|
||||||
}) => RustLib.instance.api
|
}) => RustLib.instance.api
|
||||||
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleUserDiscoveryMessages(
|
.crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages(
|
||||||
contactId: contactId,
|
contactId: contactId,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
);
|
);
|
||||||
|
|
@ -42,7 +42,7 @@ class FlutterUserDiscovery {
|
||||||
publicKey: publicKey,
|
publicKey: publicKey,
|
||||||
);
|
);
|
||||||
|
|
||||||
static Future<bool> shouldRequestNewMessages({
|
static Future<Uint8List?> shouldRequestNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<int> version,
|
required List<int> version,
|
||||||
}) => RustLib.instance.api
|
}) => RustLib.instance.api
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||||
String get codegenVersion => '2.12.0';
|
String get codegenVersion => '2.12.0';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get rustContentHash => 523281685;
|
int get rustContentHash => -630534473;
|
||||||
|
|
||||||
static const kDefaultExternalLibraryLoaderConfig =
|
static const kDefaultExternalLibraryLoaderConfig =
|
||||||
ExternalLibraryLoaderConfig(
|
ExternalLibraryLoaderConfig(
|
||||||
|
|
@ -92,7 +92,7 @@ abstract class RustLibApi extends BaseApi {
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void>
|
Future<void>
|
||||||
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleUserDiscoveryMessages({
|
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<Uint8List> messages,
|
required List<Uint8List> messages,
|
||||||
});
|
});
|
||||||
|
|
@ -104,7 +104,7 @@ abstract class RustLibApi extends BaseApi {
|
||||||
required List<int> publicKey,
|
required List<int> publicKey,
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<bool>
|
Future<Uint8List?>
|
||||||
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
|
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<int> version,
|
required List<int> version,
|
||||||
|
|
@ -228,7 +228,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void>
|
Future<void>
|
||||||
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleUserDiscoveryMessages({
|
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<Uint8List> messages,
|
required List<Uint8List> messages,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -250,7 +250,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
decodeErrorData: sse_decode_AnyhowException,
|
decodeErrorData: sse_decode_AnyhowException,
|
||||||
),
|
),
|
||||||
constMeta:
|
constMeta:
|
||||||
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleUserDiscoveryMessagesConstMeta,
|
kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta,
|
||||||
argValues: [contactId, messages],
|
argValues: [contactId, messages],
|
||||||
apiImpl: this,
|
apiImpl: this,
|
||||||
),
|
),
|
||||||
|
|
@ -258,9 +258,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskConstMeta
|
TaskConstMeta
|
||||||
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleUserDiscoveryMessagesConstMeta =>
|
get kCrateBridgeWrapperUserDiscoveryFlutterUserDiscoveryHandleNewMessagesConstMeta =>
|
||||||
const TaskConstMeta(
|
const TaskConstMeta(
|
||||||
debugName: 'flutter_user_discovery_handle_user_discovery_messages',
|
debugName: 'flutter_user_discovery_handle_new_messages',
|
||||||
argNames: ['contactId', 'messages'],
|
argNames: ['contactId', 'messages'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -305,7 +305,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool>
|
Future<Uint8List?>
|
||||||
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
|
crateBridgeWrapperUserDiscoveryFlutterUserDiscoveryShouldRequestNewMessages({
|
||||||
required PlatformInt64 contactId,
|
required PlatformInt64 contactId,
|
||||||
required List<int> version,
|
required List<int> version,
|
||||||
|
|
@ -324,7 +324,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
codec: SseCodec(
|
codec: SseCodec(
|
||||||
decodeSuccessData: sse_decode_bool,
|
decodeSuccessData: sse_decode_opt_list_prim_u_8_strict,
|
||||||
decodeErrorData: sse_decode_AnyhowException,
|
decodeErrorData: sse_decode_AnyhowException,
|
||||||
),
|
),
|
||||||
constMeta:
|
constMeta:
|
||||||
|
|
|
||||||
|
|
@ -216,10 +216,10 @@ class UserDiscoveryCallbacks {
|
||||||
await twonlyDB
|
await twonlyDB
|
||||||
.into(twonlyDB.userDiscoveryAnnouncedUsers)
|
.into(twonlyDB.userDiscoveryAnnouncedUsers)
|
||||||
.insertOnConflictUpdate(
|
.insertOnConflictUpdate(
|
||||||
UserDiscoveryAnnouncedUser(
|
UserDiscoveryAnnouncedUsersCompanion(
|
||||||
announcedUserId: announcedUser.userId,
|
announcedUserId: Value(announcedUser.userId),
|
||||||
announcedPublicKey: announcedUser.publicKey,
|
announcedPublicKey: Value(announcedUser.publicKey),
|
||||||
publicId: announcedUser.publicId,
|
publicId: Value(announcedUser.publicId),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,90 @@ class UserDiscoveryDao extends DatabaseAccessor<TwonlyDB>
|
||||||
// of this object.
|
// of this object.
|
||||||
// ignore: matching_super_parameters
|
// ignore: matching_super_parameters
|
||||||
UserDiscoveryDao(super.db);
|
UserDiscoveryDao(super.db);
|
||||||
|
|
||||||
|
/// 1. Get count for contacts which are in announced but not in the contacts table
|
||||||
|
|
||||||
|
/// Returns all users which are not yet in the contacts table but have no data loaded (e.g. Avatar, username and display name)
|
||||||
|
Future<List<UserDiscoveryAnnouncedUser>>
|
||||||
|
getNewAnnouncementsWithoutData() async {
|
||||||
|
final query =
|
||||||
|
select(userDiscoveryAnnouncedUsers).join([
|
||||||
|
leftOuterJoin(
|
||||||
|
contacts,
|
||||||
|
contacts.userId.equalsExp(
|
||||||
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
// Apply filters:
|
||||||
|
// 1. The user must NOT exist in the contacts table
|
||||||
|
// 2. The username must be null
|
||||||
|
..where(
|
||||||
|
contacts.userId.isNull() &
|
||||||
|
userDiscoveryAnnouncedUsers.username.isNull(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return (await query.get())
|
||||||
|
.map((row) => row.readTable(userDiscoveryAnnouncedUsers))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<UserDiscoveryAnnouncedUser, List<(int, DateTime?)>>>
|
||||||
|
getAnnouncedUsersWithRelations() async {
|
||||||
|
final query = select(userDiscoveryAnnouncedUsers).join([
|
||||||
|
innerJoin(
|
||||||
|
userDiscoveryUserRelations,
|
||||||
|
userDiscoveryUserRelations.announcedUserId.equalsExp(
|
||||||
|
userDiscoveryAnnouncedUsers.announcedUserId,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final rows = await query.get();
|
||||||
|
|
||||||
|
final results = <UserDiscoveryAnnouncedUser, List<(int, DateTime?)>>{};
|
||||||
|
|
||||||
|
for (final row in rows) {
|
||||||
|
final user = row.readTable(userDiscoveryAnnouncedUsers);
|
||||||
|
final relation = row.readTable(userDiscoveryUserRelations);
|
||||||
|
|
||||||
|
final relationData = (
|
||||||
|
relation.fromContactId,
|
||||||
|
relation.publicKeyVerifiedTimestamp,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!results.containsKey(user)) {
|
||||||
|
results[user] = [];
|
||||||
|
}
|
||||||
|
results[user]!.add(relationData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream<int> watchNewAnnouncementsWithDataCount() {
|
||||||
|
final countExp = userDiscoveryAnnouncedUsers.announcedUserId.count();
|
||||||
|
|
||||||
|
final query = selectOnly(userDiscoveryAnnouncedUsers)
|
||||||
|
..addColumns([countExp])
|
||||||
|
..where(
|
||||||
|
// Filters: Has a username AND has not been shown to the user yet
|
||||||
|
userDiscoveryAnnouncedUsers.username.isNotNull() &
|
||||||
|
userDiscoveryAnnouncedUsers.wasShownToTheUser.equals(false) &
|
||||||
|
userDiscoveryAnnouncedUsers.isHidden.equals(false),
|
||||||
|
);
|
||||||
|
|
||||||
|
return query.watchSingle().map((row) => row.read(countExp) ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateAnnouncedUser(
|
||||||
|
int announcedUserId,
|
||||||
|
UserDiscoveryAnnouncedUsersCompanion updatedValues,
|
||||||
|
) async {
|
||||||
|
await (update(
|
||||||
|
userDiscoveryAnnouncedUsers,
|
||||||
|
)..where((c) => c.announcedUserId.equals(announcedUserId))).write(
|
||||||
|
updatedValues,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2713
lib/src/database/schemas/twonly_db/drift_schema_v14.json
Normal file
2713
lib/src/database/schemas/twonly_db/drift_schema_v14.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,13 @@ class UserDiscoveryAnnouncedUsers extends Table {
|
||||||
BlobColumn get announcedPublicKey => blob()();
|
BlobColumn get announcedPublicKey => blob()();
|
||||||
IntColumn get publicId => integer().unique()();
|
IntColumn get publicId => integer().unique()();
|
||||||
|
|
||||||
|
// When a new user got announced this data will be requested without adding the users to the contacts...
|
||||||
|
TextColumn get username => text().nullable()();
|
||||||
|
|
||||||
|
BoolColumn get wasShownToTheUser =>
|
||||||
|
boolean().withDefault(const Constant(false))();
|
||||||
|
BoolColumn get isHidden => boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {announcedUserId};
|
Set<Column> get primaryKey => {announcedUserId};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class TwonlyDB extends _$TwonlyDB {
|
||||||
TwonlyDB.forTesting(DatabaseConnection super.connection);
|
TwonlyDB.forTesting(DatabaseConnection super.connection);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 13;
|
int get schemaVersion => 14;
|
||||||
|
|
||||||
static QueryExecutor _openConnection() {
|
static QueryExecutor _openConnection() {
|
||||||
return driftDatabase(
|
return driftDatabase(
|
||||||
|
|
@ -191,6 +191,20 @@ class TwonlyDB extends _$TwonlyDB {
|
||||||
schema.contacts.mediaSendCounter,
|
schema.contacts.mediaSendCounter,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
from13To14: (m, schema) async {
|
||||||
|
await m.addColumn(
|
||||||
|
schema.userDiscoveryAnnouncedUsers,
|
||||||
|
schema.userDiscoveryAnnouncedUsers.wasShownToTheUser,
|
||||||
|
);
|
||||||
|
await m.addColumn(
|
||||||
|
schema.userDiscoveryAnnouncedUsers,
|
||||||
|
schema.userDiscoveryAnnouncedUsers.isHidden,
|
||||||
|
);
|
||||||
|
await m.addColumn(
|
||||||
|
schema.userDiscoveryAnnouncedUsers,
|
||||||
|
schema.userDiscoveryAnnouncedUsers.username,
|
||||||
|
);
|
||||||
|
},
|
||||||
)(m, from, to);
|
)(m, from, to);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -9537,11 +9537,55 @@ class $UserDiscoveryAnnouncedUsersTable extends UserDiscoveryAnnouncedUsers
|
||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE'),
|
defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE'),
|
||||||
);
|
);
|
||||||
|
static const VerificationMeta _usernameMeta = const VerificationMeta(
|
||||||
|
'username',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> username = GeneratedColumn<String>(
|
||||||
|
'username',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _wasShownToTheUserMeta = const VerificationMeta(
|
||||||
|
'wasShownToTheUser',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> wasShownToTheUser = GeneratedColumn<bool>(
|
||||||
|
'was_shown_to_the_user',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("was_shown_to_the_user" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const Constant(false),
|
||||||
|
);
|
||||||
|
static const VerificationMeta _isHiddenMeta = const VerificationMeta(
|
||||||
|
'isHidden',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> isHidden = GeneratedColumn<bool>(
|
||||||
|
'is_hidden',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("is_hidden" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const Constant(false),
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [
|
List<GeneratedColumn> get $columns => [
|
||||||
announcedUserId,
|
announcedUserId,
|
||||||
announcedPublicKey,
|
announcedPublicKey,
|
||||||
publicId,
|
publicId,
|
||||||
|
username,
|
||||||
|
wasShownToTheUser,
|
||||||
|
isHidden,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
|
@ -9583,6 +9627,27 @@ class $UserDiscoveryAnnouncedUsersTable extends UserDiscoveryAnnouncedUsers
|
||||||
} else if (isInserting) {
|
} else if (isInserting) {
|
||||||
context.missing(_publicIdMeta);
|
context.missing(_publicIdMeta);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('username')) {
|
||||||
|
context.handle(
|
||||||
|
_usernameMeta,
|
||||||
|
username.isAcceptableOrUnknown(data['username']!, _usernameMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('was_shown_to_the_user')) {
|
||||||
|
context.handle(
|
||||||
|
_wasShownToTheUserMeta,
|
||||||
|
wasShownToTheUser.isAcceptableOrUnknown(
|
||||||
|
data['was_shown_to_the_user']!,
|
||||||
|
_wasShownToTheUserMeta,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('is_hidden')) {
|
||||||
|
context.handle(
|
||||||
|
_isHiddenMeta,
|
||||||
|
isHidden.isAcceptableOrUnknown(data['is_hidden']!, _isHiddenMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9607,6 +9672,18 @@ class $UserDiscoveryAnnouncedUsersTable extends UserDiscoveryAnnouncedUsers
|
||||||
DriftSqlType.int,
|
DriftSqlType.int,
|
||||||
data['${effectivePrefix}public_id'],
|
data['${effectivePrefix}public_id'],
|
||||||
)!,
|
)!,
|
||||||
|
username: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}username'],
|
||||||
|
),
|
||||||
|
wasShownToTheUser: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}was_shown_to_the_user'],
|
||||||
|
)!,
|
||||||
|
isHidden: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}is_hidden'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9621,10 +9698,16 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
final int announcedUserId;
|
final int announcedUserId;
|
||||||
final Uint8List announcedPublicKey;
|
final Uint8List announcedPublicKey;
|
||||||
final int publicId;
|
final int publicId;
|
||||||
|
final String? username;
|
||||||
|
final bool wasShownToTheUser;
|
||||||
|
final bool isHidden;
|
||||||
const UserDiscoveryAnnouncedUser({
|
const UserDiscoveryAnnouncedUser({
|
||||||
required this.announcedUserId,
|
required this.announcedUserId,
|
||||||
required this.announcedPublicKey,
|
required this.announcedPublicKey,
|
||||||
required this.publicId,
|
required this.publicId,
|
||||||
|
this.username,
|
||||||
|
required this.wasShownToTheUser,
|
||||||
|
required this.isHidden,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
|
@ -9632,6 +9715,11 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
map['announced_user_id'] = Variable<int>(announcedUserId);
|
map['announced_user_id'] = Variable<int>(announcedUserId);
|
||||||
map['announced_public_key'] = Variable<Uint8List>(announcedPublicKey);
|
map['announced_public_key'] = Variable<Uint8List>(announcedPublicKey);
|
||||||
map['public_id'] = Variable<int>(publicId);
|
map['public_id'] = Variable<int>(publicId);
|
||||||
|
if (!nullToAbsent || username != null) {
|
||||||
|
map['username'] = Variable<String>(username);
|
||||||
|
}
|
||||||
|
map['was_shown_to_the_user'] = Variable<bool>(wasShownToTheUser);
|
||||||
|
map['is_hidden'] = Variable<bool>(isHidden);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9640,6 +9728,11 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
announcedUserId: Value(announcedUserId),
|
announcedUserId: Value(announcedUserId),
|
||||||
announcedPublicKey: Value(announcedPublicKey),
|
announcedPublicKey: Value(announcedPublicKey),
|
||||||
publicId: Value(publicId),
|
publicId: Value(publicId),
|
||||||
|
username: username == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(username),
|
||||||
|
wasShownToTheUser: Value(wasShownToTheUser),
|
||||||
|
isHidden: Value(isHidden),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9654,6 +9747,9 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
json['announcedPublicKey'],
|
json['announcedPublicKey'],
|
||||||
),
|
),
|
||||||
publicId: serializer.fromJson<int>(json['publicId']),
|
publicId: serializer.fromJson<int>(json['publicId']),
|
||||||
|
username: serializer.fromJson<String?>(json['username']),
|
||||||
|
wasShownToTheUser: serializer.fromJson<bool>(json['wasShownToTheUser']),
|
||||||
|
isHidden: serializer.fromJson<bool>(json['isHidden']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
|
|
@ -9663,6 +9759,9 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
'announcedUserId': serializer.toJson<int>(announcedUserId),
|
'announcedUserId': serializer.toJson<int>(announcedUserId),
|
||||||
'announcedPublicKey': serializer.toJson<Uint8List>(announcedPublicKey),
|
'announcedPublicKey': serializer.toJson<Uint8List>(announcedPublicKey),
|
||||||
'publicId': serializer.toJson<int>(publicId),
|
'publicId': serializer.toJson<int>(publicId),
|
||||||
|
'username': serializer.toJson<String?>(username),
|
||||||
|
'wasShownToTheUser': serializer.toJson<bool>(wasShownToTheUser),
|
||||||
|
'isHidden': serializer.toJson<bool>(isHidden),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9670,10 +9769,16 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
int? announcedUserId,
|
int? announcedUserId,
|
||||||
Uint8List? announcedPublicKey,
|
Uint8List? announcedPublicKey,
|
||||||
int? publicId,
|
int? publicId,
|
||||||
|
Value<String?> username = const Value.absent(),
|
||||||
|
bool? wasShownToTheUser,
|
||||||
|
bool? isHidden,
|
||||||
}) => UserDiscoveryAnnouncedUser(
|
}) => UserDiscoveryAnnouncedUser(
|
||||||
announcedUserId: announcedUserId ?? this.announcedUserId,
|
announcedUserId: announcedUserId ?? this.announcedUserId,
|
||||||
announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey,
|
announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey,
|
||||||
publicId: publicId ?? this.publicId,
|
publicId: publicId ?? this.publicId,
|
||||||
|
username: username.present ? username.value : this.username,
|
||||||
|
wasShownToTheUser: wasShownToTheUser ?? this.wasShownToTheUser,
|
||||||
|
isHidden: isHidden ?? this.isHidden,
|
||||||
);
|
);
|
||||||
UserDiscoveryAnnouncedUser copyWithCompanion(
|
UserDiscoveryAnnouncedUser copyWithCompanion(
|
||||||
UserDiscoveryAnnouncedUsersCompanion data,
|
UserDiscoveryAnnouncedUsersCompanion data,
|
||||||
|
|
@ -9686,6 +9791,11 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
? data.announcedPublicKey.value
|
? data.announcedPublicKey.value
|
||||||
: this.announcedPublicKey,
|
: this.announcedPublicKey,
|
||||||
publicId: data.publicId.present ? data.publicId.value : this.publicId,
|
publicId: data.publicId.present ? data.publicId.value : this.publicId,
|
||||||
|
username: data.username.present ? data.username.value : this.username,
|
||||||
|
wasShownToTheUser: data.wasShownToTheUser.present
|
||||||
|
? data.wasShownToTheUser.value
|
||||||
|
: this.wasShownToTheUser,
|
||||||
|
isHidden: data.isHidden.present ? data.isHidden.value : this.isHidden,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9694,7 +9804,10 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
return (StringBuffer('UserDiscoveryAnnouncedUser(')
|
return (StringBuffer('UserDiscoveryAnnouncedUser(')
|
||||||
..write('announcedUserId: $announcedUserId, ')
|
..write('announcedUserId: $announcedUserId, ')
|
||||||
..write('announcedPublicKey: $announcedPublicKey, ')
|
..write('announcedPublicKey: $announcedPublicKey, ')
|
||||||
..write('publicId: $publicId')
|
..write('publicId: $publicId, ')
|
||||||
|
..write('username: $username, ')
|
||||||
|
..write('wasShownToTheUser: $wasShownToTheUser, ')
|
||||||
|
..write('isHidden: $isHidden')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -9704,6 +9817,9 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
announcedUserId,
|
announcedUserId,
|
||||||
$driftBlobEquality.hash(announcedPublicKey),
|
$driftBlobEquality.hash(announcedPublicKey),
|
||||||
publicId,
|
publicId,
|
||||||
|
username,
|
||||||
|
wasShownToTheUser,
|
||||||
|
isHidden,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
|
|
@ -9714,7 +9830,10 @@ class UserDiscoveryAnnouncedUser extends DataClass
|
||||||
other.announcedPublicKey,
|
other.announcedPublicKey,
|
||||||
this.announcedPublicKey,
|
this.announcedPublicKey,
|
||||||
) &&
|
) &&
|
||||||
other.publicId == this.publicId);
|
other.publicId == this.publicId &&
|
||||||
|
other.username == this.username &&
|
||||||
|
other.wasShownToTheUser == this.wasShownToTheUser &&
|
||||||
|
other.isHidden == this.isHidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserDiscoveryAnnouncedUsersCompanion
|
class UserDiscoveryAnnouncedUsersCompanion
|
||||||
|
|
@ -9722,27 +9841,42 @@ class UserDiscoveryAnnouncedUsersCompanion
|
||||||
final Value<int> announcedUserId;
|
final Value<int> announcedUserId;
|
||||||
final Value<Uint8List> announcedPublicKey;
|
final Value<Uint8List> announcedPublicKey;
|
||||||
final Value<int> publicId;
|
final Value<int> publicId;
|
||||||
|
final Value<String?> username;
|
||||||
|
final Value<bool> wasShownToTheUser;
|
||||||
|
final Value<bool> isHidden;
|
||||||
const UserDiscoveryAnnouncedUsersCompanion({
|
const UserDiscoveryAnnouncedUsersCompanion({
|
||||||
this.announcedUserId = const Value.absent(),
|
this.announcedUserId = const Value.absent(),
|
||||||
this.announcedPublicKey = const Value.absent(),
|
this.announcedPublicKey = const Value.absent(),
|
||||||
this.publicId = const Value.absent(),
|
this.publicId = const Value.absent(),
|
||||||
|
this.username = const Value.absent(),
|
||||||
|
this.wasShownToTheUser = const Value.absent(),
|
||||||
|
this.isHidden = const Value.absent(),
|
||||||
});
|
});
|
||||||
UserDiscoveryAnnouncedUsersCompanion.insert({
|
UserDiscoveryAnnouncedUsersCompanion.insert({
|
||||||
this.announcedUserId = const Value.absent(),
|
this.announcedUserId = const Value.absent(),
|
||||||
required Uint8List announcedPublicKey,
|
required Uint8List announcedPublicKey,
|
||||||
required int publicId,
|
required int publicId,
|
||||||
|
this.username = const Value.absent(),
|
||||||
|
this.wasShownToTheUser = const Value.absent(),
|
||||||
|
this.isHidden = const Value.absent(),
|
||||||
}) : announcedPublicKey = Value(announcedPublicKey),
|
}) : announcedPublicKey = Value(announcedPublicKey),
|
||||||
publicId = Value(publicId);
|
publicId = Value(publicId);
|
||||||
static Insertable<UserDiscoveryAnnouncedUser> custom({
|
static Insertable<UserDiscoveryAnnouncedUser> custom({
|
||||||
Expression<int>? announcedUserId,
|
Expression<int>? announcedUserId,
|
||||||
Expression<Uint8List>? announcedPublicKey,
|
Expression<Uint8List>? announcedPublicKey,
|
||||||
Expression<int>? publicId,
|
Expression<int>? publicId,
|
||||||
|
Expression<String>? username,
|
||||||
|
Expression<bool>? wasShownToTheUser,
|
||||||
|
Expression<bool>? isHidden,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (announcedUserId != null) 'announced_user_id': announcedUserId,
|
if (announcedUserId != null) 'announced_user_id': announcedUserId,
|
||||||
if (announcedPublicKey != null)
|
if (announcedPublicKey != null)
|
||||||
'announced_public_key': announcedPublicKey,
|
'announced_public_key': announcedPublicKey,
|
||||||
if (publicId != null) 'public_id': publicId,
|
if (publicId != null) 'public_id': publicId,
|
||||||
|
if (username != null) 'username': username,
|
||||||
|
if (wasShownToTheUser != null) 'was_shown_to_the_user': wasShownToTheUser,
|
||||||
|
if (isHidden != null) 'is_hidden': isHidden,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9750,11 +9884,17 @@ class UserDiscoveryAnnouncedUsersCompanion
|
||||||
Value<int>? announcedUserId,
|
Value<int>? announcedUserId,
|
||||||
Value<Uint8List>? announcedPublicKey,
|
Value<Uint8List>? announcedPublicKey,
|
||||||
Value<int>? publicId,
|
Value<int>? publicId,
|
||||||
|
Value<String?>? username,
|
||||||
|
Value<bool>? wasShownToTheUser,
|
||||||
|
Value<bool>? isHidden,
|
||||||
}) {
|
}) {
|
||||||
return UserDiscoveryAnnouncedUsersCompanion(
|
return UserDiscoveryAnnouncedUsersCompanion(
|
||||||
announcedUserId: announcedUserId ?? this.announcedUserId,
|
announcedUserId: announcedUserId ?? this.announcedUserId,
|
||||||
announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey,
|
announcedPublicKey: announcedPublicKey ?? this.announcedPublicKey,
|
||||||
publicId: publicId ?? this.publicId,
|
publicId: publicId ?? this.publicId,
|
||||||
|
username: username ?? this.username,
|
||||||
|
wasShownToTheUser: wasShownToTheUser ?? this.wasShownToTheUser,
|
||||||
|
isHidden: isHidden ?? this.isHidden,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9772,6 +9912,15 @@ class UserDiscoveryAnnouncedUsersCompanion
|
||||||
if (publicId.present) {
|
if (publicId.present) {
|
||||||
map['public_id'] = Variable<int>(publicId.value);
|
map['public_id'] = Variable<int>(publicId.value);
|
||||||
}
|
}
|
||||||
|
if (username.present) {
|
||||||
|
map['username'] = Variable<String>(username.value);
|
||||||
|
}
|
||||||
|
if (wasShownToTheUser.present) {
|
||||||
|
map['was_shown_to_the_user'] = Variable<bool>(wasShownToTheUser.value);
|
||||||
|
}
|
||||||
|
if (isHidden.present) {
|
||||||
|
map['is_hidden'] = Variable<bool>(isHidden.value);
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9780,7 +9929,10 @@ class UserDiscoveryAnnouncedUsersCompanion
|
||||||
return (StringBuffer('UserDiscoveryAnnouncedUsersCompanion(')
|
return (StringBuffer('UserDiscoveryAnnouncedUsersCompanion(')
|
||||||
..write('announcedUserId: $announcedUserId, ')
|
..write('announcedUserId: $announcedUserId, ')
|
||||||
..write('announcedPublicKey: $announcedPublicKey, ')
|
..write('announcedPublicKey: $announcedPublicKey, ')
|
||||||
..write('publicId: $publicId')
|
..write('publicId: $publicId, ')
|
||||||
|
..write('username: $username, ')
|
||||||
|
..write('wasShownToTheUser: $wasShownToTheUser, ')
|
||||||
|
..write('isHidden: $isHidden')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -19690,12 +19842,18 @@ typedef $$UserDiscoveryAnnouncedUsersTableCreateCompanionBuilder =
|
||||||
Value<int> announcedUserId,
|
Value<int> announcedUserId,
|
||||||
required Uint8List announcedPublicKey,
|
required Uint8List announcedPublicKey,
|
||||||
required int publicId,
|
required int publicId,
|
||||||
|
Value<String?> username,
|
||||||
|
Value<bool> wasShownToTheUser,
|
||||||
|
Value<bool> isHidden,
|
||||||
});
|
});
|
||||||
typedef $$UserDiscoveryAnnouncedUsersTableUpdateCompanionBuilder =
|
typedef $$UserDiscoveryAnnouncedUsersTableUpdateCompanionBuilder =
|
||||||
UserDiscoveryAnnouncedUsersCompanion Function({
|
UserDiscoveryAnnouncedUsersCompanion Function({
|
||||||
Value<int> announcedUserId,
|
Value<int> announcedUserId,
|
||||||
Value<Uint8List> announcedPublicKey,
|
Value<Uint8List> announcedPublicKey,
|
||||||
Value<int> publicId,
|
Value<int> publicId,
|
||||||
|
Value<String?> username,
|
||||||
|
Value<bool> wasShownToTheUser,
|
||||||
|
Value<bool> isHidden,
|
||||||
});
|
});
|
||||||
|
|
||||||
final class $$UserDiscoveryAnnouncedUsersTableReferences
|
final class $$UserDiscoveryAnnouncedUsersTableReferences
|
||||||
|
|
@ -19769,6 +19927,21 @@ class $$UserDiscoveryAnnouncedUsersTableFilterComposer
|
||||||
builder: (column) => ColumnFilters(column),
|
builder: (column) => ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get username => $composableBuilder(
|
||||||
|
column: $table.username,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<bool> get wasShownToTheUser => $composableBuilder(
|
||||||
|
column: $table.wasShownToTheUser,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<bool> get isHidden => $composableBuilder(
|
||||||
|
column: $table.isHidden,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
Expression<bool> userDiscoveryUserRelationsRefs(
|
Expression<bool> userDiscoveryUserRelationsRefs(
|
||||||
Expression<bool> Function($$UserDiscoveryUserRelationsTableFilterComposer f)
|
Expression<bool> Function($$UserDiscoveryUserRelationsTableFilterComposer f)
|
||||||
f,
|
f,
|
||||||
|
|
@ -19820,6 +19993,21 @@ class $$UserDiscoveryAnnouncedUsersTableOrderingComposer
|
||||||
column: $table.publicId,
|
column: $table.publicId,
|
||||||
builder: (column) => ColumnOrderings(column),
|
builder: (column) => ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get username => $composableBuilder(
|
||||||
|
column: $table.username,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<bool> get wasShownToTheUser => $composableBuilder(
|
||||||
|
column: $table.wasShownToTheUser,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<bool> get isHidden => $composableBuilder(
|
||||||
|
column: $table.isHidden,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $$UserDiscoveryAnnouncedUsersTableAnnotationComposer
|
class $$UserDiscoveryAnnouncedUsersTableAnnotationComposer
|
||||||
|
|
@ -19844,6 +20032,17 @@ class $$UserDiscoveryAnnouncedUsersTableAnnotationComposer
|
||||||
GeneratedColumn<int> get publicId =>
|
GeneratedColumn<int> get publicId =>
|
||||||
$composableBuilder(column: $table.publicId, builder: (column) => column);
|
$composableBuilder(column: $table.publicId, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get username =>
|
||||||
|
$composableBuilder(column: $table.username, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<bool> get wasShownToTheUser => $composableBuilder(
|
||||||
|
column: $table.wasShownToTheUser,
|
||||||
|
builder: (column) => column,
|
||||||
|
);
|
||||||
|
|
||||||
|
GeneratedColumn<bool> get isHidden =>
|
||||||
|
$composableBuilder(column: $table.isHidden, builder: (column) => column);
|
||||||
|
|
||||||
Expression<T> userDiscoveryUserRelationsRefs<T extends Object>(
|
Expression<T> userDiscoveryUserRelationsRefs<T extends Object>(
|
||||||
Expression<T> Function(
|
Expression<T> Function(
|
||||||
$$UserDiscoveryUserRelationsTableAnnotationComposer a,
|
$$UserDiscoveryUserRelationsTableAnnotationComposer a,
|
||||||
|
|
@ -19919,20 +20118,32 @@ class $$UserDiscoveryAnnouncedUsersTableTableManager
|
||||||
Value<int> announcedUserId = const Value.absent(),
|
Value<int> announcedUserId = const Value.absent(),
|
||||||
Value<Uint8List> announcedPublicKey = const Value.absent(),
|
Value<Uint8List> announcedPublicKey = const Value.absent(),
|
||||||
Value<int> publicId = const Value.absent(),
|
Value<int> publicId = const Value.absent(),
|
||||||
|
Value<String?> username = const Value.absent(),
|
||||||
|
Value<bool> wasShownToTheUser = const Value.absent(),
|
||||||
|
Value<bool> isHidden = const Value.absent(),
|
||||||
}) => UserDiscoveryAnnouncedUsersCompanion(
|
}) => UserDiscoveryAnnouncedUsersCompanion(
|
||||||
announcedUserId: announcedUserId,
|
announcedUserId: announcedUserId,
|
||||||
announcedPublicKey: announcedPublicKey,
|
announcedPublicKey: announcedPublicKey,
|
||||||
publicId: publicId,
|
publicId: publicId,
|
||||||
|
username: username,
|
||||||
|
wasShownToTheUser: wasShownToTheUser,
|
||||||
|
isHidden: isHidden,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
({
|
({
|
||||||
Value<int> announcedUserId = const Value.absent(),
|
Value<int> announcedUserId = const Value.absent(),
|
||||||
required Uint8List announcedPublicKey,
|
required Uint8List announcedPublicKey,
|
||||||
required int publicId,
|
required int publicId,
|
||||||
|
Value<String?> username = const Value.absent(),
|
||||||
|
Value<bool> wasShownToTheUser = const Value.absent(),
|
||||||
|
Value<bool> isHidden = const Value.absent(),
|
||||||
}) => UserDiscoveryAnnouncedUsersCompanion.insert(
|
}) => UserDiscoveryAnnouncedUsersCompanion.insert(
|
||||||
announcedUserId: announcedUserId,
|
announcedUserId: announcedUserId,
|
||||||
announcedPublicKey: announcedPublicKey,
|
announcedPublicKey: announcedPublicKey,
|
||||||
publicId: publicId,
|
publicId: publicId,
|
||||||
|
username: username,
|
||||||
|
wasShownToTheUser: wasShownToTheUser,
|
||||||
|
isHidden: isHidden,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
.map(
|
.map(
|
||||||
|
|
|
||||||
|
|
@ -6932,6 +6932,454 @@ i1.GeneratedColumn<int> _column_229(String aliasedName) =>
|
||||||
$customConstraints: 'NOT NULL DEFAULT 0',
|
$customConstraints: 'NOT NULL DEFAULT 0',
|
||||||
defaultValue: const i1.CustomExpression('0'),
|
defaultValue: const i1.CustomExpression('0'),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final class Schema14 extends i0.VersionedSchema {
|
||||||
|
Schema14({required super.database}) : super(version: 14);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
contacts,
|
||||||
|
groups,
|
||||||
|
mediaFiles,
|
||||||
|
messages,
|
||||||
|
messageHistories,
|
||||||
|
reactions,
|
||||||
|
groupMembers,
|
||||||
|
receipts,
|
||||||
|
receivedReceipts,
|
||||||
|
signalIdentityKeyStores,
|
||||||
|
signalPreKeyStores,
|
||||||
|
signalSenderKeyStores,
|
||||||
|
signalSessionStores,
|
||||||
|
messageActions,
|
||||||
|
groupHistories,
|
||||||
|
keyVerifications,
|
||||||
|
verificationTokens,
|
||||||
|
userDiscoveryAnnouncedUsers,
|
||||||
|
userDiscoveryUserRelations,
|
||||||
|
userDiscoveryOtherPromotions,
|
||||||
|
userDiscoveryOwnPromotions,
|
||||||
|
userDiscoveryShares,
|
||||||
|
];
|
||||||
|
late final Shape47 contacts = Shape47(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'contacts',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(user_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_106,
|
||||||
|
_column_107,
|
||||||
|
_column_108,
|
||||||
|
_column_109,
|
||||||
|
_column_110,
|
||||||
|
_column_111,
|
||||||
|
_column_112,
|
||||||
|
_column_113,
|
||||||
|
_column_114,
|
||||||
|
_column_115,
|
||||||
|
_column_116,
|
||||||
|
_column_117,
|
||||||
|
_column_118,
|
||||||
|
_column_211,
|
||||||
|
_column_228,
|
||||||
|
_column_229,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape23 groups = Shape23(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'groups',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(group_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_119,
|
||||||
|
_column_120,
|
||||||
|
_column_121,
|
||||||
|
_column_122,
|
||||||
|
_column_123,
|
||||||
|
_column_124,
|
||||||
|
_column_125,
|
||||||
|
_column_126,
|
||||||
|
_column_127,
|
||||||
|
_column_128,
|
||||||
|
_column_129,
|
||||||
|
_column_130,
|
||||||
|
_column_131,
|
||||||
|
_column_132,
|
||||||
|
_column_133,
|
||||||
|
_column_134,
|
||||||
|
_column_118,
|
||||||
|
_column_135,
|
||||||
|
_column_136,
|
||||||
|
_column_137,
|
||||||
|
_column_138,
|
||||||
|
_column_139,
|
||||||
|
_column_140,
|
||||||
|
_column_141,
|
||||||
|
_column_142,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape36 mediaFiles = Shape36(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'media_files',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(media_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_143,
|
||||||
|
_column_144,
|
||||||
|
_column_145,
|
||||||
|
_column_146,
|
||||||
|
_column_147,
|
||||||
|
_column_148,
|
||||||
|
_column_149,
|
||||||
|
_column_207,
|
||||||
|
_column_150,
|
||||||
|
_column_151,
|
||||||
|
_column_152,
|
||||||
|
_column_153,
|
||||||
|
_column_154,
|
||||||
|
_column_155,
|
||||||
|
_column_156,
|
||||||
|
_column_157,
|
||||||
|
_column_118,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape25 messages = Shape25(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'messages',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(message_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_158,
|
||||||
|
_column_159,
|
||||||
|
_column_160,
|
||||||
|
_column_144,
|
||||||
|
_column_161,
|
||||||
|
_column_162,
|
||||||
|
_column_163,
|
||||||
|
_column_164,
|
||||||
|
_column_165,
|
||||||
|
_column_153,
|
||||||
|
_column_166,
|
||||||
|
_column_167,
|
||||||
|
_column_168,
|
||||||
|
_column_169,
|
||||||
|
_column_118,
|
||||||
|
_column_170,
|
||||||
|
_column_171,
|
||||||
|
_column_172,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape26 messageHistories = Shape26(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'message_histories',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_173,
|
||||||
|
_column_174,
|
||||||
|
_column_175,
|
||||||
|
_column_161,
|
||||||
|
_column_118,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape27 reactions = Shape27(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'reactions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(message_id, sender_id, emoji)'],
|
||||||
|
columns: [_column_174, _column_176, _column_177, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape38 groupMembers = Shape38(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'group_members',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(group_id, contact_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_158,
|
||||||
|
_column_178,
|
||||||
|
_column_179,
|
||||||
|
_column_180,
|
||||||
|
_column_209,
|
||||||
|
_column_210,
|
||||||
|
_column_181,
|
||||||
|
_column_118,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape37 receipts = Shape37(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'receipts',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(receipt_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_182,
|
||||||
|
_column_183,
|
||||||
|
_column_184,
|
||||||
|
_column_185,
|
||||||
|
_column_186,
|
||||||
|
_column_208,
|
||||||
|
_column_187,
|
||||||
|
_column_188,
|
||||||
|
_column_189,
|
||||||
|
_column_190,
|
||||||
|
_column_191,
|
||||||
|
_column_118,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape30 receivedReceipts = Shape30(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'received_receipts',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(receipt_id)'],
|
||||||
|
columns: [_column_182, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape31 signalIdentityKeyStores = Shape31(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_identity_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(device_id, name)'],
|
||||||
|
columns: [_column_192, _column_193, _column_194, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape32 signalPreKeyStores = Shape32(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_pre_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(pre_key_id)'],
|
||||||
|
columns: [_column_195, _column_196, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape11 signalSenderKeyStores = Shape11(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_sender_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(sender_key_name)'],
|
||||||
|
columns: [_column_197, _column_198],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape33 signalSessionStores = Shape33(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_session_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(device_id, name)'],
|
||||||
|
columns: [_column_192, _column_193, _column_199, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape34 messageActions = Shape34(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'message_actions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(message_id, contact_id, type)'],
|
||||||
|
columns: [_column_174, _column_183, _column_144, _column_200],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape35 groupHistories = Shape35(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'group_histories',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(group_history_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_201,
|
||||||
|
_column_158,
|
||||||
|
_column_202,
|
||||||
|
_column_203,
|
||||||
|
_column_204,
|
||||||
|
_column_205,
|
||||||
|
_column_206,
|
||||||
|
_column_144,
|
||||||
|
_column_200,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape40 keyVerifications = Shape40(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'key_verifications',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(contact_id)'],
|
||||||
|
columns: [_column_183, _column_144, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape41 verificationTokens = Shape41(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'verification_tokens',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [_column_212, _column_213, _column_118],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape48 userDiscoveryAnnouncedUsers = Shape48(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_discovery_announced_users',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(announced_user_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_214,
|
||||||
|
_column_215,
|
||||||
|
_column_216,
|
||||||
|
_column_230,
|
||||||
|
_column_231,
|
||||||
|
_column_232,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape43 userDiscoveryUserRelations = Shape43(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_discovery_user_relations',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(announced_user_id, from_contact_id)'],
|
||||||
|
columns: [_column_217, _column_218, _column_219],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape44 userDiscoveryOtherPromotions = Shape44(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_discovery_other_promotions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: ['PRIMARY KEY(from_contact_id, promotion_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_218,
|
||||||
|
_column_220,
|
||||||
|
_column_221,
|
||||||
|
_column_222,
|
||||||
|
_column_223,
|
||||||
|
_column_219,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape45 userDiscoveryOwnPromotions = Shape45(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_discovery_own_promotions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [_column_224, _column_183, _column_225],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape46 userDiscoveryShares = Shape46(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_discovery_shares',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [_column_226, _column_227, _column_175],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape48 extends i0.VersionedTable {
|
||||||
|
Shape48({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get announcedUserId =>
|
||||||
|
columnsByName['announced_user_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get announcedPublicKey =>
|
||||||
|
columnsByName['announced_public_key']!
|
||||||
|
as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<int> get publicId =>
|
||||||
|
columnsByName['public_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get username =>
|
||||||
|
columnsByName['username']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<int> get wasShownToTheUser =>
|
||||||
|
columnsByName['was_shown_to_the_user']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get isHidden =>
|
||||||
|
columnsByName['is_hidden']! as i1.GeneratedColumn<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<String> _column_230(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>(
|
||||||
|
'username',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i1.DriftSqlType.string,
|
||||||
|
$customConstraints: 'NULL',
|
||||||
|
);
|
||||||
|
i1.GeneratedColumn<int> _column_231(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>(
|
||||||
|
'was_shown_to_the_user',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
$customConstraints:
|
||||||
|
'NOT NULL DEFAULT 0 CHECK (was_shown_to_the_user IN (0, 1))',
|
||||||
|
defaultValue: const i1.CustomExpression('0'),
|
||||||
|
);
|
||||||
|
i1.GeneratedColumn<int> _column_232(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>(
|
||||||
|
'is_hidden',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
$customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_hidden IN (0, 1))',
|
||||||
|
defaultValue: const i1.CustomExpression('0'),
|
||||||
|
);
|
||||||
i0.MigrationStepWithVersion migrationSteps({
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
|
|
@ -6945,6 +7393,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema11 schema) from10To11,
|
required Future<void> Function(i1.Migrator m, Schema11 schema) from10To11,
|
||||||
required Future<void> Function(i1.Migrator m, Schema12 schema) from11To12,
|
required Future<void> Function(i1.Migrator m, Schema12 schema) from11To12,
|
||||||
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
}) {
|
}) {
|
||||||
return (currentVersion, database) async {
|
return (currentVersion, database) async {
|
||||||
switch (currentVersion) {
|
switch (currentVersion) {
|
||||||
|
|
@ -7008,6 +7457,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
final migrator = i1.Migrator(database, schema);
|
final migrator = i1.Migrator(database, schema);
|
||||||
await from12To13(migrator, schema);
|
await from12To13(migrator, schema);
|
||||||
return 13;
|
return 13;
|
||||||
|
case 13:
|
||||||
|
final schema = Schema14(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from13To14(migrator, schema);
|
||||||
|
return 14;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
}
|
}
|
||||||
|
|
@ -7027,6 +7481,7 @@ i1.OnUpgrade stepByStep({
|
||||||
required Future<void> Function(i1.Migrator m, Schema11 schema) from10To11,
|
required Future<void> Function(i1.Migrator m, Schema11 schema) from10To11,
|
||||||
required Future<void> Function(i1.Migrator m, Schema12 schema) from11To12,
|
required Future<void> Function(i1.Migrator m, Schema12 schema) from11To12,
|
||||||
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
required Future<void> Function(i1.Migrator m, Schema13 schema) from12To13,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
}) => i0.VersionedSchema.stepByStepHelper(
|
}) => i0.VersionedSchema.stepByStepHelper(
|
||||||
step: migrationSteps(
|
step: migrationSteps(
|
||||||
from1To2: from1To2,
|
from1To2: from1To2,
|
||||||
|
|
@ -7041,5 +7496,6 @@ i1.OnUpgrade stepByStep({
|
||||||
from10To11: from10To11,
|
from10To11: from10To11,
|
||||||
from11To12: from11To12,
|
from11To12: from11To12,
|
||||||
from12To13: from12To13,
|
from12To13: from12To13,
|
||||||
|
from13To14: from13To14,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3141,6 +3141,12 @@ abstract class AppLocalizations {
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'When the typing indicator is turned off, you can\'t see when others are typing a message.'**
|
/// **'When the typing indicator is turned off, you can\'t see when others are typing a message.'**
|
||||||
String get settingsTypingIndicationSubtitle;
|
String get settingsTypingIndicationSubtitle;
|
||||||
|
|
||||||
|
/// No description provided for @scanQrOrShow.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Scan / Show QR'**
|
||||||
|
String get scanQrOrShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -1761,4 +1761,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get settingsTypingIndicationSubtitle =>
|
String get settingsTypingIndicationSubtitle =>
|
||||||
'Bei deaktivierten Tipp-Indikatoren kannst du nicht sehen, wenn andere gerade eine Nachricht tippen.';
|
'Bei deaktivierten Tipp-Indikatoren kannst du nicht sehen, wenn andere gerade eine Nachricht tippen.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanQrOrShow => 'QR scannen / anzeigen';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1749,4 +1749,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get settingsTypingIndicationSubtitle =>
|
String get settingsTypingIndicationSubtitle =>
|
||||||
'When the typing indicator is turned off, you can\'t see when others are typing a message.';
|
'When the typing indicator is turned off, you can\'t see when others are typing a message.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanQrOrShow => 'Scan / Show QR';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1749,4 +1749,7 @@ class AppLocalizationsSv extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get settingsTypingIndicationSubtitle =>
|
String get settingsTypingIndicationSubtitle =>
|
||||||
'When the typing indicator is turned off, you can\'t see when others are typing a message.';
|
'When the typing indicator is turned off, you can\'t see when others are typing a message.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanQrOrShow => 'Scan / Show QR';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||||
import 'package:twonly/src/services/signal/identity.signal.dart';
|
import 'package:twonly/src/services/signal/identity.signal.dart';
|
||||||
import 'package:twonly/src/services/signal/utils.signal.dart';
|
import 'package:twonly/src/services/signal/utils.signal.dart';
|
||||||
import 'package:twonly/src/services/subscription.service.dart';
|
import 'package:twonly/src/services/subscription.service.dart';
|
||||||
|
import 'package:twonly/src/services/user_discovery.service.dart';
|
||||||
import 'package:twonly/src/utils/keyvalue.dart';
|
import 'package:twonly/src/utils/keyvalue.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
@ -100,6 +101,7 @@ class ApiService {
|
||||||
unawaited(retransmitAllMessages());
|
unawaited(retransmitAllMessages());
|
||||||
unawaited(tryDownloadAllMediaFiles());
|
unawaited(tryDownloadAllMediaFiles());
|
||||||
unawaited(reuploadMediaFiles());
|
unawaited(reuploadMediaFiles());
|
||||||
|
|
||||||
twonlyDB.markUpdated();
|
twonlyDB.markUpdated();
|
||||||
unawaited(syncFlameCounters());
|
unawaited(syncFlameCounters());
|
||||||
unawaited(setupNotificationWithUsers());
|
unawaited(setupNotificationWithUsers());
|
||||||
|
|
@ -108,6 +110,8 @@ class ApiService {
|
||||||
unawaited(fetchMissingGroupPublicKey());
|
unawaited(fetchMissingGroupPublicKey());
|
||||||
unawaited(checkForDeletedUsernames());
|
unawaited(checkForDeletedUsernames());
|
||||||
|
|
||||||
|
unawaited(UserDiscoveryService.checkForNewAnnouncedUsers());
|
||||||
|
|
||||||
if (gUser.userStudyParticipantsToken != null) {
|
if (gUser.userStudyParticipantsToken != null) {
|
||||||
// In case the user participates in the user study, call the handler after authenticated, to be sure there is a internet connection
|
// In case the user participates in the user study, call the handler after authenticated, to be sure there is a internet connection
|
||||||
unawaited(handleUserStudyUpload());
|
unawaited(handleUserStudyUpload());
|
||||||
|
|
|
||||||
78
lib/src/services/api/client2client/user_discovery.c2c.dart
Normal file
78
lib/src/services/api/client2client/user_discovery.c2c.dart
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
|
||||||
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
|
import 'package:twonly/src/services/user_discovery.service.dart';
|
||||||
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
|
||||||
|
Future<void> checkForUserDiscoveryChanges(
|
||||||
|
int fromUserId,
|
||||||
|
List<int> receivedVersion,
|
||||||
|
) async {
|
||||||
|
final currentVersion = await UserDiscoveryService.shouldRequestNewMessages(
|
||||||
|
fromUserId,
|
||||||
|
receivedVersion,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (currentVersion != null) {
|
||||||
|
await sendCipherText(
|
||||||
|
fromUserId,
|
||||||
|
EncryptedContent(
|
||||||
|
userDiscoveryRequest: EncryptedContent_UserDiscoveryRequest(
|
||||||
|
currentVersion: currentVersion.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> handleUserDiscoveryRequest(
|
||||||
|
int fromUserId,
|
||||||
|
EncryptedContent_UserDiscoveryRequest request,
|
||||||
|
) async {
|
||||||
|
if (!gUser.isUserDiscoveryEnabled) {
|
||||||
|
Log.warn('Got a user discovery request while it is disabled');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final contact = await twonlyDB.contactsDao.getContactById(fromUserId);
|
||||||
|
if (contact == null) return;
|
||||||
|
|
||||||
|
if (contact.mediaSendCounter < gUser.minimumRequiredImagesExchanged) {
|
||||||
|
Log.warn(
|
||||||
|
'Got a request to update user discovery, but mediaSendCounter (${contact.mediaSendCounter}) < ${gUser.minimumRequiredImagesExchanged}',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final newMessages = await UserDiscoveryService.getNewMessages(
|
||||||
|
fromUserId,
|
||||||
|
request.currentVersion,
|
||||||
|
);
|
||||||
|
if (newMessages != null && newMessages.isNotEmpty) {
|
||||||
|
await sendCipherText(
|
||||||
|
fromUserId,
|
||||||
|
EncryptedContent(
|
||||||
|
userDiscoveryUpdate: EncryptedContent_UserDiscoveryUpdate(
|
||||||
|
messages: newMessages,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Log.info('Got update request, but there are no new updates for the user');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> handleUserDiscoveryUpdate(
|
||||||
|
int fromUserId,
|
||||||
|
EncryptedContent_UserDiscoveryUpdate update,
|
||||||
|
) async {
|
||||||
|
if (!gUser.isUserDiscoveryEnabled) {
|
||||||
|
Log.warn('Got a user discovery update while it is disabled');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await UserDiscoveryService.handleNewMessages(
|
||||||
|
fromUserId,
|
||||||
|
update.messages.map(Uint8List.fromList).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ import 'package:twonly/src/model/protobuf/client/generated/push_notification.pb.
|
||||||
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||||
import 'package:twonly/src/services/signal/encryption.signal.dart';
|
import 'package:twonly/src/services/signal/encryption.signal.dart';
|
||||||
import 'package:twonly/src/services/signal/session.signal.dart';
|
import 'package:twonly/src/services/signal/session.signal.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/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
|
|
@ -344,6 +345,17 @@ Future<(Uint8List, Uint8List?)?> sendCipherText(
|
||||||
}
|
}
|
||||||
encryptedContent.senderProfileCounter = Int64(gUser.avatarCounter);
|
encryptedContent.senderProfileCounter = Int64(gUser.avatarCounter);
|
||||||
|
|
||||||
|
if (gUser.isUserDiscoveryEnabled) {
|
||||||
|
final contact = await twonlyDB.contactsDao.getContactById(contactId);
|
||||||
|
if (contact != null &&
|
||||||
|
contact.mediaSendCounter >= gUser.minimumRequiredImagesExchanged) {
|
||||||
|
final version = await UserDiscoveryService.getCurrentVersion();
|
||||||
|
if (version != null) {
|
||||||
|
encryptedContent.senderUserDiscoveryVersion = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final response = pb.Message()
|
final response = pb.Message()
|
||||||
..type = pb.Message_Type.CIPHERTEXT
|
..type = pb.Message_Type.CIPHERTEXT
|
||||||
..encryptedContent = encryptedContent.writeToBuffer();
|
..encryptedContent = encryptedContent.writeToBuffer();
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import 'package:twonly/src/services/api/client2client/prekeys.c2c.dart';
|
||||||
import 'package:twonly/src/services/api/client2client/pushkeys.c2c.dart';
|
import 'package:twonly/src/services/api/client2client/pushkeys.c2c.dart';
|
||||||
import 'package:twonly/src/services/api/client2client/reaction.c2c.dart';
|
import 'package:twonly/src/services/api/client2client/reaction.c2c.dart';
|
||||||
import 'package:twonly/src/services/api/client2client/text_message.c2c.dart';
|
import 'package:twonly/src/services/api/client2client/text_message.c2c.dart';
|
||||||
|
import 'package:twonly/src/services/api/client2client/user_discovery.c2c.dart';
|
||||||
import 'package:twonly/src/services/api/messages.dart';
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
import 'package:twonly/src/services/group.services.dart';
|
import 'package:twonly/src/services/group.services.dart';
|
||||||
import 'package:twonly/src/services/notifications/background.notifications.dart';
|
import 'package:twonly/src/services/notifications/background.notifications.dart';
|
||||||
|
|
@ -262,6 +263,12 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage(
|
||||||
await twonlyDB.receiptsDao.markMessagesForRetry(fromUserId);
|
await twonlyDB.receiptsDao.markMessagesForRetry(fromUserId);
|
||||||
|
|
||||||
final senderProfileCounter = await checkForProfileUpdate(fromUserId, content);
|
final senderProfileCounter = await checkForProfileUpdate(fromUserId, content);
|
||||||
|
if (gUser.isUserDiscoveryEnabled && content.hasSenderUserDiscoveryVersion()) {
|
||||||
|
await checkForUserDiscoveryChanges(
|
||||||
|
fromUserId,
|
||||||
|
content.senderUserDiscoveryVersion,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (content.hasContactRequest()) {
|
if (content.hasContactRequest()) {
|
||||||
if (!await handleContactRequest(fromUserId, content.contactRequest)) {
|
if (!await handleContactRequest(fromUserId, content.contactRequest)) {
|
||||||
|
|
@ -291,6 +298,22 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessage(
|
||||||
return (null, null);
|
return (null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (content.hasUserDiscoveryRequest()) {
|
||||||
|
await handleUserDiscoveryRequest(
|
||||||
|
fromUserId,
|
||||||
|
content.userDiscoveryRequest,
|
||||||
|
);
|
||||||
|
return (null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content.hasUserDiscoveryUpdate()) {
|
||||||
|
await handleUserDiscoveryUpdate(
|
||||||
|
fromUserId,
|
||||||
|
content.userDiscoveryUpdate,
|
||||||
|
);
|
||||||
|
return (null, null);
|
||||||
|
}
|
||||||
|
|
||||||
if (content.hasPushKeys()) {
|
if (content.hasPushKeys()) {
|
||||||
await handlePushKey(fromUserId, content.pushKeys);
|
await handlePushKey(fromUserId, content.pushKeys);
|
||||||
return (null, null);
|
return (null, null);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,43 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:convert';
|
||||||
|
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/globals.dart';
|
||||||
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
import 'package:twonly/src/model/protobuf/client/generated/user_discovery/types.pb.dart';
|
import 'package:twonly/src/model/protobuf/client/generated/user_discovery/types.pb.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
import 'package:twonly/src/utils/qr.dart';
|
import 'package:twonly/src/utils/qr.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
|
||||||
class UserDiscoveryService {
|
class UserDiscoveryService {
|
||||||
|
static Future<void> checkForNewAnnouncedUsers() async {
|
||||||
|
final announcedUsers = await twonlyDB.userDiscoveryDao
|
||||||
|
.getNewAnnouncementsWithoutData();
|
||||||
|
|
||||||
|
for (final announcedUser in announcedUsers) {
|
||||||
|
final userdata = await apiService.getUserById(
|
||||||
|
announcedUser.announcedUserId,
|
||||||
|
);
|
||||||
|
if (userdata == null) continue;
|
||||||
|
if (userdata.publicIdentityKey !=
|
||||||
|
announcedUser.announcedPublicKey.toList()) {
|
||||||
|
Log.error(
|
||||||
|
'Server delivered a different public key then received from the announcement.',
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info('Updating the username from the announced user');
|
||||||
|
|
||||||
|
// Updating the username, so the data will not be requested again..
|
||||||
|
await twonlyDB.userDiscoveryDao.updateAnnouncedUser(
|
||||||
|
announcedUser.announcedUserId,
|
||||||
|
UserDiscoveryAnnouncedUsersCompanion(
|
||||||
|
username: Value(utf8.decode(userdata.username)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> initializeOrUpdate({
|
static Future<void> initializeOrUpdate({
|
||||||
required int threshold,
|
required int threshold,
|
||||||
required int minimumRequiredImagesExchanged,
|
required int minimumRequiredImagesExchanged,
|
||||||
|
|
@ -44,6 +74,50 @@ class UserDiscoveryService {
|
||||||
return UserDiscoveryVersion.fromBuffer(version);
|
return UserDiscoveryVersion.fromBuffer(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<Uint8List?> shouldRequestNewMessages(
|
||||||
|
int fromUserId,
|
||||||
|
List<int> receivedVersion,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
return await FlutterUserDiscovery.shouldRequestNewMessages(
|
||||||
|
contactId: fromUserId,
|
||||||
|
version: receivedVersion,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Log.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<List<Uint8List>?> getNewMessages(
|
||||||
|
int fromUserId,
|
||||||
|
List<int> receivedVersion,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
return await FlutterUserDiscovery.getNewMessages(
|
||||||
|
contactId: fromUserId,
|
||||||
|
receivedVersion: receivedVersion,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Log.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> handleNewMessages(
|
||||||
|
int fromUserId,
|
||||||
|
List<Uint8List> messages,
|
||||||
|
) async {
|
||||||
|
try {
|
||||||
|
return await FlutterUserDiscovery.handleNewMessages(
|
||||||
|
contactId: fromUserId,
|
||||||
|
messages: messages,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
Log.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<void> disable() async {
|
static Future<void> disable() async {
|
||||||
await updateUserdata((u) {
|
await updateUserdata((u) {
|
||||||
u.isUserDiscoveryEnabled = false;
|
u.isUserDiscoveryEnabled = false;
|
||||||
|
|
|
||||||
|
|
@ -167,17 +167,17 @@ class _SearchUsernameView extends State<AddNewUserView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: IconButton(
|
|
||||||
onPressed: () =>
|
|
||||||
context.push(Routes.settingsPublicProfile),
|
|
||||||
icon: const FaIcon(FontAwesomeIcons.qrcode),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
OutlinedButton.icon(
|
||||||
|
onPressed: () => context.push(Routes.settingsPublicProfile),
|
||||||
|
icon: const FaIcon(FontAwesomeIcons.qrcode),
|
||||||
|
label: Text(context.lang.scanQrOrShow),
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
if (contacts.isNotEmpty)
|
if (contacts.isNotEmpty)
|
||||||
HeadLineComponent(
|
HeadLineComponent(
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
GlobalKey searchForOtherUsers = GlobalKey();
|
GlobalKey searchForOtherUsers = GlobalKey();
|
||||||
bool showFeedbackShortcut = false;
|
bool showFeedbackShortcut = false;
|
||||||
|
|
||||||
|
int _countContactRequest = 0;
|
||||||
|
int _countAnnouncedUsers = 0;
|
||||||
|
late StreamSubscription<int?> _countContactRequestStream;
|
||||||
|
late StreamSubscription<int?> _countAnnouncedStream;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
initAsync();
|
initAsync();
|
||||||
|
|
@ -52,6 +57,24 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_countContactRequestStream = twonlyDB.contactsDao
|
||||||
|
.watchContactsRequestedCount()
|
||||||
|
.listen((update) {
|
||||||
|
if (update != null) {
|
||||||
|
setState(() {
|
||||||
|
_countContactRequest = update;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_countContactRequestStream = twonlyDB.userDiscoveryDao
|
||||||
|
.watchNewAnnouncementsWithDataCount()
|
||||||
|
.listen((update) {
|
||||||
|
setState(() {
|
||||||
|
_countAnnouncedUsers = update;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
final changeLog = await rootBundle.loadString('CHANGELOG.md');
|
final changeLog = await rootBundle.loadString('CHANGELOG.md');
|
||||||
final changeLogHash = (await compute(
|
final changeLogHash = (await compute(
|
||||||
|
|
@ -80,6 +103,8 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_contactsSub.cancel();
|
_contactsSub.cancel();
|
||||||
|
_countContactRequestStream.cancel();
|
||||||
|
_countAnnouncedStream.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,23 +157,38 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
const FeedbackIconButton(),
|
const FeedbackIconButton(),
|
||||||
StreamBuilder(
|
Stack(
|
||||||
stream: twonlyDB.contactsDao.watchContactsRequestedCount(),
|
children: [
|
||||||
builder: (context, snapshot) {
|
if (_countAnnouncedUsers + _countContactRequest > 0)
|
||||||
var count = 0;
|
Positioned.fill(
|
||||||
if (snapshot.hasData && snapshot.data != null) {
|
child: Center(
|
||||||
count = snapshot.data!;
|
child: Container(
|
||||||
}
|
width: 40,
|
||||||
return NotificationBadge(
|
height: 40,
|
||||||
count: count.toString(),
|
decoration: BoxDecoration(
|
||||||
child: IconButton(
|
color: context.color.primary,
|
||||||
key: searchForOtherUsers,
|
shape: BoxShape.circle,
|
||||||
icon: const FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
),
|
||||||
onPressed: () => context.push(Routes.chatsAddNewUser),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
Center(
|
||||||
},
|
child: NotificationBadge(
|
||||||
|
count: (_countAnnouncedUsers + _countContactRequest)
|
||||||
|
.toString(),
|
||||||
|
child: IconButton(
|
||||||
|
color: (_countAnnouncedUsers + _countContactRequest > 0)
|
||||||
|
? Colors.black
|
||||||
|
: null,
|
||||||
|
key: searchForOtherUsers,
|
||||||
|
icon: const FaIcon(FontAwesomeIcons.userPlus, size: 18),
|
||||||
|
onPressed: () => context.push(Routes.chatsAddNewUser),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await context.push(Routes.settings);
|
await context.push(Routes.settings);
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,10 @@ impl FlutterUserDiscovery {
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn should_request_new_messages(contact_id: i64, version: &[u8]) -> Result<bool> {
|
pub async fn should_request_new_messages(
|
||||||
|
contact_id: i64,
|
||||||
|
version: &[u8],
|
||||||
|
) -> Result<Option<Vec<u8>>> {
|
||||||
Ok(get_twonly_flutter()?
|
Ok(get_twonly_flutter()?
|
||||||
.user_discovery
|
.user_discovery
|
||||||
.get()
|
.get()
|
||||||
|
|
@ -47,15 +50,12 @@ impl FlutterUserDiscovery {
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_user_discovery_messages(
|
pub async fn handle_new_messages(contact_id: i64, messages: Vec<Vec<u8>>) -> Result<()> {
|
||||||
contact_id: i64,
|
|
||||||
messages: Vec<Vec<u8>>,
|
|
||||||
) -> Result<()> {
|
|
||||||
Ok(get_twonly_flutter()?
|
Ok(get_twonly_flutter()?
|
||||||
.user_discovery
|
.user_discovery
|
||||||
.get()
|
.get()
|
||||||
.await
|
.await
|
||||||
.handle_user_discovery_messages(contact_id, messages)
|
.handle_new_messages(contact_id, messages)
|
||||||
.await?)
|
.await?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
|
||||||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||||
);
|
);
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
|
||||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 523281685;
|
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -630534473;
|
||||||
|
|
||||||
// Section: executor
|
// Section: executor
|
||||||
|
|
||||||
|
|
@ -77,19 +77,19 @@ let api_received_version = <Vec<u8>>::sse_decode(&mut deserializer);deserializer
|
||||||
})().await)
|
})().await)
|
||||||
} })
|
} })
|
||||||
}
|
}
|
||||||
fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_handle_user_discovery_messages_impl(
|
fn wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_handle_new_messages_impl(
|
||||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||||
rust_vec_len_: i32,
|
rust_vec_len_: i32,
|
||||||
data_len_: i32,
|
data_len_: i32,
|
||||||
) {
|
) {
|
||||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec,_,_,_>(flutter_rust_bridge::for_generated::TaskInfo{ debug_name: "flutter_user_discovery_handle_user_discovery_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_contact_id = <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_user_discovery_messages(api_contact_id, api_messages).await?; Ok(output_ok)
|
let output_ok = crate::bridge::wrapper::user_discovery::FlutterUserDiscovery::handle_new_messages(api_contact_id, api_messages).await?; Ok(output_ok)
|
||||||
})().await)
|
})().await)
|
||||||
} })
|
} })
|
||||||
}
|
}
|
||||||
|
|
@ -900,7 +900,7 @@ fn pde_ffi_dispatcher_primary_impl(
|
||||||
match func_id {
|
match func_id {
|
||||||
1 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_current_version_impl(port, ptr, rust_vec_len, data_len),
|
1 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_current_version_impl(port, ptr, rust_vec_len, data_len),
|
||||||
2 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_new_messages_impl(port, ptr, rust_vec_len, data_len),
|
2 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_get_new_messages_impl(port, ptr, rust_vec_len, data_len),
|
||||||
3 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_handle_user_discovery_messages_impl(port, ptr, rust_vec_len, data_len),
|
3 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_handle_new_messages_impl(port, ptr, rust_vec_len, data_len),
|
||||||
4 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_initialize_or_update_impl(port, ptr, rust_vec_len, data_len),
|
4 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_initialize_or_update_impl(port, ptr, rust_vec_len, data_len),
|
||||||
5 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_should_request_new_messages_impl(port, ptr, rust_vec_len, data_len),
|
5 => wire__crate__bridge__wrapper__user_discovery__flutter_user_discovery_should_request_new_messages_impl(port, ptr, rust_vec_len, data_len),
|
||||||
6 => wire__crate__bridge__callbacks__init_flutter_callbacks_impl(port, ptr, rust_vec_len, data_len),
|
6 => wire__crate__bridge__callbacks__init_flutter_callbacks_impl(port, ptr, rust_vec_len, data_len),
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ impl<Store: UserDiscoveryStore, Utils: UserDiscoveryUtils> UserDiscovery<Store,
|
||||||
&self,
|
&self,
|
||||||
contact_id: UserID,
|
contact_id: UserID,
|
||||||
version: &[u8],
|
version: &[u8],
|
||||||
) -> Result<bool> {
|
) -> Result<Option<Vec<u8>>> {
|
||||||
let received_version = UserDiscoveryVersion::decode(version)?;
|
let received_version = UserDiscoveryVersion::decode(version)?;
|
||||||
let stored_version = match self.store.get_contact_version(contact_id).await? {
|
let stored_version = match self.store.get_contact_version(contact_id).await? {
|
||||||
Some(buf) => UserDiscoveryVersion::decode(buf.as_slice())?,
|
Some(buf) => UserDiscoveryVersion::decode(buf.as_slice())?,
|
||||||
|
|
@ -247,8 +247,13 @@ impl<Store: UserDiscoveryStore, Utils: UserDiscoveryUtils> UserDiscovery<Store,
|
||||||
stored.promotion = %stored_version.promotion,
|
stored.promotion = %stored_version.promotion,
|
||||||
"Comparing version numbers"
|
"Comparing version numbers"
|
||||||
);
|
);
|
||||||
Ok(received_version.announcement > stored_version.announcement
|
if received_version.announcement > stored_version.announcement
|
||||||
|| received_version.promotion > stored_version.promotion)
|
|| received_version.promotion > stored_version.promotion
|
||||||
|
{
|
||||||
|
Ok(Some(stored_version.encode_to_vec()))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn get_contact_version(&self, contact_id: UserID) -> Result<Option<Vec<u8>>> {
|
pub(crate) async fn get_contact_version(&self, contact_id: UserID) -> Result<Option<Vec<u8>>> {
|
||||||
|
|
@ -257,7 +262,7 @@ impl<Store: UserDiscoveryStore, Utils: UserDiscoveryUtils> UserDiscovery<Store,
|
||||||
|
|
||||||
/// Returns the latest version for this discovery.
|
/// Returns the latest version for this discovery.
|
||||||
/// Before calling this function the application must sure that contact_id is qualified to be announced.
|
/// Before calling this function the application must sure that contact_id is qualified to be announced.
|
||||||
pub async fn handle_user_discovery_messages(
|
pub async fn handle_new_messages(
|
||||||
&self,
|
&self,
|
||||||
contact_id: UserID,
|
contact_id: UserID,
|
||||||
messages: Vec<Vec<u8>>,
|
messages: Vec<Vec<u8>>,
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ async fn assert_new_messages<S: UserDiscoveryStore>(
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to.1.should_request_new_messages(from.0 as UserID, to_received_version)
|
to.1.should_request_new_messages(from.0 as UserID, to_received_version)
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.is_some(),
|
||||||
has_new_messages
|
has_new_messages
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +54,8 @@ async fn request_and_handle_messages<S: UserDiscoveryStore>(
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to.1.should_request_new_messages(from.0 as UserID, to_received_version)
|
to.1.should_request_new_messages(from.0 as UserID, to_received_version)
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.is_some(),
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -72,7 +74,7 @@ async fn request_and_handle_messages<S: UserDiscoveryStore>(
|
||||||
|
|
||||||
assert!(new_messages.len() <= messages_count);
|
assert!(new_messages.len() <= messages_count);
|
||||||
|
|
||||||
to.1.handle_user_discovery_messages(from.0 as UserID, new_messages)
|
to.1.handle_new_messages(from.0 as UserID, new_messages)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
@ -82,7 +84,8 @@ async fn request_and_handle_messages<S: UserDiscoveryStore>(
|
||||||
&from.1.get_current_version().await.unwrap()
|
&from.1.get_current_version().await.unwrap()
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
|
.is_some(),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import 'schema_v10.dart' as v10;
|
||||||
import 'schema_v11.dart' as v11;
|
import 'schema_v11.dart' as v11;
|
||||||
import 'schema_v12.dart' as v12;
|
import 'schema_v12.dart' as v12;
|
||||||
import 'schema_v13.dart' as v13;
|
import 'schema_v13.dart' as v13;
|
||||||
|
import 'schema_v14.dart' as v14;
|
||||||
|
|
||||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
@override
|
@override
|
||||||
|
|
@ -48,10 +49,12 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
return v12.DatabaseAtV12(db);
|
return v12.DatabaseAtV12(db);
|
||||||
case 13:
|
case 13:
|
||||||
return v13.DatabaseAtV13(db);
|
return v13.DatabaseAtV13(db);
|
||||||
|
case 14:
|
||||||
|
return v14.DatabaseAtV14(db);
|
||||||
default:
|
default:
|
||||||
throw MissingSchemaException(version, versions);
|
throw MissingSchemaException(version, versions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
|
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9556
test/drift/twonly_db/generated/schema_v14.dart
Normal file
9556
test/drift/twonly_db/generated/schema_v14.dart
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue