mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 20:38:40 +00:00
fixing issue with the prekey unkown error
This commit is contained in:
parent
97d7281f4d
commit
ba1913d737
14 changed files with 4480 additions and 197 deletions
|
|
@ -3,14 +3,14 @@
|
||||||
## 0.0.61
|
## 0.0.61
|
||||||
|
|
||||||
- Fixing message decryption error
|
- Fixing message decryption error
|
||||||
|
- Fixing issue with user deletion
|
||||||
|
- Fixing issue with flame counter sync
|
||||||
- Dependency and Flutter upgrade
|
- Dependency and Flutter upgrade
|
||||||
|
- Developer Settings
|
||||||
|
|
||||||
## 0.0.60
|
## 0.0.60
|
||||||
|
|
||||||
- Improved logging to debug the 'Tap to load' issue.
|
- Improved logging to debug the 'Tap to load' issue.
|
||||||
|
|
||||||
==> If you encounter any issues, please send your debug log via the feedback button along with a short description of the error so that we can resolve them. :)
|
|
||||||
|
|
||||||
- Display your own avatar in the title bar of the chat list.
|
- Display your own avatar in the title bar of the chat list.
|
||||||
- Created a default avatar image in case none was set.
|
- Created a default avatar image in case none was set.
|
||||||
- Improved UI handling when requesting microphone access for the first time.
|
- Improved UI handling when requesting microphone access for the first time.
|
||||||
|
|
|
||||||
1
drift_schemas/twonly_database/drift_schema_v17.json
Normal file
1
drift_schemas/twonly_database/drift_schema_v17.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -195,6 +195,16 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
return select(contacts).watch();
|
return select(contacts).watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> modifyFlameCounterForTesting() async {
|
||||||
|
await update(contacts).write(
|
||||||
|
ContactsCompanion(
|
||||||
|
lastFlameCounterChange: Value(DateTime.now()),
|
||||||
|
flameCounter: const Value(1337),
|
||||||
|
lastFlameSync: const Value(null),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Stream<int> watchFlameCounter(int userId) {
|
Stream<int> watchFlameCounter(int userId) {
|
||||||
return (select(contacts)
|
return (select(contacts)
|
||||||
..where(
|
..where(
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,16 @@ class SignalDao extends DatabaseAccessor<TwonlyDatabase> with _$SignalDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> purgeOutDatedPreKeys() async {
|
Future<void> purgeOutDatedPreKeys() async {
|
||||||
|
// Deletion is a workaround for the issue, that own pre keys where deleted after 40 days, while they could be 30days
|
||||||
|
// on the server + 25 days on the others device old, resulting in the issue that the receiver could not decrypt the
|
||||||
|
// messages...
|
||||||
|
await (delete(signalContactSignedPreKeys)
|
||||||
|
..where(
|
||||||
|
(t) => (t.createdAt.isSmallerThanValue(
|
||||||
|
DateTime(2025, 10, 10),
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
.go();
|
||||||
// other pre keys are valid 100 days
|
// other pre keys are valid 100 days
|
||||||
await (delete(signalContactSignedPreKeys)
|
await (delete(signalContactSignedPreKeys)
|
||||||
..where(
|
..where(
|
||||||
|
|
|
||||||
|
|
@ -16,5 +16,8 @@ class MessageRetransmissions extends Table {
|
||||||
BlobColumn get pushData => blob().nullable()();
|
BlobColumn get pushData => blob().nullable()();
|
||||||
BlobColumn get encryptedHash => blob().nullable()();
|
BlobColumn get encryptedHash => blob().nullable()();
|
||||||
|
|
||||||
|
IntColumn get retryCount => integer().withDefault(const Constant(0))();
|
||||||
|
DateTimeColumn get lastRetry => dateTime().nullable()();
|
||||||
|
|
||||||
DateTimeColumn get acknowledgeByServerAt => dateTime().nullable()();
|
DateTimeColumn get acknowledgeByServerAt => dateTime().nullable()();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
||||||
TwonlyDatabase.forTesting(DatabaseConnection super.connection);
|
TwonlyDatabase.forTesting(DatabaseConnection super.connection);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 16;
|
int get schemaVersion => 17;
|
||||||
|
|
||||||
static QueryExecutor _openConnection() {
|
static QueryExecutor _openConnection() {
|
||||||
return driftDatabase(
|
return driftDatabase(
|
||||||
|
|
@ -157,6 +157,12 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
||||||
from15To16: (m, schema) async {
|
from15To16: (m, schema) async {
|
||||||
await m.deleteTable('media_downloads');
|
await m.deleteTable('media_downloads');
|
||||||
},
|
},
|
||||||
|
from16To17: (m, schema) async {
|
||||||
|
await m.addColumn(schema.messageRetransmissions,
|
||||||
|
schema.messageRetransmissions.lastRetry);
|
||||||
|
await m.addColumn(schema.messageRetransmissions,
|
||||||
|
schema.messageRetransmissions.retryCount);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3983,6 +3983,20 @@ class $MessageRetransmissionsTable extends MessageRetransmissions
|
||||||
late final GeneratedColumn<Uint8List> encryptedHash =
|
late final GeneratedColumn<Uint8List> encryptedHash =
|
||||||
GeneratedColumn<Uint8List>('encrypted_hash', aliasedName, true,
|
GeneratedColumn<Uint8List>('encrypted_hash', aliasedName, true,
|
||||||
type: DriftSqlType.blob, requiredDuringInsert: false);
|
type: DriftSqlType.blob, requiredDuringInsert: false);
|
||||||
|
static const VerificationMeta _retryCountMeta =
|
||||||
|
const VerificationMeta('retryCount');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> retryCount = GeneratedColumn<int>(
|
||||||
|
'retry_count', aliasedName, false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: const Constant(0));
|
||||||
|
static const VerificationMeta _lastRetryMeta =
|
||||||
|
const VerificationMeta('lastRetry');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<DateTime> lastRetry = GeneratedColumn<DateTime>(
|
||||||
|
'last_retry', aliasedName, true,
|
||||||
|
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _acknowledgeByServerAtMeta =
|
static const VerificationMeta _acknowledgeByServerAtMeta =
|
||||||
const VerificationMeta('acknowledgeByServerAt');
|
const VerificationMeta('acknowledgeByServerAt');
|
||||||
@override
|
@override
|
||||||
|
|
@ -3997,6 +4011,8 @@ class $MessageRetransmissionsTable extends MessageRetransmissions
|
||||||
plaintextContent,
|
plaintextContent,
|
||||||
pushData,
|
pushData,
|
||||||
encryptedHash,
|
encryptedHash,
|
||||||
|
retryCount,
|
||||||
|
lastRetry,
|
||||||
acknowledgeByServerAt
|
acknowledgeByServerAt
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
|
|
@ -4044,6 +4060,16 @@ class $MessageRetransmissionsTable extends MessageRetransmissions
|
||||||
encryptedHash.isAcceptableOrUnknown(
|
encryptedHash.isAcceptableOrUnknown(
|
||||||
data['encrypted_hash']!, _encryptedHashMeta));
|
data['encrypted_hash']!, _encryptedHashMeta));
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('retry_count')) {
|
||||||
|
context.handle(
|
||||||
|
_retryCountMeta,
|
||||||
|
retryCount.isAcceptableOrUnknown(
|
||||||
|
data['retry_count']!, _retryCountMeta));
|
||||||
|
}
|
||||||
|
if (data.containsKey('last_retry')) {
|
||||||
|
context.handle(_lastRetryMeta,
|
||||||
|
lastRetry.isAcceptableOrUnknown(data['last_retry']!, _lastRetryMeta));
|
||||||
|
}
|
||||||
if (data.containsKey('acknowledge_by_server_at')) {
|
if (data.containsKey('acknowledge_by_server_at')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_acknowledgeByServerAtMeta,
|
_acknowledgeByServerAtMeta,
|
||||||
|
|
@ -4071,6 +4097,10 @@ class $MessageRetransmissionsTable extends MessageRetransmissions
|
||||||
.read(DriftSqlType.blob, data['${effectivePrefix}push_data']),
|
.read(DriftSqlType.blob, data['${effectivePrefix}push_data']),
|
||||||
encryptedHash: attachedDatabase.typeMapping
|
encryptedHash: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.blob, data['${effectivePrefix}encrypted_hash']),
|
.read(DriftSqlType.blob, data['${effectivePrefix}encrypted_hash']),
|
||||||
|
retryCount: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.int, data['${effectivePrefix}retry_count'])!,
|
||||||
|
lastRetry: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.dateTime, data['${effectivePrefix}last_retry']),
|
||||||
acknowledgeByServerAt: attachedDatabase.typeMapping.read(
|
acknowledgeByServerAt: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}acknowledge_by_server_at']),
|
data['${effectivePrefix}acknowledge_by_server_at']),
|
||||||
|
|
@ -4091,6 +4121,8 @@ class MessageRetransmission extends DataClass
|
||||||
final Uint8List plaintextContent;
|
final Uint8List plaintextContent;
|
||||||
final Uint8List? pushData;
|
final Uint8List? pushData;
|
||||||
final Uint8List? encryptedHash;
|
final Uint8List? encryptedHash;
|
||||||
|
final int retryCount;
|
||||||
|
final DateTime? lastRetry;
|
||||||
final DateTime? acknowledgeByServerAt;
|
final DateTime? acknowledgeByServerAt;
|
||||||
const MessageRetransmission(
|
const MessageRetransmission(
|
||||||
{required this.retransmissionId,
|
{required this.retransmissionId,
|
||||||
|
|
@ -4099,6 +4131,8 @@ class MessageRetransmission extends DataClass
|
||||||
required this.plaintextContent,
|
required this.plaintextContent,
|
||||||
this.pushData,
|
this.pushData,
|
||||||
this.encryptedHash,
|
this.encryptedHash,
|
||||||
|
required this.retryCount,
|
||||||
|
this.lastRetry,
|
||||||
this.acknowledgeByServerAt});
|
this.acknowledgeByServerAt});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
|
@ -4115,6 +4149,10 @@ class MessageRetransmission extends DataClass
|
||||||
if (!nullToAbsent || encryptedHash != null) {
|
if (!nullToAbsent || encryptedHash != null) {
|
||||||
map['encrypted_hash'] = Variable<Uint8List>(encryptedHash);
|
map['encrypted_hash'] = Variable<Uint8List>(encryptedHash);
|
||||||
}
|
}
|
||||||
|
map['retry_count'] = Variable<int>(retryCount);
|
||||||
|
if (!nullToAbsent || lastRetry != null) {
|
||||||
|
map['last_retry'] = Variable<DateTime>(lastRetry);
|
||||||
|
}
|
||||||
if (!nullToAbsent || acknowledgeByServerAt != null) {
|
if (!nullToAbsent || acknowledgeByServerAt != null) {
|
||||||
map['acknowledge_by_server_at'] =
|
map['acknowledge_by_server_at'] =
|
||||||
Variable<DateTime>(acknowledgeByServerAt);
|
Variable<DateTime>(acknowledgeByServerAt);
|
||||||
|
|
@ -4136,6 +4174,10 @@ class MessageRetransmission extends DataClass
|
||||||
encryptedHash: encryptedHash == null && nullToAbsent
|
encryptedHash: encryptedHash == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(encryptedHash),
|
: Value(encryptedHash),
|
||||||
|
retryCount: Value(retryCount),
|
||||||
|
lastRetry: lastRetry == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(lastRetry),
|
||||||
acknowledgeByServerAt: acknowledgeByServerAt == null && nullToAbsent
|
acknowledgeByServerAt: acknowledgeByServerAt == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(acknowledgeByServerAt),
|
: Value(acknowledgeByServerAt),
|
||||||
|
|
@ -4153,6 +4195,8 @@ class MessageRetransmission extends DataClass
|
||||||
serializer.fromJson<Uint8List>(json['plaintextContent']),
|
serializer.fromJson<Uint8List>(json['plaintextContent']),
|
||||||
pushData: serializer.fromJson<Uint8List?>(json['pushData']),
|
pushData: serializer.fromJson<Uint8List?>(json['pushData']),
|
||||||
encryptedHash: serializer.fromJson<Uint8List?>(json['encryptedHash']),
|
encryptedHash: serializer.fromJson<Uint8List?>(json['encryptedHash']),
|
||||||
|
retryCount: serializer.fromJson<int>(json['retryCount']),
|
||||||
|
lastRetry: serializer.fromJson<DateTime?>(json['lastRetry']),
|
||||||
acknowledgeByServerAt:
|
acknowledgeByServerAt:
|
||||||
serializer.fromJson<DateTime?>(json['acknowledgeByServerAt']),
|
serializer.fromJson<DateTime?>(json['acknowledgeByServerAt']),
|
||||||
);
|
);
|
||||||
|
|
@ -4167,6 +4211,8 @@ class MessageRetransmission extends DataClass
|
||||||
'plaintextContent': serializer.toJson<Uint8List>(plaintextContent),
|
'plaintextContent': serializer.toJson<Uint8List>(plaintextContent),
|
||||||
'pushData': serializer.toJson<Uint8List?>(pushData),
|
'pushData': serializer.toJson<Uint8List?>(pushData),
|
||||||
'encryptedHash': serializer.toJson<Uint8List?>(encryptedHash),
|
'encryptedHash': serializer.toJson<Uint8List?>(encryptedHash),
|
||||||
|
'retryCount': serializer.toJson<int>(retryCount),
|
||||||
|
'lastRetry': serializer.toJson<DateTime?>(lastRetry),
|
||||||
'acknowledgeByServerAt':
|
'acknowledgeByServerAt':
|
||||||
serializer.toJson<DateTime?>(acknowledgeByServerAt),
|
serializer.toJson<DateTime?>(acknowledgeByServerAt),
|
||||||
};
|
};
|
||||||
|
|
@ -4179,6 +4225,8 @@ class MessageRetransmission extends DataClass
|
||||||
Uint8List? plaintextContent,
|
Uint8List? plaintextContent,
|
||||||
Value<Uint8List?> pushData = const Value.absent(),
|
Value<Uint8List?> pushData = const Value.absent(),
|
||||||
Value<Uint8List?> encryptedHash = const Value.absent(),
|
Value<Uint8List?> encryptedHash = const Value.absent(),
|
||||||
|
int? retryCount,
|
||||||
|
Value<DateTime?> lastRetry = const Value.absent(),
|
||||||
Value<DateTime?> acknowledgeByServerAt = const Value.absent()}) =>
|
Value<DateTime?> acknowledgeByServerAt = const Value.absent()}) =>
|
||||||
MessageRetransmission(
|
MessageRetransmission(
|
||||||
retransmissionId: retransmissionId ?? this.retransmissionId,
|
retransmissionId: retransmissionId ?? this.retransmissionId,
|
||||||
|
|
@ -4188,6 +4236,8 @@ class MessageRetransmission extends DataClass
|
||||||
pushData: pushData.present ? pushData.value : this.pushData,
|
pushData: pushData.present ? pushData.value : this.pushData,
|
||||||
encryptedHash:
|
encryptedHash:
|
||||||
encryptedHash.present ? encryptedHash.value : this.encryptedHash,
|
encryptedHash.present ? encryptedHash.value : this.encryptedHash,
|
||||||
|
retryCount: retryCount ?? this.retryCount,
|
||||||
|
lastRetry: lastRetry.present ? lastRetry.value : this.lastRetry,
|
||||||
acknowledgeByServerAt: acknowledgeByServerAt.present
|
acknowledgeByServerAt: acknowledgeByServerAt.present
|
||||||
? acknowledgeByServerAt.value
|
? acknowledgeByServerAt.value
|
||||||
: this.acknowledgeByServerAt,
|
: this.acknowledgeByServerAt,
|
||||||
|
|
@ -4207,6 +4257,9 @@ class MessageRetransmission extends DataClass
|
||||||
encryptedHash: data.encryptedHash.present
|
encryptedHash: data.encryptedHash.present
|
||||||
? data.encryptedHash.value
|
? data.encryptedHash.value
|
||||||
: this.encryptedHash,
|
: this.encryptedHash,
|
||||||
|
retryCount:
|
||||||
|
data.retryCount.present ? data.retryCount.value : this.retryCount,
|
||||||
|
lastRetry: data.lastRetry.present ? data.lastRetry.value : this.lastRetry,
|
||||||
acknowledgeByServerAt: data.acknowledgeByServerAt.present
|
acknowledgeByServerAt: data.acknowledgeByServerAt.present
|
||||||
? data.acknowledgeByServerAt.value
|
? data.acknowledgeByServerAt.value
|
||||||
: this.acknowledgeByServerAt,
|
: this.acknowledgeByServerAt,
|
||||||
|
|
@ -4222,6 +4275,8 @@ class MessageRetransmission extends DataClass
|
||||||
..write('plaintextContent: $plaintextContent, ')
|
..write('plaintextContent: $plaintextContent, ')
|
||||||
..write('pushData: $pushData, ')
|
..write('pushData: $pushData, ')
|
||||||
..write('encryptedHash: $encryptedHash, ')
|
..write('encryptedHash: $encryptedHash, ')
|
||||||
|
..write('retryCount: $retryCount, ')
|
||||||
|
..write('lastRetry: $lastRetry, ')
|
||||||
..write('acknowledgeByServerAt: $acknowledgeByServerAt')
|
..write('acknowledgeByServerAt: $acknowledgeByServerAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
|
|
@ -4235,6 +4290,8 @@ class MessageRetransmission extends DataClass
|
||||||
$driftBlobEquality.hash(plaintextContent),
|
$driftBlobEquality.hash(plaintextContent),
|
||||||
$driftBlobEquality.hash(pushData),
|
$driftBlobEquality.hash(pushData),
|
||||||
$driftBlobEquality.hash(encryptedHash),
|
$driftBlobEquality.hash(encryptedHash),
|
||||||
|
retryCount,
|
||||||
|
lastRetry,
|
||||||
acknowledgeByServerAt);
|
acknowledgeByServerAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
|
|
@ -4247,6 +4304,8 @@ class MessageRetransmission extends DataClass
|
||||||
other.plaintextContent, this.plaintextContent) &&
|
other.plaintextContent, this.plaintextContent) &&
|
||||||
$driftBlobEquality.equals(other.pushData, this.pushData) &&
|
$driftBlobEquality.equals(other.pushData, this.pushData) &&
|
||||||
$driftBlobEquality.equals(other.encryptedHash, this.encryptedHash) &&
|
$driftBlobEquality.equals(other.encryptedHash, this.encryptedHash) &&
|
||||||
|
other.retryCount == this.retryCount &&
|
||||||
|
other.lastRetry == this.lastRetry &&
|
||||||
other.acknowledgeByServerAt == this.acknowledgeByServerAt);
|
other.acknowledgeByServerAt == this.acknowledgeByServerAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4258,6 +4317,8 @@ class MessageRetransmissionsCompanion
|
||||||
final Value<Uint8List> plaintextContent;
|
final Value<Uint8List> plaintextContent;
|
||||||
final Value<Uint8List?> pushData;
|
final Value<Uint8List?> pushData;
|
||||||
final Value<Uint8List?> encryptedHash;
|
final Value<Uint8List?> encryptedHash;
|
||||||
|
final Value<int> retryCount;
|
||||||
|
final Value<DateTime?> lastRetry;
|
||||||
final Value<DateTime?> acknowledgeByServerAt;
|
final Value<DateTime?> acknowledgeByServerAt;
|
||||||
const MessageRetransmissionsCompanion({
|
const MessageRetransmissionsCompanion({
|
||||||
this.retransmissionId = const Value.absent(),
|
this.retransmissionId = const Value.absent(),
|
||||||
|
|
@ -4266,6 +4327,8 @@ class MessageRetransmissionsCompanion
|
||||||
this.plaintextContent = const Value.absent(),
|
this.plaintextContent = const Value.absent(),
|
||||||
this.pushData = const Value.absent(),
|
this.pushData = const Value.absent(),
|
||||||
this.encryptedHash = const Value.absent(),
|
this.encryptedHash = const Value.absent(),
|
||||||
|
this.retryCount = const Value.absent(),
|
||||||
|
this.lastRetry = const Value.absent(),
|
||||||
this.acknowledgeByServerAt = const Value.absent(),
|
this.acknowledgeByServerAt = const Value.absent(),
|
||||||
});
|
});
|
||||||
MessageRetransmissionsCompanion.insert({
|
MessageRetransmissionsCompanion.insert({
|
||||||
|
|
@ -4275,6 +4338,8 @@ class MessageRetransmissionsCompanion
|
||||||
required Uint8List plaintextContent,
|
required Uint8List plaintextContent,
|
||||||
this.pushData = const Value.absent(),
|
this.pushData = const Value.absent(),
|
||||||
this.encryptedHash = const Value.absent(),
|
this.encryptedHash = const Value.absent(),
|
||||||
|
this.retryCount = const Value.absent(),
|
||||||
|
this.lastRetry = const Value.absent(),
|
||||||
this.acknowledgeByServerAt = const Value.absent(),
|
this.acknowledgeByServerAt = const Value.absent(),
|
||||||
}) : contactId = Value(contactId),
|
}) : contactId = Value(contactId),
|
||||||
plaintextContent = Value(plaintextContent);
|
plaintextContent = Value(plaintextContent);
|
||||||
|
|
@ -4285,6 +4350,8 @@ class MessageRetransmissionsCompanion
|
||||||
Expression<Uint8List>? plaintextContent,
|
Expression<Uint8List>? plaintextContent,
|
||||||
Expression<Uint8List>? pushData,
|
Expression<Uint8List>? pushData,
|
||||||
Expression<Uint8List>? encryptedHash,
|
Expression<Uint8List>? encryptedHash,
|
||||||
|
Expression<int>? retryCount,
|
||||||
|
Expression<DateTime>? lastRetry,
|
||||||
Expression<DateTime>? acknowledgeByServerAt,
|
Expression<DateTime>? acknowledgeByServerAt,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
|
|
@ -4294,6 +4361,8 @@ class MessageRetransmissionsCompanion
|
||||||
if (plaintextContent != null) 'plaintext_content': plaintextContent,
|
if (plaintextContent != null) 'plaintext_content': plaintextContent,
|
||||||
if (pushData != null) 'push_data': pushData,
|
if (pushData != null) 'push_data': pushData,
|
||||||
if (encryptedHash != null) 'encrypted_hash': encryptedHash,
|
if (encryptedHash != null) 'encrypted_hash': encryptedHash,
|
||||||
|
if (retryCount != null) 'retry_count': retryCount,
|
||||||
|
if (lastRetry != null) 'last_retry': lastRetry,
|
||||||
if (acknowledgeByServerAt != null)
|
if (acknowledgeByServerAt != null)
|
||||||
'acknowledge_by_server_at': acknowledgeByServerAt,
|
'acknowledge_by_server_at': acknowledgeByServerAt,
|
||||||
});
|
});
|
||||||
|
|
@ -4306,6 +4375,8 @@ class MessageRetransmissionsCompanion
|
||||||
Value<Uint8List>? plaintextContent,
|
Value<Uint8List>? plaintextContent,
|
||||||
Value<Uint8List?>? pushData,
|
Value<Uint8List?>? pushData,
|
||||||
Value<Uint8List?>? encryptedHash,
|
Value<Uint8List?>? encryptedHash,
|
||||||
|
Value<int>? retryCount,
|
||||||
|
Value<DateTime?>? lastRetry,
|
||||||
Value<DateTime?>? acknowledgeByServerAt}) {
|
Value<DateTime?>? acknowledgeByServerAt}) {
|
||||||
return MessageRetransmissionsCompanion(
|
return MessageRetransmissionsCompanion(
|
||||||
retransmissionId: retransmissionId ?? this.retransmissionId,
|
retransmissionId: retransmissionId ?? this.retransmissionId,
|
||||||
|
|
@ -4314,6 +4385,8 @@ class MessageRetransmissionsCompanion
|
||||||
plaintextContent: plaintextContent ?? this.plaintextContent,
|
plaintextContent: plaintextContent ?? this.plaintextContent,
|
||||||
pushData: pushData ?? this.pushData,
|
pushData: pushData ?? this.pushData,
|
||||||
encryptedHash: encryptedHash ?? this.encryptedHash,
|
encryptedHash: encryptedHash ?? this.encryptedHash,
|
||||||
|
retryCount: retryCount ?? this.retryCount,
|
||||||
|
lastRetry: lastRetry ?? this.lastRetry,
|
||||||
acknowledgeByServerAt:
|
acknowledgeByServerAt:
|
||||||
acknowledgeByServerAt ?? this.acknowledgeByServerAt,
|
acknowledgeByServerAt ?? this.acknowledgeByServerAt,
|
||||||
);
|
);
|
||||||
|
|
@ -4340,6 +4413,12 @@ class MessageRetransmissionsCompanion
|
||||||
if (encryptedHash.present) {
|
if (encryptedHash.present) {
|
||||||
map['encrypted_hash'] = Variable<Uint8List>(encryptedHash.value);
|
map['encrypted_hash'] = Variable<Uint8List>(encryptedHash.value);
|
||||||
}
|
}
|
||||||
|
if (retryCount.present) {
|
||||||
|
map['retry_count'] = Variable<int>(retryCount.value);
|
||||||
|
}
|
||||||
|
if (lastRetry.present) {
|
||||||
|
map['last_retry'] = Variable<DateTime>(lastRetry.value);
|
||||||
|
}
|
||||||
if (acknowledgeByServerAt.present) {
|
if (acknowledgeByServerAt.present) {
|
||||||
map['acknowledge_by_server_at'] =
|
map['acknowledge_by_server_at'] =
|
||||||
Variable<DateTime>(acknowledgeByServerAt.value);
|
Variable<DateTime>(acknowledgeByServerAt.value);
|
||||||
|
|
@ -4356,6 +4435,8 @@ class MessageRetransmissionsCompanion
|
||||||
..write('plaintextContent: $plaintextContent, ')
|
..write('plaintextContent: $plaintextContent, ')
|
||||||
..write('pushData: $pushData, ')
|
..write('pushData: $pushData, ')
|
||||||
..write('encryptedHash: $encryptedHash, ')
|
..write('encryptedHash: $encryptedHash, ')
|
||||||
|
..write('retryCount: $retryCount, ')
|
||||||
|
..write('lastRetry: $lastRetry, ')
|
||||||
..write('acknowledgeByServerAt: $acknowledgeByServerAt')
|
..write('acknowledgeByServerAt: $acknowledgeByServerAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
|
|
@ -6752,6 +6833,8 @@ typedef $$MessageRetransmissionsTableCreateCompanionBuilder
|
||||||
required Uint8List plaintextContent,
|
required Uint8List plaintextContent,
|
||||||
Value<Uint8List?> pushData,
|
Value<Uint8List?> pushData,
|
||||||
Value<Uint8List?> encryptedHash,
|
Value<Uint8List?> encryptedHash,
|
||||||
|
Value<int> retryCount,
|
||||||
|
Value<DateTime?> lastRetry,
|
||||||
Value<DateTime?> acknowledgeByServerAt,
|
Value<DateTime?> acknowledgeByServerAt,
|
||||||
});
|
});
|
||||||
typedef $$MessageRetransmissionsTableUpdateCompanionBuilder
|
typedef $$MessageRetransmissionsTableUpdateCompanionBuilder
|
||||||
|
|
@ -6762,6 +6845,8 @@ typedef $$MessageRetransmissionsTableUpdateCompanionBuilder
|
||||||
Value<Uint8List> plaintextContent,
|
Value<Uint8List> plaintextContent,
|
||||||
Value<Uint8List?> pushData,
|
Value<Uint8List?> pushData,
|
||||||
Value<Uint8List?> encryptedHash,
|
Value<Uint8List?> encryptedHash,
|
||||||
|
Value<int> retryCount,
|
||||||
|
Value<DateTime?> lastRetry,
|
||||||
Value<DateTime?> acknowledgeByServerAt,
|
Value<DateTime?> acknowledgeByServerAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -6824,6 +6909,12 @@ class $$MessageRetransmissionsTableFilterComposer
|
||||||
ColumnFilters<Uint8List> get encryptedHash => $composableBuilder(
|
ColumnFilters<Uint8List> get encryptedHash => $composableBuilder(
|
||||||
column: $table.encryptedHash, builder: (column) => ColumnFilters(column));
|
column: $table.encryptedHash, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<int> get retryCount => $composableBuilder(
|
||||||
|
column: $table.retryCount, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get lastRetry => $composableBuilder(
|
||||||
|
column: $table.lastRetry, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
ColumnFilters<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
||||||
column: $table.acknowledgeByServerAt,
|
column: $table.acknowledgeByServerAt,
|
||||||
builder: (column) => ColumnFilters(column));
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
@ -6893,6 +6984,12 @@ class $$MessageRetransmissionsTableOrderingComposer
|
||||||
column: $table.encryptedHash,
|
column: $table.encryptedHash,
|
||||||
builder: (column) => ColumnOrderings(column));
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<int> get retryCount => $composableBuilder(
|
||||||
|
column: $table.retryCount, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get lastRetry => $composableBuilder(
|
||||||
|
column: $table.lastRetry, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
ColumnOrderings<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
||||||
column: $table.acknowledgeByServerAt,
|
column: $table.acknowledgeByServerAt,
|
||||||
builder: (column) => ColumnOrderings(column));
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
@ -6959,6 +7056,12 @@ class $$MessageRetransmissionsTableAnnotationComposer
|
||||||
GeneratedColumn<Uint8List> get encryptedHash => $composableBuilder(
|
GeneratedColumn<Uint8List> get encryptedHash => $composableBuilder(
|
||||||
column: $table.encryptedHash, builder: (column) => column);
|
column: $table.encryptedHash, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get retryCount => $composableBuilder(
|
||||||
|
column: $table.retryCount, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get lastRetry =>
|
||||||
|
$composableBuilder(column: $table.lastRetry, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
GeneratedColumn<DateTime> get acknowledgeByServerAt => $composableBuilder(
|
||||||
column: $table.acknowledgeByServerAt, builder: (column) => column);
|
column: $table.acknowledgeByServerAt, builder: (column) => column);
|
||||||
|
|
||||||
|
|
@ -7036,6 +7139,8 @@ class $$MessageRetransmissionsTableTableManager extends RootTableManager<
|
||||||
Value<Uint8List> plaintextContent = const Value.absent(),
|
Value<Uint8List> plaintextContent = const Value.absent(),
|
||||||
Value<Uint8List?> pushData = const Value.absent(),
|
Value<Uint8List?> pushData = const Value.absent(),
|
||||||
Value<Uint8List?> encryptedHash = const Value.absent(),
|
Value<Uint8List?> encryptedHash = const Value.absent(),
|
||||||
|
Value<int> retryCount = const Value.absent(),
|
||||||
|
Value<DateTime?> lastRetry = const Value.absent(),
|
||||||
Value<DateTime?> acknowledgeByServerAt = const Value.absent(),
|
Value<DateTime?> acknowledgeByServerAt = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
MessageRetransmissionsCompanion(
|
MessageRetransmissionsCompanion(
|
||||||
|
|
@ -7045,6 +7150,8 @@ class $$MessageRetransmissionsTableTableManager extends RootTableManager<
|
||||||
plaintextContent: plaintextContent,
|
plaintextContent: plaintextContent,
|
||||||
pushData: pushData,
|
pushData: pushData,
|
||||||
encryptedHash: encryptedHash,
|
encryptedHash: encryptedHash,
|
||||||
|
retryCount: retryCount,
|
||||||
|
lastRetry: lastRetry,
|
||||||
acknowledgeByServerAt: acknowledgeByServerAt,
|
acknowledgeByServerAt: acknowledgeByServerAt,
|
||||||
),
|
),
|
||||||
createCompanionCallback: ({
|
createCompanionCallback: ({
|
||||||
|
|
@ -7054,6 +7161,8 @@ class $$MessageRetransmissionsTableTableManager extends RootTableManager<
|
||||||
required Uint8List plaintextContent,
|
required Uint8List plaintextContent,
|
||||||
Value<Uint8List?> pushData = const Value.absent(),
|
Value<Uint8List?> pushData = const Value.absent(),
|
||||||
Value<Uint8List?> encryptedHash = const Value.absent(),
|
Value<Uint8List?> encryptedHash = const Value.absent(),
|
||||||
|
Value<int> retryCount = const Value.absent(),
|
||||||
|
Value<DateTime?> lastRetry = const Value.absent(),
|
||||||
Value<DateTime?> acknowledgeByServerAt = const Value.absent(),
|
Value<DateTime?> acknowledgeByServerAt = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
MessageRetransmissionsCompanion.insert(
|
MessageRetransmissionsCompanion.insert(
|
||||||
|
|
@ -7063,6 +7172,8 @@ class $$MessageRetransmissionsTableTableManager extends RootTableManager<
|
||||||
plaintextContent: plaintextContent,
|
plaintextContent: plaintextContent,
|
||||||
pushData: pushData,
|
pushData: pushData,
|
||||||
encryptedHash: encryptedHash,
|
encryptedHash: encryptedHash,
|
||||||
|
retryCount: retryCount,
|
||||||
|
lastRetry: lastRetry,
|
||||||
acknowledgeByServerAt: acknowledgeByServerAt,
|
acknowledgeByServerAt: acknowledgeByServerAt,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
|
|
|
||||||
|
|
@ -3713,6 +3713,253 @@ final class Schema16 extends i0.VersionedSchema {
|
||||||
alias: null);
|
alias: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class Schema17 extends i0.VersionedSchema {
|
||||||
|
Schema17({required super.database}) : super(version: 17);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
contacts,
|
||||||
|
messages,
|
||||||
|
mediaUploads,
|
||||||
|
signalIdentityKeyStores,
|
||||||
|
signalPreKeyStores,
|
||||||
|
signalSenderKeyStores,
|
||||||
|
signalSessionStores,
|
||||||
|
signalContactPreKeys,
|
||||||
|
signalContactSignedPreKeys,
|
||||||
|
messageRetransmissions,
|
||||||
|
];
|
||||||
|
late final Shape13 contacts = Shape13(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'contacts',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(user_id)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_3,
|
||||||
|
_column_4,
|
||||||
|
_column_5,
|
||||||
|
_column_6,
|
||||||
|
_column_7,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_39,
|
||||||
|
_column_53,
|
||||||
|
_column_57,
|
||||||
|
_column_54,
|
||||||
|
_column_40,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_13,
|
||||||
|
_column_14,
|
||||||
|
_column_55,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape19 messages = Shape19(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'messages',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_17,
|
||||||
|
_column_18,
|
||||||
|
_column_19,
|
||||||
|
_column_48,
|
||||||
|
_column_49,
|
||||||
|
_column_20,
|
||||||
|
_column_21,
|
||||||
|
_column_22,
|
||||||
|
_column_52,
|
||||||
|
_column_23,
|
||||||
|
_column_24,
|
||||||
|
_column_25,
|
||||||
|
_column_70,
|
||||||
|
_column_26,
|
||||||
|
_column_27,
|
||||||
|
_column_28,
|
||||||
|
_column_29,
|
||||||
|
_column_30,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape20 mediaUploads = Shape20(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'media_uploads',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_41,
|
||||||
|
_column_42,
|
||||||
|
_column_56,
|
||||||
|
_column_44,
|
||||||
|
_column_45,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape2 signalIdentityKeyStores = Shape2(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_identity_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(device_id, name)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_31,
|
||||||
|
_column_32,
|
||||||
|
_column_33,
|
||||||
|
_column_10,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape3 signalPreKeyStores = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_pre_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(pre_key_id)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_34,
|
||||||
|
_column_35,
|
||||||
|
_column_10,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape4 signalSenderKeyStores = Shape4(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_sender_key_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(sender_key_name)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_36,
|
||||||
|
_column_37,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape5 signalSessionStores = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_session_stores',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(device_id, name)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_31,
|
||||||
|
_column_32,
|
||||||
|
_column_38,
|
||||||
|
_column_10,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape14 signalContactPreKeys = Shape14(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_contact_pre_keys',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(contact_id, pre_key_id)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_58,
|
||||||
|
_column_34,
|
||||||
|
_column_35,
|
||||||
|
_column_10,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape15 signalContactSignedPreKeys = Shape15(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'signal_contact_signed_pre_keys',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [
|
||||||
|
'PRIMARY KEY(contact_id)',
|
||||||
|
],
|
||||||
|
columns: [
|
||||||
|
_column_58,
|
||||||
|
_column_59,
|
||||||
|
_column_60,
|
||||||
|
_column_61,
|
||||||
|
_column_10,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape21 messageRetransmissions = Shape21(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'message_retransmissions',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_62,
|
||||||
|
_column_63,
|
||||||
|
_column_64,
|
||||||
|
_column_65,
|
||||||
|
_column_66,
|
||||||
|
_column_69,
|
||||||
|
_column_71,
|
||||||
|
_column_72,
|
||||||
|
_column_67,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape21 extends i0.VersionedTable {
|
||||||
|
Shape21({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get retransmissionId =>
|
||||||
|
columnsByName['retransmission_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get contactId =>
|
||||||
|
columnsByName['contact_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get messageId =>
|
||||||
|
columnsByName['message_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get plaintextContent =>
|
||||||
|
columnsByName['plaintext_content']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get pushData =>
|
||||||
|
columnsByName['push_data']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get encryptedHash =>
|
||||||
|
columnsByName['encrypted_hash']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<int> get retryCount =>
|
||||||
|
columnsByName['retry_count']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get lastRetry =>
|
||||||
|
columnsByName['last_retry']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<DateTime> get acknowledgeByServerAt =>
|
||||||
|
columnsByName['acknowledge_by_server_at']!
|
||||||
|
as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_71(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('retry_count', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int, defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<DateTime> _column_72(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('last_retry', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
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,
|
||||||
|
|
@ -3729,6 +3976,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
}) {
|
}) {
|
||||||
return (currentVersion, database) async {
|
return (currentVersion, database) async {
|
||||||
switch (currentVersion) {
|
switch (currentVersion) {
|
||||||
|
|
@ -3807,6 +4055,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
final migrator = i1.Migrator(database, schema);
|
final migrator = i1.Migrator(database, schema);
|
||||||
await from15To16(migrator, schema);
|
await from15To16(migrator, schema);
|
||||||
return 16;
|
return 16;
|
||||||
|
case 16:
|
||||||
|
final schema = Schema17(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from16To17(migrator, schema);
|
||||||
|
return 17;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
}
|
}
|
||||||
|
|
@ -3829,6 +4082,7 @@ i1.OnUpgrade stepByStep({
|
||||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
}) =>
|
}) =>
|
||||||
i0.VersionedSchema.stepByStepHelper(
|
i0.VersionedSchema.stepByStepHelper(
|
||||||
step: migrationSteps(
|
step: migrationSteps(
|
||||||
|
|
@ -3847,4 +4101,5 @@ i1.OnUpgrade stepByStep({
|
||||||
from13To14: from13To14,
|
from13To14: from13To14,
|
||||||
from14To15: from14To15,
|
from14To15: from14To15,
|
||||||
from15To16: from15To16,
|
from15To16: from15To16,
|
||||||
|
from16To17: from16To17,
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ Future<void> sendRetransmitMessage(int retransId) async {
|
||||||
.getSingleOrNull();
|
.getSingleOrNull();
|
||||||
if (contact == null || contact.deleted) {
|
if (contact == null || contact.deleted) {
|
||||||
Log.warn('Contact deleted $retransId or not found in database.');
|
Log.warn('Contact deleted $retransId or not found in database.');
|
||||||
|
await twonlyDB.messageRetransmissionDao
|
||||||
|
.deleteRetransmissionById(retransId);
|
||||||
if (retrans.messageId != null) {
|
if (retrans.messageId != null) {
|
||||||
await twonlyDB.messagesDao.updateMessageByMessageId(
|
await twonlyDB.messagesDao.updateMessageByMessageId(
|
||||||
retrans.messageId!,
|
retrans.messageId!,
|
||||||
|
|
@ -142,6 +144,8 @@ Future<void> sendRetransmitMessage(int retransId) async {
|
||||||
retransId,
|
retransId,
|
||||||
MessageRetransmissionsCompanion(
|
MessageRetransmissionsCompanion(
|
||||||
acknowledgeByServerAt: Value(DateTime.now()),
|
acknowledgeByServerAt: Value(DateTime.now()),
|
||||||
|
retryCount: Value(retrans.retryCount + 1),
|
||||||
|
lastRetry: Value(DateTime.now()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
|
||||||
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
||||||
response = await handleNewMessage(fromUserId, body);
|
response = await handleNewMessage(fromUserId, body);
|
||||||
} else {
|
} else {
|
||||||
Log.error('Got a new message from the server: $msg');
|
Log.error('Got a unknown message from the server: $msg');
|
||||||
response = client.Response()..error = ErrorCode.InternalError;
|
response = client.Response()..error = ErrorCode.InternalError;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -90,26 +90,10 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
return client.Response()..ok = ok;
|
return client.Response()..ok = ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.Response? result;
|
||||||
|
|
||||||
Log.info('Got: ${message.kind} from $fromUserId');
|
Log.info('Got: ${message.kind} from $fromUserId');
|
||||||
|
|
||||||
if (messageGetsAck(message.kind) && message.retransId != null) {
|
|
||||||
Log.info('Sending ACK for ${message.kind}');
|
|
||||||
|
|
||||||
/// ACK every message
|
|
||||||
await encryptAndSendMessageAsync(
|
|
||||||
null,
|
|
||||||
fromUserId,
|
|
||||||
MessageJson(
|
|
||||||
kind: MessageKind.ack,
|
|
||||||
content: AckContent(
|
|
||||||
messageIdToAck: message.messageSenderId,
|
|
||||||
retransIdToAck: message.retransId!,
|
|
||||||
),
|
|
||||||
timestamp: DateTime.now(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message.kind) {
|
switch (message.kind) {
|
||||||
case MessageKind.ack:
|
case MessageKind.ack:
|
||||||
final content = message.content;
|
final content = message.content;
|
||||||
|
|
@ -125,7 +109,6 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
update,
|
update,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await twonlyDB.messageRetransmissionDao
|
await twonlyDB.messageRetransmissionDao
|
||||||
.deleteRetransmissionById(content.retransIdToAck);
|
.deleteRetransmissionById(content.retransIdToAck);
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +132,7 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
case MessageKind.contactRequest:
|
case MessageKind.contactRequest:
|
||||||
return handleContactRequest(fromUserId, message);
|
await handleContactRequest(fromUserId, message);
|
||||||
|
|
||||||
case MessageKind.flameSync:
|
case MessageKind.flameSync:
|
||||||
final contact = await twonlyDB.contactsDao
|
final contact = await twonlyDB.contactsDao
|
||||||
|
|
@ -165,7 +148,6 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
isToday(content.lastFlameCounterChange)) {
|
isToday(content.lastFlameCounterChange)) {
|
||||||
if (content.flameCounter > contact.flameCounter) {
|
if (content.flameCounter > contact.flameCounter) {
|
||||||
updates = ContactsCompanion(
|
updates = ContactsCompanion(
|
||||||
alsoBestFriend: Value(content.bestFriend),
|
|
||||||
flameCounter: Value(content.flameCounter),
|
flameCounter: Value(content.flameCounter),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -283,164 +265,194 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
|
|
||||||
// ignore: no_default_cases
|
// ignore: no_default_cases
|
||||||
default:
|
default:
|
||||||
if (message.kind != MessageKind.textMessage &&
|
if (message.messageSenderId == null) {
|
||||||
message.kind != MessageKind.media &&
|
|
||||||
message.kind != MessageKind.storedMediaFile &&
|
|
||||||
message.kind != MessageKind.reopenedMedia) {
|
|
||||||
Log.error('Got unknown MessageKind $message');
|
|
||||||
} else if (message.messageSenderId == null) {
|
|
||||||
Log.error('Messageid not defined $message');
|
Log.error('Messageid not defined $message');
|
||||||
|
} else if ([
|
||||||
|
MessageKind.textMessage,
|
||||||
|
MessageKind.media,
|
||||||
|
MessageKind.storedMediaFile,
|
||||||
|
MessageKind.reopenedMedia,
|
||||||
|
].contains(message.kind)) {
|
||||||
|
result = await handleMediaOrTextMessage(fromUserId, message);
|
||||||
} else {
|
} else {
|
||||||
if (message.kind == MessageKind.storedMediaFile) {
|
Log.error('Got unknown MessageKind $message');
|
||||||
if (message.messageReceiverId != null) {
|
|
||||||
/// stored media file just updates the message
|
|
||||||
await twonlyDB.messagesDao.updateMessageByOtherUser(
|
|
||||||
fromUserId,
|
|
||||||
message.messageReceiverId!,
|
|
||||||
const MessagesCompanion(
|
|
||||||
mediaStored: Value(true),
|
|
||||||
errorWhileSending: Value(false),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final msg = await twonlyDB.messagesDao
|
|
||||||
.getMessageByIdAndContactId(
|
|
||||||
fromUserId,
|
|
||||||
message.messageReceiverId!,
|
|
||||||
)
|
|
||||||
.getSingleOrNull();
|
|
||||||
if (msg != null && msg.mediaUploadId != null) {
|
|
||||||
final filePath =
|
|
||||||
await getMediaFilePath(msg.mediaUploadId, 'send');
|
|
||||||
if (filePath.contains('mp4')) {
|
|
||||||
unawaited(createThumbnailsForVideo(File(filePath)));
|
|
||||||
} else {
|
|
||||||
unawaited(createThumbnailsForImage(File(filePath)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (message.content != null) {
|
|
||||||
final content = message.content!;
|
|
||||||
// when a message is received doubled ignore it...
|
|
||||||
|
|
||||||
final openedMessage = await twonlyDB.messagesDao
|
|
||||||
.getMessageByOtherMessageId(fromUserId, message.messageSenderId!)
|
|
||||||
.getSingleOrNull();
|
|
||||||
|
|
||||||
if (openedMessage != null) {
|
|
||||||
if (openedMessage.errorWhileSending) {
|
|
||||||
await twonlyDB.messagesDao
|
|
||||||
.deleteMessagesByMessageId(openedMessage.messageId);
|
|
||||||
} else {
|
|
||||||
Log.error(
|
|
||||||
'Got a duplicated message from other user: ${message.messageSenderId!}',
|
|
||||||
);
|
|
||||||
final ok = client.Response_Ok()..none = true;
|
|
||||||
return client.Response()..ok = ok;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int? responseToMessageId;
|
|
||||||
int? responseToOtherMessageId;
|
|
||||||
int? messageId;
|
|
||||||
|
|
||||||
var acknowledgeByUser = false;
|
|
||||||
DateTime? openedAt;
|
|
||||||
|
|
||||||
if (message.kind == MessageKind.reopenedMedia) {
|
|
||||||
acknowledgeByUser = true;
|
|
||||||
openedAt = DateTime.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content is TextMessageContent) {
|
|
||||||
responseToMessageId = content.responseToMessageId;
|
|
||||||
responseToOtherMessageId = content.responseToOtherMessageId;
|
|
||||||
|
|
||||||
if (responseToMessageId != null ||
|
|
||||||
responseToOtherMessageId != null) {
|
|
||||||
// reactions are shown in the notification directly...
|
|
||||||
if (isEmoji(content.text)) {
|
|
||||||
openedAt = DateTime.now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (content is ReopenedMediaFileContent) {
|
|
||||||
responseToMessageId = content.messageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (responseToMessageId != null) {
|
|
||||||
await twonlyDB.messagesDao.updateMessageByOtherUser(
|
|
||||||
fromUserId,
|
|
||||||
responseToMessageId,
|
|
||||||
MessagesCompanion(
|
|
||||||
errorWhileSending: const Value(false),
|
|
||||||
openedAt: Value(
|
|
||||||
DateTime.now(),
|
|
||||||
), // when a user reacted to the media file, it should be marked as opened
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final contentJson = jsonEncode(content.toJson());
|
|
||||||
final update = MessagesCompanion(
|
|
||||||
contactId: Value(fromUserId),
|
|
||||||
kind: Value(message.kind),
|
|
||||||
messageOtherId: Value(message.messageSenderId),
|
|
||||||
contentJson: Value(contentJson),
|
|
||||||
acknowledgeByServer: const Value(true),
|
|
||||||
acknowledgeByUser: Value(acknowledgeByUser),
|
|
||||||
responseToMessageId: Value(responseToMessageId),
|
|
||||||
responseToOtherMessageId: Value(responseToOtherMessageId),
|
|
||||||
openedAt: Value(openedAt),
|
|
||||||
downloadState: Value(
|
|
||||||
message.kind == MessageKind.media
|
|
||||||
? DownloadState.pending
|
|
||||||
: DownloadState.downloaded,
|
|
||||||
),
|
|
||||||
sendAt: Value(message.timestamp),
|
|
||||||
);
|
|
||||||
|
|
||||||
messageId = await twonlyDB.messagesDao.insertMessage(
|
|
||||||
update,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (messageId == null) {
|
|
||||||
Log.error('could not insert message into db');
|
|
||||||
return client.Response()..error = ErrorCode.InternalError;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.info('Inserted a new message with id: $messageId');
|
|
||||||
|
|
||||||
if (message.kind == MessageKind.media) {
|
|
||||||
await twonlyDB.contactsDao.incFlameCounter(
|
|
||||||
fromUserId,
|
|
||||||
true,
|
|
||||||
message.timestamp,
|
|
||||||
);
|
|
||||||
|
|
||||||
final msg = await twonlyDB.messagesDao
|
|
||||||
.getMessageByMessageId(messageId)
|
|
||||||
.getSingleOrNull();
|
|
||||||
if (msg != null) {
|
|
||||||
unawaited(startDownloadMedia(msg, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.error('Content is not defined $message');
|
|
||||||
}
|
|
||||||
|
|
||||||
// unarchive contact when receiving a new message
|
|
||||||
await twonlyDB.contactsDao.updateContact(
|
|
||||||
fromUserId,
|
|
||||||
const ContactsCompanion(
|
|
||||||
archived: Value(false),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (messageGetsAck(message.kind) && message.retransId != null) {
|
||||||
|
Log.info('Sending ACK for ${message.kind}');
|
||||||
|
|
||||||
|
/// ACK every message
|
||||||
|
await encryptAndSendMessageAsync(
|
||||||
|
null,
|
||||||
|
fromUserId,
|
||||||
|
MessageJson(
|
||||||
|
kind: MessageKind.ack,
|
||||||
|
content: AckContent(
|
||||||
|
messageIdToAck: message.messageSenderId,
|
||||||
|
retransIdToAck: message.retransId!,
|
||||||
|
),
|
||||||
|
timestamp: DateTime.now(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
final ok = client.Response_Ok()..none = true;
|
final ok = client.Response_Ok()..none = true;
|
||||||
return client.Response()..ok = ok;
|
return client.Response()..ok = ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<client.Response?> handleMediaOrTextMessage(
|
||||||
|
int fromUserId,
|
||||||
|
MessageJson message,
|
||||||
|
) async {
|
||||||
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
|
if (message.messageReceiverId != null) {
|
||||||
|
/// stored media file just updates the message
|
||||||
|
await twonlyDB.messagesDao.updateMessageByOtherUser(
|
||||||
|
fromUserId,
|
||||||
|
message.messageReceiverId!,
|
||||||
|
const MessagesCompanion(
|
||||||
|
mediaStored: Value(true),
|
||||||
|
errorWhileSending: Value(false),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final msg = await twonlyDB.messagesDao
|
||||||
|
.getMessageByIdAndContactId(
|
||||||
|
fromUserId,
|
||||||
|
message.messageReceiverId!,
|
||||||
|
)
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (msg != null && msg.mediaUploadId != null) {
|
||||||
|
final filePath = await getMediaFilePath(msg.mediaUploadId, 'send');
|
||||||
|
if (filePath.contains('mp4')) {
|
||||||
|
unawaited(createThumbnailsForVideo(File(filePath)));
|
||||||
|
} else {
|
||||||
|
unawaited(createThumbnailsForImage(File(filePath)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (message.content != null) {
|
||||||
|
final content = message.content!;
|
||||||
|
// when a message is received doubled ignore it...
|
||||||
|
|
||||||
|
final openedMessage = await twonlyDB.messagesDao
|
||||||
|
.getMessageByOtherMessageId(fromUserId, message.messageSenderId!)
|
||||||
|
.getSingleOrNull();
|
||||||
|
|
||||||
|
if (openedMessage != null) {
|
||||||
|
if (openedMessage.errorWhileSending) {
|
||||||
|
await twonlyDB.messagesDao
|
||||||
|
.deleteMessagesByMessageId(openedMessage.messageId);
|
||||||
|
} else {
|
||||||
|
Log.error(
|
||||||
|
'Got a duplicated message from other user: ${message.messageSenderId!}',
|
||||||
|
);
|
||||||
|
final ok = client.Response_Ok()..none = true;
|
||||||
|
return client.Response()..ok = ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? responseToMessageId;
|
||||||
|
int? responseToOtherMessageId;
|
||||||
|
int? messageId;
|
||||||
|
|
||||||
|
var acknowledgeByUser = false;
|
||||||
|
DateTime? openedAt;
|
||||||
|
|
||||||
|
if (message.kind == MessageKind.reopenedMedia) {
|
||||||
|
acknowledgeByUser = true;
|
||||||
|
openedAt = DateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content is TextMessageContent) {
|
||||||
|
responseToMessageId = content.responseToMessageId;
|
||||||
|
responseToOtherMessageId = content.responseToOtherMessageId;
|
||||||
|
|
||||||
|
if (responseToMessageId != null || responseToOtherMessageId != null) {
|
||||||
|
// reactions are shown in the notification directly...
|
||||||
|
if (isEmoji(content.text)) {
|
||||||
|
openedAt = DateTime.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (content is ReopenedMediaFileContent) {
|
||||||
|
responseToMessageId = content.messageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseToMessageId != null) {
|
||||||
|
await twonlyDB.messagesDao.updateMessageByOtherUser(
|
||||||
|
fromUserId,
|
||||||
|
responseToMessageId,
|
||||||
|
MessagesCompanion(
|
||||||
|
errorWhileSending: const Value(false),
|
||||||
|
openedAt: Value(
|
||||||
|
DateTime.now(),
|
||||||
|
), // when a user reacted to the media file, it should be marked as opened
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final contentJson = jsonEncode(content.toJson());
|
||||||
|
final update = MessagesCompanion(
|
||||||
|
contactId: Value(fromUserId),
|
||||||
|
kind: Value(message.kind),
|
||||||
|
messageOtherId: Value(message.messageSenderId),
|
||||||
|
contentJson: Value(contentJson),
|
||||||
|
acknowledgeByServer: const Value(true),
|
||||||
|
acknowledgeByUser: Value(acknowledgeByUser),
|
||||||
|
responseToMessageId: Value(responseToMessageId),
|
||||||
|
responseToOtherMessageId: Value(responseToOtherMessageId),
|
||||||
|
openedAt: Value(openedAt),
|
||||||
|
downloadState: Value(
|
||||||
|
message.kind == MessageKind.media
|
||||||
|
? DownloadState.pending
|
||||||
|
: DownloadState.downloaded,
|
||||||
|
),
|
||||||
|
sendAt: Value(message.timestamp),
|
||||||
|
);
|
||||||
|
|
||||||
|
messageId = await twonlyDB.messagesDao.insertMessage(
|
||||||
|
update,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (messageId == null) {
|
||||||
|
Log.error('could not insert message into db');
|
||||||
|
return client.Response()..error = ErrorCode.InternalError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info('Inserted a new message with id: $messageId');
|
||||||
|
|
||||||
|
if (message.kind == MessageKind.media) {
|
||||||
|
await twonlyDB.contactsDao.incFlameCounter(
|
||||||
|
fromUserId,
|
||||||
|
true,
|
||||||
|
message.timestamp,
|
||||||
|
);
|
||||||
|
|
||||||
|
final msg = await twonlyDB.messagesDao
|
||||||
|
.getMessageByMessageId(messageId)
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (msg != null) {
|
||||||
|
unawaited(startDownloadMedia(msg, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.error('Content is not defined $message');
|
||||||
|
}
|
||||||
|
|
||||||
|
// unarchive contact when receiving a new message
|
||||||
|
await twonlyDB.contactsDao.updateContact(
|
||||||
|
fromUserId,
|
||||||
|
const ContactsCompanion(
|
||||||
|
archived: Value(false),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Future<client.Response> handleRequestNewPreKey() async {
|
Future<client.Response> handleRequestNewPreKey() async {
|
||||||
final localPreKeys = await signalGetPreKeys();
|
final localPreKeys = await signalGetPreKeys();
|
||||||
|
|
||||||
|
|
@ -457,7 +469,7 @@ Future<client.Response> handleRequestNewPreKey() async {
|
||||||
return client.Response()..ok = ok;
|
return client.Response()..ok = ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<client.Response> handleContactRequest(
|
Future<void> handleContactRequest(
|
||||||
int fromUserId,
|
int fromUserId,
|
||||||
MessageJson message,
|
MessageJson message,
|
||||||
) async {
|
) async {
|
||||||
|
|
@ -475,6 +487,4 @@ Future<client.Response> handleContactRequest(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await setupNotificationWithUsers();
|
await setupNotificationWithUsers();
|
||||||
final ok = client.Response_Ok()..none = true;
|
|
||||||
return client.Response()..ok = ok;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/services/flame.service.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart';
|
||||||
|
|
||||||
|
|
@ -65,6 +68,14 @@ class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
if (kDebugMode)
|
||||||
|
ListTile(
|
||||||
|
title: const Text('Test FlameSync'),
|
||||||
|
onTap: () async {
|
||||||
|
await twonlyDB.contactsDao.modifyFlameCounterForTesting();
|
||||||
|
await syncFlameCounters();
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:drift/drift.dart' hide Column;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
|
import 'package:twonly/src/model/json/message.dart';
|
||||||
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
|
|
||||||
class RetransmissionDataView extends StatefulWidget {
|
class RetransmissionDataView extends StatefulWidget {
|
||||||
const RetransmissionDataView({super.key});
|
const RetransmissionDataView({super.key});
|
||||||
|
|
@ -11,11 +17,48 @@ class RetransmissionDataView extends StatefulWidget {
|
||||||
State<RetransmissionDataView> createState() => _RetransmissionDataViewState();
|
State<RetransmissionDataView> createState() => _RetransmissionDataViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RetransMsg {
|
||||||
|
RetransMsg({
|
||||||
|
required this.json,
|
||||||
|
required this.retrans,
|
||||||
|
required this.contact,
|
||||||
|
});
|
||||||
|
final MessageJson json;
|
||||||
|
final MessageRetransmission retrans;
|
||||||
|
final Contact? contact;
|
||||||
|
|
||||||
|
static List<RetransMsg> fromRaw(
|
||||||
|
List<MessageRetransmission> retrans,
|
||||||
|
Map<int, Contact> contacts,
|
||||||
|
) {
|
||||||
|
final res = <RetransMsg>[];
|
||||||
|
|
||||||
|
for (final retrans in retrans) {
|
||||||
|
final json = MessageJson.fromJson(
|
||||||
|
jsonDecode(
|
||||||
|
utf8.decode(
|
||||||
|
gzip.decode(retrans.plaintextContent),
|
||||||
|
),
|
||||||
|
) as Map<String, dynamic>,
|
||||||
|
);
|
||||||
|
res.add(
|
||||||
|
RetransMsg(
|
||||||
|
json: json,
|
||||||
|
retrans: retrans,
|
||||||
|
contact: contacts[retrans.contactId],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _RetransmissionDataViewState extends State<RetransmissionDataView> {
|
class _RetransmissionDataViewState extends State<RetransmissionDataView> {
|
||||||
List<MessageRetransmission> retransmissions = [];
|
List<MessageRetransmission> retransmissions = [];
|
||||||
List<Contact> contacts = [];
|
Map<int, Contact> contacts = {};
|
||||||
StreamSubscription<List<MessageRetransmission>>? subscriptionRetransmission;
|
StreamSubscription<List<MessageRetransmission>>? subscriptionRetransmission;
|
||||||
StreamSubscription<List<Contact>>? subscriptionContacts;
|
StreamSubscription<List<Contact>>? subscriptionContacts;
|
||||||
|
List<RetransMsg> messages = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -35,15 +78,21 @@ class _RetransmissionDataViewState extends State<RetransmissionDataView> {
|
||||||
Future<void> initAsync() async {
|
Future<void> initAsync() async {
|
||||||
subscriptionContacts =
|
subscriptionContacts =
|
||||||
twonlyDB.contactsDao.watchAllContacts().listen((updated) {
|
twonlyDB.contactsDao.watchAllContacts().listen((updated) {
|
||||||
setState(() {
|
for (final contact in updated) {
|
||||||
contacts = updated;
|
contacts[contact.userId] = contact;
|
||||||
});
|
}
|
||||||
|
if (retransmissions.isNotEmpty) {
|
||||||
|
messages = RetransMsg.fromRaw(retransmissions, contacts);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
});
|
});
|
||||||
subscriptionRetransmission =
|
subscriptionRetransmission =
|
||||||
twonlyDB.messageRetransmissionDao.watchAllMessages().listen((updated) {
|
twonlyDB.messageRetransmissionDao.watchAllMessages().listen((updated) {
|
||||||
setState(() {
|
retransmissions = updated;
|
||||||
retransmissions = updated;
|
if (contacts.isNotEmpty) {
|
||||||
});
|
messages = RetransMsg.fromRaw(retransmissions, contacts);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,16 +104,83 @@ class _RetransmissionDataViewState extends State<RetransmissionDataView> {
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
ListView(
|
Expanded(
|
||||||
children: retransmissions
|
child: ListView(
|
||||||
.map(
|
children: messages
|
||||||
(retrans) => ListTile(
|
.map(
|
||||||
title: Text(retrans.retransmissionId.toString()),
|
(retrans) => ListTile(
|
||||||
subtitle: Text('Message to ${retrans.contactId}'),
|
title: Text(
|
||||||
),
|
'${retrans.retrans.retransmissionId}: ${retrans.json.kind}',
|
||||||
)
|
),
|
||||||
.toList(),
|
subtitle: Column(
|
||||||
)
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'To ${retrans.contact?.username}',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Server-Ack: ${retrans.retrans.acknowledgeByServerAt}',
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Retry: ${retrans.retrans.retryCount} : ${retrans.retrans.lastRetry}',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
trailing: SizedBox(
|
||||||
|
width: 80,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
width: 40,
|
||||||
|
child: Center(
|
||||||
|
child: GestureDetector(
|
||||||
|
onDoubleTap: () async {
|
||||||
|
await twonlyDB.messageRetransmissionDao
|
||||||
|
.deleteRetransmissionById(
|
||||||
|
retrans.retrans.retransmissionId);
|
||||||
|
},
|
||||||
|
child: const FaIcon(
|
||||||
|
FontAwesomeIcons.trash,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 40,
|
||||||
|
child: OutlinedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||||
|
EdgeInsets.zero,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await twonlyDB.messageRetransmissionDao
|
||||||
|
.updateRetransmission(
|
||||||
|
retrans.retrans.retransmissionId,
|
||||||
|
const MessageRetransmissionsCompanion(
|
||||||
|
acknowledgeByServerAt: Value(null),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await sendRetransmitMessage(
|
||||||
|
retrans.retrans.retransmissionId,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const FaIcon(
|
||||||
|
FontAwesomeIcons.arrowRotateLeft,
|
||||||
|
size: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import 'schema_v13.dart' as v13;
|
||||||
import 'schema_v14.dart' as v14;
|
import 'schema_v14.dart' as v14;
|
||||||
import 'schema_v15.dart' as v15;
|
import 'schema_v15.dart' as v15;
|
||||||
import 'schema_v16.dart' as v16;
|
import 'schema_v16.dart' as v16;
|
||||||
|
import 'schema_v17.dart' as v17;
|
||||||
|
|
||||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
@override
|
@override
|
||||||
|
|
@ -56,6 +57,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
return v15.DatabaseAtV15(db);
|
return v15.DatabaseAtV15(db);
|
||||||
case 16:
|
case 16:
|
||||||
return v16.DatabaseAtV16(db);
|
return v16.DatabaseAtV16(db);
|
||||||
|
case 17:
|
||||||
|
return v17.DatabaseAtV17(db);
|
||||||
default:
|
default:
|
||||||
throw MissingSchemaException(version, versions);
|
throw MissingSchemaException(version, versions);
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +80,7 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
13,
|
13,
|
||||||
14,
|
14,
|
||||||
15,
|
15,
|
||||||
16
|
16,
|
||||||
|
17
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3742
test/drift/twonly_database/generated/schema_v17.dart
Normal file
3742
test/drift/twonly_database/generated/schema_v17.dart
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue