mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 12:28:40 +00:00
fix #68
This commit is contained in:
parent
86d87b84ac
commit
190b16ec9a
27 changed files with 4013 additions and 158 deletions
File diff suppressed because one or more lines are too long
|
|
@ -34,8 +34,10 @@ void main() async {
|
|||
apiService = ApiService();
|
||||
twonlyDB = TwonlyDatabase();
|
||||
await twonlyDB.messagesDao.resetPendingDownloadState();
|
||||
await purgeReceivedMediaFiles();
|
||||
await purgeSendMediaFiles();
|
||||
|
||||
// purge media files in the background
|
||||
purgeReceivedMediaFiles();
|
||||
purgeSendMediaFiles();
|
||||
|
||||
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
|
||||
|
|
|
|||
|
|
@ -123,12 +123,22 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
|||
// return (select(contacts)).watch();
|
||||
}
|
||||
|
||||
Stream<Contact> watchContact(int userid) {
|
||||
Stream<Contact?> watchContact(int userid) {
|
||||
return (select(contacts)..where((t) => t.userId.equals(userid)))
|
||||
.watchSingle();
|
||||
.watchSingleOrNull();
|
||||
}
|
||||
|
||||
Stream<List<Contact>> watchContactsForShareView() {
|
||||
return (select(contacts)
|
||||
..where((t) =>
|
||||
t.accepted.equals(true) &
|
||||
t.blocked.equals(false) &
|
||||
t.deleted.equals(false))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||
.watch();
|
||||
}
|
||||
|
||||
Stream<List<Contact>> watchContactsForStartNewChat() {
|
||||
return (select(contacts)
|
||||
..where((t) => t.accepted.equals(true) & t.blocked.equals(false))
|
||||
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||
|
|
@ -190,13 +200,20 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
|||
}
|
||||
|
||||
String getContactDisplayName(Contact user) {
|
||||
if (user.nickName != null) {
|
||||
return user.nickName!;
|
||||
String name = user.username;
|
||||
if (user.nickName != null && user.nickName != "") {
|
||||
name = user.nickName!;
|
||||
} else if (user.displayName != null) {
|
||||
name = user.displayName!;
|
||||
}
|
||||
if (user.displayName != null) {
|
||||
return user.displayName!;
|
||||
if (user.deleted) {
|
||||
name = applyStrikethrough(name);
|
||||
}
|
||||
return user.username;
|
||||
return name;
|
||||
}
|
||||
|
||||
String applyStrikethrough(String text) {
|
||||
return text.split('').map((char) => '$char\u0336').join('');
|
||||
}
|
||||
|
||||
int getFlameCounterFromContact(Contact contact) {
|
||||
|
|
|
|||
|
|
@ -186,6 +186,10 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
|||
.go();
|
||||
}
|
||||
|
||||
Future deleteAllMessagesByContactId(int contactId) {
|
||||
return (delete(messages)..where((t) => t.contactId.equals(contactId))).go();
|
||||
}
|
||||
|
||||
Future<bool> containsOtherMessageId(
|
||||
int fromUserId, int messageOtherId) async {
|
||||
final query = select(messages)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ class SignalDao extends DatabaseAccessor<TwonlyDatabase> with _$SignalDaoMixin {
|
|||
// of this object.
|
||||
SignalDao(super.db);
|
||||
|
||||
Future deleteAllByContactId(int contactId) async {
|
||||
await (delete(signalContactPreKeys)
|
||||
..where((t) => t.contactId.equals(contactId)))
|
||||
.go();
|
||||
await (delete(signalContactSignedPreKeys)
|
||||
..where((t) => t.contactId.equals(contactId)))
|
||||
.go();
|
||||
}
|
||||
|
||||
// 1: Count the number of pre-keys by contact ID
|
||||
Future<int> countPreKeysByContactId(int contactId) {
|
||||
return (select(signalContactPreKeys)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ class Contacts extends Table {
|
|||
BoolColumn get verified => boolean().withDefault(Constant(false))();
|
||||
BoolColumn get archived => boolean().withDefault(Constant(false))();
|
||||
BoolColumn get pinned => boolean().withDefault(Constant(false))();
|
||||
BoolColumn get deleted => boolean().withDefault(Constant(false))();
|
||||
|
||||
BoolColumn get alsoBestFriend => boolean().withDefault(Constant(false))();
|
||||
|
||||
IntColumn get deleteMessagesAfterXMinutes =>
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
@override
|
||||
MigrationStrategy get migration {
|
||||
return MigrationStrategy(
|
||||
beforeOpen: (details) async {
|
||||
await customStatement('PRAGMA foreign_keys = ON');
|
||||
},
|
||||
onUpgrade: stepByStep(
|
||||
from1To2: (m, schema) async {
|
||||
m.addColumn(schema.messages, schema.messages.errorWhileSending);
|
||||
|
|
@ -109,6 +112,7 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
|||
from9To10: (m, schema) async {
|
||||
m.createTable(signalContactPreKeys);
|
||||
m.createTable(signalContactSignedPreKeys);
|
||||
m.addColumn(schema.contacts, schema.contacts.deleted);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,16 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'),
|
||||
defaultValue: Constant(false));
|
||||
static const VerificationMeta _deletedMeta =
|
||||
const VerificationMeta('deleted');
|
||||
@override
|
||||
late final GeneratedColumn<bool> deleted = GeneratedColumn<bool>(
|
||||
'deleted', aliasedName, false,
|
||||
type: DriftSqlType.bool,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('CHECK ("deleted" IN (0, 1))'),
|
||||
defaultValue: Constant(false));
|
||||
static const VerificationMeta _alsoBestFriendMeta =
|
||||
const VerificationMeta('alsoBestFriend');
|
||||
@override
|
||||
|
|
@ -195,6 +205,7 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
verified,
|
||||
archived,
|
||||
pinned,
|
||||
deleted,
|
||||
alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes,
|
||||
createdAt,
|
||||
|
|
@ -270,6 +281,10 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
context.handle(_pinnedMeta,
|
||||
pinned.isAcceptableOrUnknown(data['pinned']!, _pinnedMeta));
|
||||
}
|
||||
if (data.containsKey('deleted')) {
|
||||
context.handle(_deletedMeta,
|
||||
deleted.isAcceptableOrUnknown(data['deleted']!, _deletedMeta));
|
||||
}
|
||||
if (data.containsKey('also_best_friend')) {
|
||||
context.handle(
|
||||
_alsoBestFriendMeta,
|
||||
|
|
@ -362,6 +377,8 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
.read(DriftSqlType.bool, data['${effectivePrefix}archived'])!,
|
||||
pinned: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}pinned'])!,
|
||||
deleted: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}deleted'])!,
|
||||
alsoBestFriend: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}also_best_friend'])!,
|
||||
deleteMessagesAfterXMinutes: attachedDatabase.typeMapping.read(
|
||||
|
|
@ -408,6 +425,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
final bool verified;
|
||||
final bool archived;
|
||||
final bool pinned;
|
||||
final bool deleted;
|
||||
final bool alsoBestFriend;
|
||||
final int deleteMessagesAfterXMinutes;
|
||||
final DateTime createdAt;
|
||||
|
|
@ -431,6 +449,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
required this.verified,
|
||||
required this.archived,
|
||||
required this.pinned,
|
||||
required this.deleted,
|
||||
required this.alsoBestFriend,
|
||||
required this.deleteMessagesAfterXMinutes,
|
||||
required this.createdAt,
|
||||
|
|
@ -462,6 +481,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
map['verified'] = Variable<bool>(verified);
|
||||
map['archived'] = Variable<bool>(archived);
|
||||
map['pinned'] = Variable<bool>(pinned);
|
||||
map['deleted'] = Variable<bool>(deleted);
|
||||
map['also_best_friend'] = Variable<bool>(alsoBestFriend);
|
||||
map['delete_messages_after_x_minutes'] =
|
||||
Variable<int>(deleteMessagesAfterXMinutes);
|
||||
|
|
@ -505,6 +525,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
verified: Value(verified),
|
||||
archived: Value(archived),
|
||||
pinned: Value(pinned),
|
||||
deleted: Value(deleted),
|
||||
alsoBestFriend: Value(alsoBestFriend),
|
||||
deleteMessagesAfterXMinutes: Value(deleteMessagesAfterXMinutes),
|
||||
createdAt: Value(createdAt),
|
||||
|
|
@ -542,6 +563,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
verified: serializer.fromJson<bool>(json['verified']),
|
||||
archived: serializer.fromJson<bool>(json['archived']),
|
||||
pinned: serializer.fromJson<bool>(json['pinned']),
|
||||
deleted: serializer.fromJson<bool>(json['deleted']),
|
||||
alsoBestFriend: serializer.fromJson<bool>(json['alsoBestFriend']),
|
||||
deleteMessagesAfterXMinutes:
|
||||
serializer.fromJson<int>(json['deleteMessagesAfterXMinutes']),
|
||||
|
|
@ -574,6 +596,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
'verified': serializer.toJson<bool>(verified),
|
||||
'archived': serializer.toJson<bool>(archived),
|
||||
'pinned': serializer.toJson<bool>(pinned),
|
||||
'deleted': serializer.toJson<bool>(deleted),
|
||||
'alsoBestFriend': serializer.toJson<bool>(alsoBestFriend),
|
||||
'deleteMessagesAfterXMinutes':
|
||||
serializer.toJson<int>(deleteMessagesAfterXMinutes),
|
||||
|
|
@ -602,6 +625,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
bool? verified,
|
||||
bool? archived,
|
||||
bool? pinned,
|
||||
bool? deleted,
|
||||
bool? alsoBestFriend,
|
||||
int? deleteMessagesAfterXMinutes,
|
||||
DateTime? createdAt,
|
||||
|
|
@ -625,6 +649,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
verified: verified ?? this.verified,
|
||||
archived: archived ?? this.archived,
|
||||
pinned: pinned ?? this.pinned,
|
||||
deleted: deleted ?? this.deleted,
|
||||
alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes:
|
||||
deleteMessagesAfterXMinutes ?? this.deleteMessagesAfterXMinutes,
|
||||
|
|
@ -661,6 +686,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
verified: data.verified.present ? data.verified.value : this.verified,
|
||||
archived: data.archived.present ? data.archived.value : this.archived,
|
||||
pinned: data.pinned.present ? data.pinned.value : this.pinned,
|
||||
deleted: data.deleted.present ? data.deleted.value : this.deleted,
|
||||
alsoBestFriend: data.alsoBestFriend.present
|
||||
? data.alsoBestFriend.value
|
||||
: this.alsoBestFriend,
|
||||
|
|
@ -707,6 +733,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
..write('verified: $verified, ')
|
||||
..write('archived: $archived, ')
|
||||
..write('pinned: $pinned, ')
|
||||
..write('deleted: $deleted, ')
|
||||
..write('alsoBestFriend: $alsoBestFriend, ')
|
||||
..write('deleteMessagesAfterXMinutes: $deleteMessagesAfterXMinutes, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
|
|
@ -735,6 +762,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
verified,
|
||||
archived,
|
||||
pinned,
|
||||
deleted,
|
||||
alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes,
|
||||
createdAt,
|
||||
|
|
@ -762,6 +790,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
other.verified == this.verified &&
|
||||
other.archived == this.archived &&
|
||||
other.pinned == this.pinned &&
|
||||
other.deleted == this.deleted &&
|
||||
other.alsoBestFriend == this.alsoBestFriend &&
|
||||
other.deleteMessagesAfterXMinutes ==
|
||||
this.deleteMessagesAfterXMinutes &&
|
||||
|
|
@ -788,6 +817,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
final Value<bool> verified;
|
||||
final Value<bool> archived;
|
||||
final Value<bool> pinned;
|
||||
final Value<bool> deleted;
|
||||
final Value<bool> alsoBestFriend;
|
||||
final Value<int> deleteMessagesAfterXMinutes;
|
||||
final Value<DateTime> createdAt;
|
||||
|
|
@ -811,6 +841,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.verified = const Value.absent(),
|
||||
this.archived = const Value.absent(),
|
||||
this.pinned = const Value.absent(),
|
||||
this.deleted = const Value.absent(),
|
||||
this.alsoBestFriend = const Value.absent(),
|
||||
this.deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
|
|
@ -835,6 +866,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.verified = const Value.absent(),
|
||||
this.archived = const Value.absent(),
|
||||
this.pinned = const Value.absent(),
|
||||
this.deleted = const Value.absent(),
|
||||
this.alsoBestFriend = const Value.absent(),
|
||||
this.deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
|
|
@ -859,6 +891,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Expression<bool>? verified,
|
||||
Expression<bool>? archived,
|
||||
Expression<bool>? pinned,
|
||||
Expression<bool>? deleted,
|
||||
Expression<bool>? alsoBestFriend,
|
||||
Expression<int>? deleteMessagesAfterXMinutes,
|
||||
Expression<DateTime>? createdAt,
|
||||
|
|
@ -883,6 +916,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
if (verified != null) 'verified': verified,
|
||||
if (archived != null) 'archived': archived,
|
||||
if (pinned != null) 'pinned': pinned,
|
||||
if (deleted != null) 'deleted': deleted,
|
||||
if (alsoBestFriend != null) 'also_best_friend': alsoBestFriend,
|
||||
if (deleteMessagesAfterXMinutes != null)
|
||||
'delete_messages_after_x_minutes': deleteMessagesAfterXMinutes,
|
||||
|
|
@ -913,6 +947,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Value<bool>? verified,
|
||||
Value<bool>? archived,
|
||||
Value<bool>? pinned,
|
||||
Value<bool>? deleted,
|
||||
Value<bool>? alsoBestFriend,
|
||||
Value<int>? deleteMessagesAfterXMinutes,
|
||||
Value<DateTime>? createdAt,
|
||||
|
|
@ -936,6 +971,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
verified: verified ?? this.verified,
|
||||
archived: archived ?? this.archived,
|
||||
pinned: pinned ?? this.pinned,
|
||||
deleted: deleted ?? this.deleted,
|
||||
alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes:
|
||||
deleteMessagesAfterXMinutes ?? this.deleteMessagesAfterXMinutes,
|
||||
|
|
@ -990,6 +1026,9 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
if (pinned.present) {
|
||||
map['pinned'] = Variable<bool>(pinned.value);
|
||||
}
|
||||
if (deleted.present) {
|
||||
map['deleted'] = Variable<bool>(deleted.value);
|
||||
}
|
||||
if (alsoBestFriend.present) {
|
||||
map['also_best_friend'] = Variable<bool>(alsoBestFriend.value);
|
||||
}
|
||||
|
|
@ -1042,6 +1081,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
..write('verified: $verified, ')
|
||||
..write('archived: $archived, ')
|
||||
..write('pinned: $pinned, ')
|
||||
..write('deleted: $deleted, ')
|
||||
..write('alsoBestFriend: $alsoBestFriend, ')
|
||||
..write('deleteMessagesAfterXMinutes: $deleteMessagesAfterXMinutes, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
|
|
@ -4196,6 +4236,7 @@ typedef $$ContactsTableCreateCompanionBuilder = ContactsCompanion Function({
|
|||
Value<bool> verified,
|
||||
Value<bool> archived,
|
||||
Value<bool> pinned,
|
||||
Value<bool> deleted,
|
||||
Value<bool> alsoBestFriend,
|
||||
Value<int> deleteMessagesAfterXMinutes,
|
||||
Value<DateTime> createdAt,
|
||||
|
|
@ -4220,6 +4261,7 @@ typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({
|
|||
Value<bool> verified,
|
||||
Value<bool> archived,
|
||||
Value<bool> pinned,
|
||||
Value<bool> deleted,
|
||||
Value<bool> alsoBestFriend,
|
||||
Value<int> deleteMessagesAfterXMinutes,
|
||||
Value<DateTime> createdAt,
|
||||
|
|
@ -4298,6 +4340,9 @@ class $$ContactsTableFilterComposer
|
|||
ColumnFilters<bool> get pinned => $composableBuilder(
|
||||
column: $table.pinned, builder: (column) => ColumnFilters(column));
|
||||
|
||||
ColumnFilters<bool> get deleted => $composableBuilder(
|
||||
column: $table.deleted, builder: (column) => ColumnFilters(column));
|
||||
|
||||
ColumnFilters<bool> get alsoBestFriend => $composableBuilder(
|
||||
column: $table.alsoBestFriend,
|
||||
builder: (column) => ColumnFilters(column));
|
||||
|
|
@ -4403,6 +4448,9 @@ class $$ContactsTableOrderingComposer
|
|||
ColumnOrderings<bool> get pinned => $composableBuilder(
|
||||
column: $table.pinned, builder: (column) => ColumnOrderings(column));
|
||||
|
||||
ColumnOrderings<bool> get deleted => $composableBuilder(
|
||||
column: $table.deleted, builder: (column) => ColumnOrderings(column));
|
||||
|
||||
ColumnOrderings<bool> get alsoBestFriend => $composableBuilder(
|
||||
column: $table.alsoBestFriend,
|
||||
builder: (column) => ColumnOrderings(column));
|
||||
|
|
@ -4488,6 +4536,9 @@ class $$ContactsTableAnnotationComposer
|
|||
GeneratedColumn<bool> get pinned =>
|
||||
$composableBuilder(column: $table.pinned, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<bool> get deleted =>
|
||||
$composableBuilder(column: $table.deleted, builder: (column) => column);
|
||||
|
||||
GeneratedColumn<bool> get alsoBestFriend => $composableBuilder(
|
||||
column: $table.alsoBestFriend, builder: (column) => column);
|
||||
|
||||
|
|
@ -4575,6 +4626,7 @@ class $$ContactsTableTableManager extends RootTableManager<
|
|||
Value<bool> verified = const Value.absent(),
|
||||
Value<bool> archived = const Value.absent(),
|
||||
Value<bool> pinned = const Value.absent(),
|
||||
Value<bool> deleted = const Value.absent(),
|
||||
Value<bool> alsoBestFriend = const Value.absent(),
|
||||
Value<int> deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
|
|
@ -4599,6 +4651,7 @@ class $$ContactsTableTableManager extends RootTableManager<
|
|||
verified: verified,
|
||||
archived: archived,
|
||||
pinned: pinned,
|
||||
deleted: deleted,
|
||||
alsoBestFriend: alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes: deleteMessagesAfterXMinutes,
|
||||
createdAt: createdAt,
|
||||
|
|
@ -4623,6 +4676,7 @@ class $$ContactsTableTableManager extends RootTableManager<
|
|||
Value<bool> verified = const Value.absent(),
|
||||
Value<bool> archived = const Value.absent(),
|
||||
Value<bool> pinned = const Value.absent(),
|
||||
Value<bool> deleted = const Value.absent(),
|
||||
Value<bool> alsoBestFriend = const Value.absent(),
|
||||
Value<int> deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
Value<DateTime> createdAt = const Value.absent(),
|
||||
|
|
@ -4647,6 +4701,7 @@ class $$ContactsTableTableManager extends RootTableManager<
|
|||
verified: verified,
|
||||
archived: archived,
|
||||
pinned: pinned,
|
||||
deleted: deleted,
|
||||
alsoBestFriend: alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes: deleteMessagesAfterXMinutes,
|
||||
createdAt: createdAt,
|
||||
|
|
|
|||
|
|
@ -1895,7 +1895,7 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
signalContactPreKeys,
|
||||
signalContactSignedPreKeys,
|
||||
];
|
||||
late final Shape12 contacts = Shape12(
|
||||
late final Shape13 contacts = Shape13(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'contacts',
|
||||
withoutRowId: false,
|
||||
|
|
@ -1916,6 +1916,7 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
_column_9,
|
||||
_column_39,
|
||||
_column_53,
|
||||
_column_57,
|
||||
_column_54,
|
||||
_column_40,
|
||||
_column_10,
|
||||
|
|
@ -2054,7 +2055,7 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape13 signalContactPreKeys = Shape13(
|
||||
late final Shape14 signalContactPreKeys = Shape14(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_contact_pre_keys',
|
||||
withoutRowId: false,
|
||||
|
|
@ -2063,7 +2064,7 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
'PRIMARY KEY(contact_id, pre_key_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_57,
|
||||
_column_58,
|
||||
_column_34,
|
||||
_column_35,
|
||||
_column_10,
|
||||
|
|
@ -2071,19 +2072,19 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
attachedDatabase: database,
|
||||
),
|
||||
alias: null);
|
||||
late final Shape14 signalContactSignedPreKeys = Shape14(
|
||||
late final Shape15 signalContactSignedPreKeys = Shape15(
|
||||
source: i0.VersionedTable(
|
||||
entityName: 'signal_contact_signed_pre_keys',
|
||||
withoutRowId: false,
|
||||
isStrict: false,
|
||||
tableConstraints: [
|
||||
'PRIMARY KEY(contact_id, signed_pre_key_id)',
|
||||
'PRIMARY KEY(contact_id)',
|
||||
],
|
||||
columns: [
|
||||
_column_57,
|
||||
_column_58,
|
||||
_column_59,
|
||||
_column_60,
|
||||
_column_61,
|
||||
_column_10,
|
||||
],
|
||||
attachedDatabase: database,
|
||||
|
|
@ -2093,6 +2094,65 @@ final class Schema10 extends i0.VersionedSchema {
|
|||
|
||||
class Shape13 extends i0.VersionedTable {
|
||||
Shape13({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get userId =>
|
||||
columnsByName['user_id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<String> get username =>
|
||||
columnsByName['username']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get displayName =>
|
||||
columnsByName['display_name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get nickName =>
|
||||
columnsByName['nick_name']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<String> get avatarSvg =>
|
||||
columnsByName['avatar_svg']! as i1.GeneratedColumn<String>;
|
||||
i1.GeneratedColumn<int> get myAvatarCounter =>
|
||||
columnsByName['my_avatar_counter']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<bool> get accepted =>
|
||||
columnsByName['accepted']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get requested =>
|
||||
columnsByName['requested']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get blocked =>
|
||||
columnsByName['blocked']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get verified =>
|
||||
columnsByName['verified']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get archived =>
|
||||
columnsByName['archived']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get pinned =>
|
||||
columnsByName['pinned']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get deleted =>
|
||||
columnsByName['deleted']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<bool> get alsoBestFriend =>
|
||||
columnsByName['also_best_friend']! as i1.GeneratedColumn<bool>;
|
||||
i1.GeneratedColumn<int> get deleteMessagesAfterXMinutes =>
|
||||
columnsByName['delete_messages_after_x_minutes']!
|
||||
as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<int> get totalMediaCounter =>
|
||||
columnsByName['total_media_counter']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<DateTime> get lastMessageSend =>
|
||||
columnsByName['last_message_send']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<DateTime> get lastMessageReceived =>
|
||||
columnsByName['last_message_received']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<DateTime> get lastFlameCounterChange =>
|
||||
columnsByName['last_flame_counter_change']!
|
||||
as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<DateTime> get lastFlameSync =>
|
||||
columnsByName['last_flame_sync']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<DateTime> get lastMessageExchange =>
|
||||
columnsByName['last_message_exchange']! as i1.GeneratedColumn<DateTime>;
|
||||
i1.GeneratedColumn<int> get flameCounter =>
|
||||
columnsByName['flame_counter']! as i1.GeneratedColumn<int>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<bool> _column_57(String aliasedName) =>
|
||||
i1.GeneratedColumn<bool>('deleted', aliasedName, false,
|
||||
type: i1.DriftSqlType.bool,
|
||||
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||
'CHECK ("deleted" IN (0, 1))'),
|
||||
defaultValue: const CustomExpression('0'));
|
||||
|
||||
class Shape14 extends i0.VersionedTable {
|
||||
Shape14({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get contactId =>
|
||||
columnsByName['contact_id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get preKeyId =>
|
||||
|
|
@ -2103,12 +2163,12 @@ class Shape13 extends i0.VersionedTable {
|
|||
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<int> _column_57(String aliasedName) =>
|
||||
i1.GeneratedColumn<int> _column_58(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('contact_id', aliasedName, false,
|
||||
type: i1.DriftSqlType.int);
|
||||
|
||||
class Shape14 extends i0.VersionedTable {
|
||||
Shape14({required super.source, required super.alias}) : super.aliased();
|
||||
class Shape15 extends i0.VersionedTable {
|
||||
Shape15({required super.source, required super.alias}) : super.aliased();
|
||||
i1.GeneratedColumn<int> get contactId =>
|
||||
columnsByName['contact_id']! as i1.GeneratedColumn<int>;
|
||||
i1.GeneratedColumn<int> get signedPreKeyId =>
|
||||
|
|
@ -2122,13 +2182,13 @@ class Shape14 extends i0.VersionedTable {
|
|||
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||
}
|
||||
|
||||
i1.GeneratedColumn<int> _column_58(String aliasedName) =>
|
||||
i1.GeneratedColumn<int> _column_59(String aliasedName) =>
|
||||
i1.GeneratedColumn<int>('signed_pre_key_id', aliasedName, false,
|
||||
type: i1.DriftSqlType.int);
|
||||
i1.GeneratedColumn<i2.Uint8List> _column_59(String aliasedName) =>
|
||||
i1.GeneratedColumn<i2.Uint8List> _column_60(String aliasedName) =>
|
||||
i1.GeneratedColumn<i2.Uint8List>('signed_pre_key', aliasedName, false,
|
||||
type: i1.DriftSqlType.blob);
|
||||
i1.GeneratedColumn<i2.Uint8List> _column_60(String aliasedName) =>
|
||||
i1.GeneratedColumn<i2.Uint8List> _column_61(String aliasedName) =>
|
||||
i1.GeneratedColumn<i2.Uint8List>(
|
||||
'signed_pre_key_signature', aliasedName, false,
|
||||
type: i1.DriftSqlType.blob);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
"chatListViewSearchUserNameBtn": "Füge deinen ersten twonly-Kontakt hinzu!",
|
||||
"chatListViewSendFirstTwonly": "Sende dein erstes twonly!",
|
||||
"chatListDetailInput": "Nachricht eingeben",
|
||||
"userDeletedAccount": "Der Nutzer hat sein Konto gelöscht.",
|
||||
"contextMenuVerifyUser": "Verifizieren",
|
||||
"@contextMenuVerifyUser": {},
|
||||
"contextMenuArchiveUser": "Archivieren",
|
||||
|
|
@ -141,7 +142,10 @@
|
|||
"contactNickname": "Spitzname",
|
||||
"contactNicknameNew": "Neuer Spitzname",
|
||||
"contactBlock": "Blockieren",
|
||||
"deleteAllContactMessages": "Alle Nachrichten löschen",
|
||||
"contactRemove": "Benutzer löschen",
|
||||
"contactRemoveTitle": "{username} löschen?",
|
||||
"contactRemoveBody": "Entferne den Benutzer und lösche den Chat sowie alle zugehörigen Mediendateien dauerhaft. Dadurch wird auch DEIN KONTO VON DEM TELEFON DEINES KONTAKTS gelöscht.",
|
||||
"deleteAllContactMessages": "Textnachrichten löschen",
|
||||
"deleteAllContactMessagesBody": "Dadurch werden alle Nachrichten, ausgenommen gespeicherte Mediendateien, in deinem Chat mit {username} gelöscht. Dies löscht NICHT die auf dem Gerät von {username} gespeicherten Nachrichten!",
|
||||
"contactBlockTitle": "Blockiere {username}",
|
||||
"contactBlockBody": "Ein blockierter Benutzer kann dir keine Nachrichten mehr senden, und sein Profil ist nicht mehr sichtbar. Um die Blockierung eines Benutzers aufzuheben, navigiere einfach zu Einstellungen > Datenschutz > Blockierte Benutzer.",
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@
|
|||
"@chatListViewSendFirstTwonly": {},
|
||||
"chatListDetailInput": "Type a message",
|
||||
"@chatListDetailInput": {},
|
||||
"userDeletedAccount": "The user has deleted its account.",
|
||||
"contextMenuVerifyUser": "Verify",
|
||||
"@contextMenuVerifyUser": {},
|
||||
"contextMenuArchiveUser": "Archive",
|
||||
|
|
@ -250,7 +251,7 @@
|
|||
"@contactNickname": {},
|
||||
"contactNicknameNew": "New nickname",
|
||||
"@contactNicknameNew": {},
|
||||
"deleteAllContactMessages": "Delete all messages",
|
||||
"deleteAllContactMessages": "Delete all text-messages",
|
||||
"@deleteAllContactMessages": {},
|
||||
"deleteAllContactMessagesBody": "This will remove all messages, except stored media files, in your chat with {username}. This will NOT delete the messages stored at {username}s device!",
|
||||
"@deleteAllContactMessagesBody": {
|
||||
|
|
@ -268,6 +269,9 @@
|
|||
},
|
||||
"contactBlockBody": "A blocked user will no longer be able to send you messages and their profile will be hidden from view. To unblock a user, simply navigate to Settings > Privacy > Blocked Users.",
|
||||
"@contactBlockBody": {},
|
||||
"contactRemove": "Remove user",
|
||||
"contactRemoveTitle": "Remove {username}",
|
||||
"contactRemoveBody": "Remove the user and permanently delete the chat and all associated media files. This will also delete YOUR ACCOUNT FROM YOUR CONTACT'S PHONE.",
|
||||
"undo": "Undo",
|
||||
"@undo": {},
|
||||
"redo": "Redo",
|
||||
|
|
|
|||
|
|
@ -446,6 +446,12 @@ abstract class AppLocalizations {
|
|||
/// **'Type a message'**
|
||||
String get chatListDetailInput;
|
||||
|
||||
/// No description provided for @userDeletedAccount.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The user has deleted its account.'**
|
||||
String get userDeletedAccount;
|
||||
|
||||
/// No description provided for @contextMenuVerifyUser.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -845,7 +851,7 @@ abstract class AppLocalizations {
|
|||
/// No description provided for @deleteAllContactMessages.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Delete all messages'**
|
||||
/// **'Delete all text-messages'**
|
||||
String get deleteAllContactMessages;
|
||||
|
||||
/// No description provided for @deleteAllContactMessagesBody.
|
||||
|
|
@ -872,6 +878,24 @@ abstract class AppLocalizations {
|
|||
/// **'A blocked user will no longer be able to send you messages and their profile will be hidden from view. To unblock a user, simply navigate to Settings > Privacy > Blocked Users.'**
|
||||
String get contactBlockBody;
|
||||
|
||||
/// No description provided for @contactRemove.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove user'**
|
||||
String get contactRemove;
|
||||
|
||||
/// No description provided for @contactRemoveTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove {username}'**
|
||||
String contactRemoveTitle(Object username);
|
||||
|
||||
/// No description provided for @contactRemoveBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Remove the user and permanently delete the chat and all associated media files. This will also delete YOUR ACCOUNT FROM YOUR CONTACT\'S PHONE.'**
|
||||
String get contactRemoveBody;
|
||||
|
||||
/// No description provided for @undo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -203,6 +203,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
@override
|
||||
String get chatListDetailInput => 'Nachricht eingeben';
|
||||
|
||||
@override
|
||||
String get userDeletedAccount => 'Der Nutzer hat sein Konto gelöscht.';
|
||||
|
||||
@override
|
||||
String get contextMenuVerifyUser => 'Verifizieren';
|
||||
|
||||
|
|
@ -419,7 +422,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get contactNicknameNew => 'Neuer Spitzname';
|
||||
|
||||
@override
|
||||
String get deleteAllContactMessages => 'Alle Nachrichten löschen';
|
||||
String get deleteAllContactMessages => 'Textnachrichten löschen';
|
||||
|
||||
@override
|
||||
String deleteAllContactMessagesBody(Object username) {
|
||||
|
|
@ -438,6 +441,18 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
String get contactBlockBody =>
|
||||
'Ein blockierter Benutzer kann dir keine Nachrichten mehr senden, und sein Profil ist nicht mehr sichtbar. Um die Blockierung eines Benutzers aufzuheben, navigiere einfach zu Einstellungen > Datenschutz > Blockierte Benutzer.';
|
||||
|
||||
@override
|
||||
String get contactRemove => 'Benutzer löschen';
|
||||
|
||||
@override
|
||||
String contactRemoveTitle(Object username) {
|
||||
return '$username löschen?';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contactRemoveBody =>
|
||||
'Entferne den Benutzer und lösche den Chat sowie alle zugehörigen Mediendateien dauerhaft. Dadurch wird auch DEIN KONTO VON DEM TELEFON DEINES KONTAKTS gelöscht.';
|
||||
|
||||
@override
|
||||
String get undo => 'Rückgängig';
|
||||
|
||||
|
|
|
|||
|
|
@ -201,6 +201,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
@override
|
||||
String get chatListDetailInput => 'Type a message';
|
||||
|
||||
@override
|
||||
String get userDeletedAccount => 'The user has deleted its account.';
|
||||
|
||||
@override
|
||||
String get contextMenuVerifyUser => 'Verify';
|
||||
|
||||
|
|
@ -414,7 +417,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get contactNicknameNew => 'New nickname';
|
||||
|
||||
@override
|
||||
String get deleteAllContactMessages => 'Delete all messages';
|
||||
String get deleteAllContactMessages => 'Delete all text-messages';
|
||||
|
||||
@override
|
||||
String deleteAllContactMessagesBody(Object username) {
|
||||
|
|
@ -433,6 +436,18 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
String get contactBlockBody =>
|
||||
'A blocked user will no longer be able to send you messages and their profile will be hidden from view. To unblock a user, simply navigate to Settings > Privacy > Blocked Users.';
|
||||
|
||||
@override
|
||||
String get contactRemove => 'Remove user';
|
||||
|
||||
@override
|
||||
String contactRemoveTitle(Object username) {
|
||||
return 'Remove $username';
|
||||
}
|
||||
|
||||
@override
|
||||
String get contactRemoveBody =>
|
||||
'Remove the user and permanently delete the chat and all associated media files. This will also delete YOUR ACCOUNT FROM YOUR CONTACT\'S PHONE.';
|
||||
|
||||
@override
|
||||
String get undo => 'Undo';
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'dart:collection';
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
|
@ -10,6 +11,7 @@ import 'package:mutex/mutex.dart';
|
|||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/app.dart';
|
||||
import 'package:twonly/src/database/twonly_database.dart';
|
||||
import 'package:twonly/src/model/json/userdata.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/client_to_server.pbserver.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/error.pb.dart';
|
||||
|
|
@ -221,8 +223,12 @@ class ApiService {
|
|||
box.put("rawbytes-to-retransmit", retransmit);
|
||||
}
|
||||
|
||||
Future<Result> sendRequestSync(ClientToServer request,
|
||||
{bool authenticated = true, bool ensureRetransmission = false}) async {
|
||||
Future<Result> sendRequestSync(
|
||||
ClientToServer request, {
|
||||
bool authenticated = true,
|
||||
bool ensureRetransmission = false,
|
||||
int? contactId,
|
||||
}) async {
|
||||
var seq = Int64(Random().nextInt(4294967296));
|
||||
while (messagesV0.containsKey(seq)) {
|
||||
seq = Int64(Random().nextInt(4294967296));
|
||||
|
|
@ -263,6 +269,11 @@ class ApiService {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (res.error == ErrorCode.UserIdNotFound && contactId != null) {
|
||||
Log.error("Contact deleted their account $contactId.");
|
||||
await twonlyDB.contactsDao
|
||||
.updateContact(contactId, ContactsCompanion(deleted: Value(true)));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
@ -393,7 +404,7 @@ class ApiService {
|
|||
var get = ApplicationData_GetUserById()..userId = Int64(userId);
|
||||
var appData = ApplicationData()..getuserbyid = get;
|
||||
var req = createClientToServerFromApplicationData(appData);
|
||||
return await sendRequestSync(req);
|
||||
return await sendRequestSync(req, contactId: userId);
|
||||
}
|
||||
|
||||
Future<Result> getUploadToken(int recipientsCount) async {
|
||||
|
|
@ -504,7 +515,7 @@ class ApiService {
|
|||
var get = ApplicationData_RemoveAdditionalUser()..userId = userId;
|
||||
var appData = ApplicationData()..removeadditionaluser = get;
|
||||
var req = createClientToServerFromApplicationData(appData);
|
||||
return await sendRequestSync(req);
|
||||
return await sendRequestSync(req, contactId: userId.toInt());
|
||||
}
|
||||
|
||||
Future<Result> buyVoucher(int valueInCents) async {
|
||||
|
|
@ -571,7 +582,7 @@ class ApiService {
|
|||
var get = ApplicationData_GetSignedPreKeyByUserId()..userId = Int64(userId);
|
||||
var appData = ApplicationData()..getsignedprekeybyuserid = get;
|
||||
var req = createClientToServerFromApplicationData(appData);
|
||||
Result res = await sendRequestSync(req);
|
||||
Result res = await sendRequestSync(req, contactId: userId);
|
||||
if (res.isSuccess) {
|
||||
server.Response_Ok ok = res.value;
|
||||
if (ok.hasSignedprekey()) {
|
||||
|
|
@ -585,7 +596,7 @@ class ApiService {
|
|||
var get = ApplicationData_GetPrekeysByUserId()..userId = Int64(userId);
|
||||
var appData = ApplicationData()..getprekeysbyuserid = get;
|
||||
var req = createClientToServerFromApplicationData(appData);
|
||||
Result res = await sendRequestSync(req);
|
||||
Result res = await sendRequestSync(req, contactId: userId);
|
||||
if (res.isSuccess) {
|
||||
server.Response_Ok ok = res.value;
|
||||
if (ok.hasUserdata()) {
|
||||
|
|
@ -617,7 +628,6 @@ class ApiService {
|
|||
|
||||
var appData = ApplicationData()..textmessage = testMessage;
|
||||
var req = createClientToServerFromApplicationData(appData);
|
||||
|
||||
return await sendRequestSync(req);
|
||||
return await sendRequestSync(req, contactId: target);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import 'package:twonly/src/database/twonly_database.dart';
|
|||
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||
import 'package:twonly/src/model/json/message.dart';
|
||||
import 'package:twonly/src/model/json/userdata.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/error.pb.dart';
|
||||
import 'package:twonly/src/services/api/utils.dart';
|
||||
import 'package:twonly/src/services/signal/encryption.signal.dart';
|
||||
import 'package:twonly/src/utils/hive.dart';
|
||||
|
|
@ -114,19 +115,37 @@ Future<Result> sendRetransmitMessage(
|
|||
Result resp =
|
||||
await apiService.sendTextMessage(msg.userId, msg.bytes, msg.pushData);
|
||||
|
||||
bool retry = true;
|
||||
|
||||
if (resp.isError) {
|
||||
if (resp.error == ErrorCode.UserIdNotFound) {
|
||||
retry = false;
|
||||
if (msg.messageId != null) {
|
||||
await twonlyDB.messagesDao.updateMessageByMessageId(
|
||||
msg.messageId!,
|
||||
MessagesCompanion(errorWhileSending: Value(true)),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resp.isSuccess) {
|
||||
if (msg.messageId != null) {
|
||||
retry = false;
|
||||
await twonlyDB.messagesDao.updateMessageByMessageId(
|
||||
msg.messageId!,
|
||||
MessagesCompanion(acknowledgeByServer: Value(true)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!retry) {
|
||||
{
|
||||
var retransmit = await getAllMessagesForRetransmitting();
|
||||
retransmit.remove(stateId);
|
||||
Box box = await getMediaStorage();
|
||||
box.put("messages-to-retransmit", jsonEncode(retransmit));
|
||||
}
|
||||
if (msg.messageId != null) {
|
||||
await twonlyDB.messagesDao.updateMessageByMessageId(
|
||||
msg.messageId!,
|
||||
MessagesCompanion(acknowledgeByServer: Value(true)),
|
||||
);
|
||||
}
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
|||
break;
|
||||
|
||||
case MessageKind.rejectRequest:
|
||||
await twonlyDB.contactsDao.deleteContactByUserId(fromUserId);
|
||||
await deleteContact(fromUserId);
|
||||
break;
|
||||
|
||||
case MessageKind.acceptRequest:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import 'package:fixnum/fixnum.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||
import 'package:twonly/src/model/json/message.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/client_to_server.pb.dart'
|
||||
as client;
|
||||
import 'package:twonly/src/model/protobuf/api/client_to_server.pbserver.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/error.pb.dart';
|
||||
import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'
|
||||
as server;
|
||||
import 'package:twonly/src/services/api/messages.dart';
|
||||
import 'package:twonly/src/services/signal/session.signal.dart';
|
||||
|
||||
class Result<T, E> {
|
||||
final T? value;
|
||||
|
|
@ -42,3 +47,22 @@ ClientToServer createClientToServerFromApplicationData(
|
|||
..applicationdata = applicationData;
|
||||
return ClientToServer()..v0 = v0;
|
||||
}
|
||||
|
||||
Future deleteContact(int contactId) async {
|
||||
await twonlyDB.messagesDao.deleteAllMessagesByContactId(contactId);
|
||||
await twonlyDB.signalDao.deleteAllByContactId(contactId);
|
||||
await deleteSessionWithTarget(contactId);
|
||||
await twonlyDB.contactsDao.deleteContactByUserId(contactId);
|
||||
}
|
||||
|
||||
Future rejectUser(int contactId) async {
|
||||
await encryptAndSendMessageAsync(
|
||||
null,
|
||||
contactId,
|
||||
MessageJson(
|
||||
kind: MessageKind.rejectRequest,
|
||||
timestamp: DateTime.now(),
|
||||
content: MessageContent(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,13 @@ Future<bool> createNewSignalSession(Response_UserData userData) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future deleteSessionWithTarget(int target) async {
|
||||
ConnectSignalProtocolStore? signalStore = await getSignalStore();
|
||||
if (signalStore == null) return;
|
||||
final address = SignalProtocolAddress(target.toString(), defaultDeviceId);
|
||||
await signalStore.sessionStore.deleteSession(address);
|
||||
}
|
||||
|
||||
Future<Fingerprint?> generateSessionFingerPrint(int target) async {
|
||||
ConnectSignalProtocolStore? signalStore = await getSignalStore();
|
||||
UserData? user = await getUser();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
|||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:twonly/src/providers/connection.provider.dart';
|
||||
import 'package:twonly/src/services/api/utils.dart';
|
||||
import 'package:twonly/src/services/signal/session.signal.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||
|
|
@ -262,16 +263,8 @@ class _ContactsListViewState extends State<ContactsListView> {
|
|||
child: IconButton(
|
||||
icon: Icon(Icons.close, color: Colors.red),
|
||||
onPressed: () async {
|
||||
await twonlyDB.contactsDao.deleteContactByUserId(contact.userId);
|
||||
await encryptAndSendMessageAsync(
|
||||
null,
|
||||
contact.userId,
|
||||
MessageJson(
|
||||
kind: MessageKind.rejectRequest,
|
||||
timestamp: DateTime.now(),
|
||||
content: MessageContent(),
|
||||
),
|
||||
);
|
||||
rejectUser(contact.userId);
|
||||
await deleteContact(contact.userId);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -363,37 +363,41 @@ class _UserListItem extends State<UserListItem> {
|
|||
title: Text(
|
||||
getContactDisplayName(widget.user),
|
||||
),
|
||||
subtitle: (currentMessage == null)
|
||||
? Text(context.lang.chatsTapToSend)
|
||||
: Row(
|
||||
children: [
|
||||
MessageSendStateIcon(previewMessages),
|
||||
Text("•"),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
formatDuration(lastMessageInSeconds),
|
||||
style: TextStyle(fontSize: 12),
|
||||
subtitle: (widget.user.deleted)
|
||||
? Text(context.lang.userDeletedAccount)
|
||||
: (currentMessage == null)
|
||||
? Text(context.lang.chatsTapToSend)
|
||||
: Row(
|
||||
children: [
|
||||
MessageSendStateIcon(previewMessages),
|
||||
Text("•"),
|
||||
const SizedBox(width: 5),
|
||||
Text(
|
||||
formatDuration(lastMessageInSeconds),
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
if (flameCounter > 0)
|
||||
FlameCounterWidget(
|
||||
widget.user,
|
||||
flameCounter,
|
||||
prefix: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (flameCounter > 0)
|
||||
FlameCounterWidget(
|
||||
widget.user,
|
||||
flameCounter,
|
||||
prefix: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
leading: ContactAvatar(contact: widget.user),
|
||||
trailing: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.user);
|
||||
},
|
||||
));
|
||||
},
|
||||
icon: FaIcon(FontAwesomeIcons.camera,
|
||||
color: context.color.outline.withAlpha(150)),
|
||||
),
|
||||
trailing: (widget.user.deleted)
|
||||
? null
|
||||
: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.user);
|
||||
},
|
||||
));
|
||||
},
|
||||
icon: FaIcon(FontAwesomeIcons.camera,
|
||||
color: context.color.outline.withAlpha(150)),
|
||||
),
|
||||
onTap: () {
|
||||
if (currentMessage == null) {
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
HashSet<int> alreadyReportedOpened = HashSet<int>();
|
||||
late Contact user;
|
||||
String currentInputText = "";
|
||||
late StreamSubscription<Contact> userSub;
|
||||
late StreamSubscription<Contact?> userSub;
|
||||
late StreamSubscription<List<Message>> messageSub;
|
||||
List<Message> messages = [];
|
||||
List<MemoryItem> galleryItems = [];
|
||||
|
|
@ -75,9 +75,10 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
|
||||
Future initStreams() async {
|
||||
await twonlyDB.messagesDao.removeOldMessages();
|
||||
Stream<Contact> contact =
|
||||
Stream<Contact?> contact =
|
||||
twonlyDB.contactsDao.watchContact(widget.contact.userId);
|
||||
userSub = contact.listen((contact) {
|
||||
if (contact == null) return;
|
||||
setState(() {
|
||||
user = contact;
|
||||
});
|
||||
|
|
@ -336,7 +337,7 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
},
|
||||
),
|
||||
),
|
||||
if (responseToMessage != null)
|
||||
if (responseToMessage != null && !user.deleted)
|
||||
Container(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 00,
|
||||
|
|
@ -369,43 +370,45 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
top: 10,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: newMessageController,
|
||||
focusNode: textFieldFocus,
|
||||
onChanged: (value) {
|
||||
currentInputText = value;
|
||||
setState(() {});
|
||||
},
|
||||
onSubmitted: (_) {
|
||||
_sendMessage();
|
||||
},
|
||||
decoration: inputTextMessageDeco(context),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
(currentInputText != "")
|
||||
? IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
|
||||
onPressed: () {
|
||||
_sendMessage();
|
||||
},
|
||||
)
|
||||
: IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.camera),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.contact);
|
||||
children: (user.deleted)
|
||||
? []
|
||||
: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: newMessageController,
|
||||
focusNode: textFieldFocus,
|
||||
onChanged: (value) {
|
||||
currentInputText = value;
|
||||
setState(() {});
|
||||
},
|
||||
onSubmitted: (_) {
|
||||
_sendMessage();
|
||||
},
|
||||
decoration: inputTextMessageDeco(context),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
(currentInputText != "")
|
||||
? IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
|
||||
onPressed: () {
|
||||
_sendMessage();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
)
|
||||
: IconButton(
|
||||
icon: FaIcon(FontAwesomeIcons.camera),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.contact);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class _StartNewChatView extends State<StartNewChatView> {
|
|||
super.initState();
|
||||
|
||||
Stream<List<Contact>> stream =
|
||||
twonlyDB.contactsDao.watchContactsForShareView();
|
||||
twonlyDB.contactsDao.watchContactsForStartNewChat();
|
||||
|
||||
contactSub = stream.listen((update) {
|
||||
update.sort((a, b) =>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:drift/drift.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/services/api/utils.dart';
|
||||
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||
import 'package:twonly/src/views/components/flame.dart';
|
||||
|
|
@ -22,6 +23,39 @@ class ContactView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ContactViewState extends State<ContactView> {
|
||||
Future handleUserRemoveRequest(Contact contact) async {
|
||||
bool remove = await showAlertDialog(
|
||||
context,
|
||||
context.lang.contactRemoveTitle(getContactDisplayName(contact)),
|
||||
context.lang.contactRemoveBody,
|
||||
);
|
||||
if (remove) {
|
||||
// trigger deletion for the other user...
|
||||
rejectUser(contact.userId);
|
||||
await deleteContact(contact.userId);
|
||||
if (mounted) {
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future handleUserBlockRequest(Contact contact) async {
|
||||
bool block = await showAlertDialog(
|
||||
context,
|
||||
context.lang.contactBlockTitle(getContactDisplayName(contact)),
|
||||
context.lang.contactBlockBody,
|
||||
);
|
||||
if (block) {
|
||||
final update = ContactsCompanion(blocked: Value(true));
|
||||
if (context.mounted) {
|
||||
await twonlyDB.contactsDao.updateContact(contact.userId, update);
|
||||
}
|
||||
if (context.mounted) {
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Stream<Contact?> contact = twonlyDB.contactsDao
|
||||
|
|
@ -93,7 +127,8 @@ class _ContactViewState extends State<ContactView> {
|
|||
},
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.trashCan,
|
||||
icon: FontAwesomeIcons.eraser,
|
||||
iconSize: 16,
|
||||
text: context.lang.deleteAllContactMessages,
|
||||
onTap: () async {
|
||||
bool block = await showAlertDialog(
|
||||
|
|
@ -114,24 +149,14 @@ class _ContactViewState extends State<ContactView> {
|
|||
icon: FontAwesomeIcons.ban,
|
||||
color: Colors.red,
|
||||
text: context.lang.contactBlock,
|
||||
onTap: () async {
|
||||
bool block = await showAlertDialog(
|
||||
context,
|
||||
context.lang
|
||||
.contactBlockTitle(getContactDisplayName(contact)),
|
||||
context.lang.contactBlockBody,
|
||||
);
|
||||
if (block) {
|
||||
final update = ContactsCompanion(blocked: Value(true));
|
||||
if (context.mounted) {
|
||||
await twonlyDB.contactsDao
|
||||
.updateContact(contact.userId, update);
|
||||
}
|
||||
if (context.mounted) {
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
}
|
||||
}
|
||||
},
|
||||
onTap: () => handleUserBlockRequest(contact),
|
||||
),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.userMinus,
|
||||
iconSize: 16,
|
||||
color: Colors.red,
|
||||
text: context.lang.contactRemove,
|
||||
onTap: () => handleUserRemoveRequest(contact),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,15 @@ class _AccountViewState extends State<AccountView> {
|
|||
.settingsAccountDeleteAccountWithBallance(
|
||||
formattedBallance!))
|
||||
: Text(context.lang.settingsAccountDeleteAccountNoBallance),
|
||||
onLongPress: (kDebugMode)
|
||||
? () async {
|
||||
await deleteLocalUserData();
|
||||
Restart.restartApp(
|
||||
notificationTitle: 'Account successfully deleted',
|
||||
notificationBody: 'Click here to open the app again',
|
||||
);
|
||||
}
|
||||
: null,
|
||||
onTap: (formattedBallance == null)
|
||||
? null
|
||||
: () async {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ class Contacts extends Table with TableInfo<Contacts, ContactsData> {
|
|||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'),
|
||||
defaultValue: const CustomExpression('0'));
|
||||
late final GeneratedColumn<bool> deleted = GeneratedColumn<bool>(
|
||||
'deleted', aliasedName, false,
|
||||
type: DriftSqlType.bool,
|
||||
requiredDuringInsert: false,
|
||||
defaultConstraints:
|
||||
GeneratedColumn.constraintIsAlways('CHECK ("deleted" IN (0, 1))'),
|
||||
defaultValue: const CustomExpression('0'));
|
||||
late final GeneratedColumn<bool> alsoBestFriend = GeneratedColumn<bool>(
|
||||
'also_best_friend', aliasedName, false,
|
||||
type: DriftSqlType.bool,
|
||||
|
|
@ -133,6 +140,7 @@ class Contacts extends Table with TableInfo<Contacts, ContactsData> {
|
|||
verified,
|
||||
archived,
|
||||
pinned,
|
||||
deleted,
|
||||
alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes,
|
||||
createdAt,
|
||||
|
|
@ -179,6 +187,8 @@ class Contacts extends Table with TableInfo<Contacts, ContactsData> {
|
|||
.read(DriftSqlType.bool, data['${effectivePrefix}archived'])!,
|
||||
pinned: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}pinned'])!,
|
||||
deleted: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}deleted'])!,
|
||||
alsoBestFriend: attachedDatabase.typeMapping
|
||||
.read(DriftSqlType.bool, data['${effectivePrefix}also_best_friend'])!,
|
||||
deleteMessagesAfterXMinutes: attachedDatabase.typeMapping.read(
|
||||
|
|
@ -225,6 +235,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
final bool verified;
|
||||
final bool archived;
|
||||
final bool pinned;
|
||||
final bool deleted;
|
||||
final bool alsoBestFriend;
|
||||
final int deleteMessagesAfterXMinutes;
|
||||
final DateTime createdAt;
|
||||
|
|
@ -248,6 +259,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
required this.verified,
|
||||
required this.archived,
|
||||
required this.pinned,
|
||||
required this.deleted,
|
||||
required this.alsoBestFriend,
|
||||
required this.deleteMessagesAfterXMinutes,
|
||||
required this.createdAt,
|
||||
|
|
@ -279,6 +291,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
map['verified'] = Variable<bool>(verified);
|
||||
map['archived'] = Variable<bool>(archived);
|
||||
map['pinned'] = Variable<bool>(pinned);
|
||||
map['deleted'] = Variable<bool>(deleted);
|
||||
map['also_best_friend'] = Variable<bool>(alsoBestFriend);
|
||||
map['delete_messages_after_x_minutes'] =
|
||||
Variable<int>(deleteMessagesAfterXMinutes);
|
||||
|
|
@ -322,6 +335,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
verified: Value(verified),
|
||||
archived: Value(archived),
|
||||
pinned: Value(pinned),
|
||||
deleted: Value(deleted),
|
||||
alsoBestFriend: Value(alsoBestFriend),
|
||||
deleteMessagesAfterXMinutes: Value(deleteMessagesAfterXMinutes),
|
||||
createdAt: Value(createdAt),
|
||||
|
|
@ -359,6 +373,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
verified: serializer.fromJson<bool>(json['verified']),
|
||||
archived: serializer.fromJson<bool>(json['archived']),
|
||||
pinned: serializer.fromJson<bool>(json['pinned']),
|
||||
deleted: serializer.fromJson<bool>(json['deleted']),
|
||||
alsoBestFriend: serializer.fromJson<bool>(json['alsoBestFriend']),
|
||||
deleteMessagesAfterXMinutes:
|
||||
serializer.fromJson<int>(json['deleteMessagesAfterXMinutes']),
|
||||
|
|
@ -391,6 +406,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
'verified': serializer.toJson<bool>(verified),
|
||||
'archived': serializer.toJson<bool>(archived),
|
||||
'pinned': serializer.toJson<bool>(pinned),
|
||||
'deleted': serializer.toJson<bool>(deleted),
|
||||
'alsoBestFriend': serializer.toJson<bool>(alsoBestFriend),
|
||||
'deleteMessagesAfterXMinutes':
|
||||
serializer.toJson<int>(deleteMessagesAfterXMinutes),
|
||||
|
|
@ -419,6 +435,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
bool? verified,
|
||||
bool? archived,
|
||||
bool? pinned,
|
||||
bool? deleted,
|
||||
bool? alsoBestFriend,
|
||||
int? deleteMessagesAfterXMinutes,
|
||||
DateTime? createdAt,
|
||||
|
|
@ -442,6 +459,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
verified: verified ?? this.verified,
|
||||
archived: archived ?? this.archived,
|
||||
pinned: pinned ?? this.pinned,
|
||||
deleted: deleted ?? this.deleted,
|
||||
alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes:
|
||||
deleteMessagesAfterXMinutes ?? this.deleteMessagesAfterXMinutes,
|
||||
|
|
@ -478,6 +496,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
verified: data.verified.present ? data.verified.value : this.verified,
|
||||
archived: data.archived.present ? data.archived.value : this.archived,
|
||||
pinned: data.pinned.present ? data.pinned.value : this.pinned,
|
||||
deleted: data.deleted.present ? data.deleted.value : this.deleted,
|
||||
alsoBestFriend: data.alsoBestFriend.present
|
||||
? data.alsoBestFriend.value
|
||||
: this.alsoBestFriend,
|
||||
|
|
@ -524,6 +543,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
..write('verified: $verified, ')
|
||||
..write('archived: $archived, ')
|
||||
..write('pinned: $pinned, ')
|
||||
..write('deleted: $deleted, ')
|
||||
..write('alsoBestFriend: $alsoBestFriend, ')
|
||||
..write('deleteMessagesAfterXMinutes: $deleteMessagesAfterXMinutes, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
|
|
@ -552,6 +572,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
verified,
|
||||
archived,
|
||||
pinned,
|
||||
deleted,
|
||||
alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes,
|
||||
createdAt,
|
||||
|
|
@ -579,6 +600,7 @@ class ContactsData extends DataClass implements Insertable<ContactsData> {
|
|||
other.verified == this.verified &&
|
||||
other.archived == this.archived &&
|
||||
other.pinned == this.pinned &&
|
||||
other.deleted == this.deleted &&
|
||||
other.alsoBestFriend == this.alsoBestFriend &&
|
||||
other.deleteMessagesAfterXMinutes ==
|
||||
this.deleteMessagesAfterXMinutes &&
|
||||
|
|
@ -605,6 +627,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
final Value<bool> verified;
|
||||
final Value<bool> archived;
|
||||
final Value<bool> pinned;
|
||||
final Value<bool> deleted;
|
||||
final Value<bool> alsoBestFriend;
|
||||
final Value<int> deleteMessagesAfterXMinutes;
|
||||
final Value<DateTime> createdAt;
|
||||
|
|
@ -628,6 +651,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
this.verified = const Value.absent(),
|
||||
this.archived = const Value.absent(),
|
||||
this.pinned = const Value.absent(),
|
||||
this.deleted = const Value.absent(),
|
||||
this.alsoBestFriend = const Value.absent(),
|
||||
this.deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
|
|
@ -652,6 +676,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
this.verified = const Value.absent(),
|
||||
this.archived = const Value.absent(),
|
||||
this.pinned = const Value.absent(),
|
||||
this.deleted = const Value.absent(),
|
||||
this.alsoBestFriend = const Value.absent(),
|
||||
this.deleteMessagesAfterXMinutes = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
|
|
@ -676,6 +701,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
Expression<bool>? verified,
|
||||
Expression<bool>? archived,
|
||||
Expression<bool>? pinned,
|
||||
Expression<bool>? deleted,
|
||||
Expression<bool>? alsoBestFriend,
|
||||
Expression<int>? deleteMessagesAfterXMinutes,
|
||||
Expression<DateTime>? createdAt,
|
||||
|
|
@ -700,6 +726,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
if (verified != null) 'verified': verified,
|
||||
if (archived != null) 'archived': archived,
|
||||
if (pinned != null) 'pinned': pinned,
|
||||
if (deleted != null) 'deleted': deleted,
|
||||
if (alsoBestFriend != null) 'also_best_friend': alsoBestFriend,
|
||||
if (deleteMessagesAfterXMinutes != null)
|
||||
'delete_messages_after_x_minutes': deleteMessagesAfterXMinutes,
|
||||
|
|
@ -730,6 +757,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
Value<bool>? verified,
|
||||
Value<bool>? archived,
|
||||
Value<bool>? pinned,
|
||||
Value<bool>? deleted,
|
||||
Value<bool>? alsoBestFriend,
|
||||
Value<int>? deleteMessagesAfterXMinutes,
|
||||
Value<DateTime>? createdAt,
|
||||
|
|
@ -753,6 +781,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
verified: verified ?? this.verified,
|
||||
archived: archived ?? this.archived,
|
||||
pinned: pinned ?? this.pinned,
|
||||
deleted: deleted ?? this.deleted,
|
||||
alsoBestFriend: alsoBestFriend ?? this.alsoBestFriend,
|
||||
deleteMessagesAfterXMinutes:
|
||||
deleteMessagesAfterXMinutes ?? this.deleteMessagesAfterXMinutes,
|
||||
|
|
@ -807,6 +836,9 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
if (pinned.present) {
|
||||
map['pinned'] = Variable<bool>(pinned.value);
|
||||
}
|
||||
if (deleted.present) {
|
||||
map['deleted'] = Variable<bool>(deleted.value);
|
||||
}
|
||||
if (alsoBestFriend.present) {
|
||||
map['also_best_friend'] = Variable<bool>(alsoBestFriend.value);
|
||||
}
|
||||
|
|
@ -859,6 +891,7 @@ class ContactsCompanion extends UpdateCompanion<ContactsData> {
|
|||
..write('verified: $verified, ')
|
||||
..write('archived: $archived, ')
|
||||
..write('pinned: $pinned, ')
|
||||
..write('deleted: $deleted, ')
|
||||
..write('alsoBestFriend: $alsoBestFriend, ')
|
||||
..write('deleteMessagesAfterXMinutes: $deleteMessagesAfterXMinutes, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
|
|
@ -3176,7 +3209,7 @@ class SignalContactSignedPreKeys extends Table
|
|||
SignalContactSignedPreKeys(this.attachedDatabase, [this._alias]);
|
||||
late final GeneratedColumn<int> contactId = GeneratedColumn<int>(
|
||||
'contact_id', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
type: DriftSqlType.int, requiredDuringInsert: false);
|
||||
late final GeneratedColumn<int> signedPreKeyId = GeneratedColumn<int>(
|
||||
'signed_pre_key_id', aliasedName, false,
|
||||
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||
|
|
@ -3206,7 +3239,7 @@ class SignalContactSignedPreKeys extends Table
|
|||
String get actualTableName => $name;
|
||||
static const String $name = 'signal_contact_signed_pre_keys';
|
||||
@override
|
||||
Set<GeneratedColumn> get $primaryKey => {contactId, signedPreKeyId};
|
||||
Set<GeneratedColumn> get $primaryKey => {contactId};
|
||||
@override
|
||||
SignalContactSignedPreKeysData map(Map<String, dynamic> data,
|
||||
{String? tablePrefix}) {
|
||||
|
|
@ -3361,24 +3394,20 @@ class SignalContactSignedPreKeysCompanion
|
|||
final Value<Uint8List> signedPreKey;
|
||||
final Value<Uint8List> signedPreKeySignature;
|
||||
final Value<DateTime> createdAt;
|
||||
final Value<int> rowid;
|
||||
const SignalContactSignedPreKeysCompanion({
|
||||
this.contactId = const Value.absent(),
|
||||
this.signedPreKeyId = const Value.absent(),
|
||||
this.signedPreKey = const Value.absent(),
|
||||
this.signedPreKeySignature = const Value.absent(),
|
||||
this.createdAt = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
});
|
||||
SignalContactSignedPreKeysCompanion.insert({
|
||||
required int contactId,
|
||||
this.contactId = const Value.absent(),
|
||||
required int signedPreKeyId,
|
||||
required Uint8List signedPreKey,
|
||||
required Uint8List signedPreKeySignature,
|
||||
this.createdAt = const Value.absent(),
|
||||
this.rowid = const Value.absent(),
|
||||
}) : contactId = Value(contactId),
|
||||
signedPreKeyId = Value(signedPreKeyId),
|
||||
}) : signedPreKeyId = Value(signedPreKeyId),
|
||||
signedPreKey = Value(signedPreKey),
|
||||
signedPreKeySignature = Value(signedPreKeySignature);
|
||||
static Insertable<SignalContactSignedPreKeysData> custom({
|
||||
|
|
@ -3387,7 +3416,6 @@ class SignalContactSignedPreKeysCompanion
|
|||
Expression<Uint8List>? signedPreKey,
|
||||
Expression<Uint8List>? signedPreKeySignature,
|
||||
Expression<DateTime>? createdAt,
|
||||
Expression<int>? rowid,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (contactId != null) 'contact_id': contactId,
|
||||
|
|
@ -3396,7 +3424,6 @@ class SignalContactSignedPreKeysCompanion
|
|||
if (signedPreKeySignature != null)
|
||||
'signed_pre_key_signature': signedPreKeySignature,
|
||||
if (createdAt != null) 'created_at': createdAt,
|
||||
if (rowid != null) 'rowid': rowid,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -3405,8 +3432,7 @@ class SignalContactSignedPreKeysCompanion
|
|||
Value<int>? signedPreKeyId,
|
||||
Value<Uint8List>? signedPreKey,
|
||||
Value<Uint8List>? signedPreKeySignature,
|
||||
Value<DateTime>? createdAt,
|
||||
Value<int>? rowid}) {
|
||||
Value<DateTime>? createdAt}) {
|
||||
return SignalContactSignedPreKeysCompanion(
|
||||
contactId: contactId ?? this.contactId,
|
||||
signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId,
|
||||
|
|
@ -3414,7 +3440,6 @@ class SignalContactSignedPreKeysCompanion
|
|||
signedPreKeySignature:
|
||||
signedPreKeySignature ?? this.signedPreKeySignature,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
rowid: rowid ?? this.rowid,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -3437,9 +3462,6 @@ class SignalContactSignedPreKeysCompanion
|
|||
if (createdAt.present) {
|
||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||
}
|
||||
if (rowid.present) {
|
||||
map['rowid'] = Variable<int>(rowid.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
@ -3450,8 +3472,7 @@ class SignalContactSignedPreKeysCompanion
|
|||
..write('signedPreKeyId: $signedPreKeyId, ')
|
||||
..write('signedPreKey: $signedPreKey, ')
|
||||
..write('signedPreKeySignature: $signedPreKeySignature, ')
|
||||
..write('createdAt: $createdAt, ')
|
||||
..write('rowid: $rowid')
|
||||
..write('createdAt: $createdAt')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
|
|
|||
3525
test/drift/twonly_database/generated/schema_v11.dart
Normal file
3525
test/drift/twonly_database/generated/schema_v11.dart
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue