mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 14:28:40 +00:00
fix #75
This commit is contained in:
parent
f559e643b1
commit
875ebb9eab
33 changed files with 5168 additions and 107 deletions
13
build.yaml
Normal file
13
build.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
targets:
|
||||||
|
$default:
|
||||||
|
sources:
|
||||||
|
- lib/**
|
||||||
|
- "tool/**"
|
||||||
|
- pubspec.yaml
|
||||||
|
- lib/$lib$
|
||||||
|
- $package$
|
||||||
|
builders:
|
||||||
|
drift_dev:
|
||||||
|
options:
|
||||||
|
databases:
|
||||||
|
twonly_database: lib/src/database/twonly_database.dart
|
||||||
1
drift_schemas/twonly_database/drift_schema_v1.json
Normal file
1
drift_schemas/twonly_database/drift_schema_v1.json
Normal file
File diff suppressed because one or more lines are too long
1
drift_schemas/twonly_database/drift_schema_v2.json
Normal file
1
drift_schemas/twonly_database/drift_schema_v2.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -2,7 +2,7 @@ import 'dart:collection';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/components/verified_shield.dart';
|
import 'package:twonly/src/components/verified_shield.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/components/flame.dart';
|
import 'package:twonly/src/components/flame.dart';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/json_models/userdata.dart';
|
import 'package:twonly/src/json_models/userdata.dart';
|
||||||
|
|
||||||
|
|
@ -44,9 +44,6 @@ class ContactAvatar extends StatelessWidget {
|
||||||
height: proSize,
|
height: proSize,
|
||||||
width: proSize,
|
width: proSize,
|
||||||
child: Center(
|
child: Center(
|
||||||
// child: Container(
|
|
||||||
// color: Colors.green,
|
|
||||||
// ),
|
|
||||||
child: SvgPicture.string(
|
child: SvgPicture.string(
|
||||||
avatarSvg,
|
avatarSvg,
|
||||||
errorBuilder: (context, error, stackTrace) {
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,13 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
|
|
||||||
if (message.kind == MessageKind.storedMediaFile) {
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
icon = FaIcon(FontAwesomeIcons.floppyDisk, size: 12, color: color);
|
icon = FaIcon(FontAwesomeIcons.floppyDisk, size: 12, color: color);
|
||||||
text = "Stored in gallery";
|
text = context.lang.messageStoredInGalery;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.errorWhileSending) {
|
||||||
|
icon =
|
||||||
|
FaIcon(FontAwesomeIcons.circleExclamation, size: 12, color: color);
|
||||||
|
text = "Error while sending";
|
||||||
}
|
}
|
||||||
|
|
||||||
icons.add(icon);
|
icons.add(icon);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
class PermissionHandlerView extends StatefulWidget {
|
class PermissionHandlerView extends StatefulWidget {
|
||||||
|
|
@ -23,12 +24,14 @@ Future<bool> checkPermissions() async {
|
||||||
|
|
||||||
class PermissionHandlerViewState extends State<PermissionHandlerView> {
|
class PermissionHandlerViewState extends State<PermissionHandlerView> {
|
||||||
Future<Map<Permission, PermissionStatus>> permissionServices() async {
|
Future<Map<Permission, PermissionStatus>> permissionServices() async {
|
||||||
// You can request multiple permissions at once.
|
// try {
|
||||||
Map<Permission, PermissionStatus> statuses = await [
|
Map<Permission, PermissionStatus> statuses = await [
|
||||||
Permission.camera,
|
Permission.camera,
|
||||||
// Permission.microphone,
|
// Permission.microphone,
|
||||||
Permission.notification
|
Permission.notification
|
||||||
].request();
|
].request();
|
||||||
|
// } catch (e) {}
|
||||||
|
// You can request multiple permissions at once.
|
||||||
|
|
||||||
// if (statuses[Permission.microphone]!.isPermanentlyDenied) {
|
// if (statuses[Permission.microphone]!.isPermanentlyDenied) {
|
||||||
// openAppSettings();
|
// openAppSettings();
|
||||||
|
|
@ -70,9 +73,13 @@ class PermissionHandlerViewState extends State<PermissionHandlerView> {
|
||||||
label: Text("Request permissions"),
|
label: Text("Request permissions"),
|
||||||
icon: const Icon(Icons.perm_camera_mic),
|
icon: const Icon(Icons.perm_camera_mic),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
permissionServices();
|
try {
|
||||||
if (await checkPermissions()) {
|
permissionServices();
|
||||||
widget.onSuccess();
|
if (await checkPermissions()) {
|
||||||
|
widget.onSuccess();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Logger("permissions_view").shout(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -164,3 +164,28 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getContactDisplayName(Contact user) {
|
||||||
|
if (user.nickName != null) {
|
||||||
|
return user.nickName!;
|
||||||
|
}
|
||||||
|
if (user.displayName != null) {
|
||||||
|
return user.displayName!;
|
||||||
|
}
|
||||||
|
return user.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFlameCounterFromContact(Contact contact) {
|
||||||
|
if (contact.lastMessageSend == null || contact.lastMessageReceived == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
final now = DateTime.now();
|
||||||
|
final startOfToday = DateTime(now.year, now.month, now.day);
|
||||||
|
final twoDaysAgo = startOfToday.subtract(Duration(days: 2));
|
||||||
|
if (contact.lastMessageSend!.isAfter(twoDaysAgo) &&
|
||||||
|
contact.lastMessageReceived!.isAfter(twoDaysAgo)) {
|
||||||
|
return contact.flameCounter + 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/src/database/tables/contacts_table.dart';
|
||||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
|
||||||
|
|
||||||
part 'messages_dao.g.dart';
|
part 'messages_dao.g.dart';
|
||||||
|
|
||||||
@DriftAccessor(tables: [Messages])
|
@DriftAccessor(tables: [Messages, Contacts])
|
||||||
class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
with _$MessagesDaoMixin {
|
with _$MessagesDaoMixin {
|
||||||
// this constructor is required so that the main database can create an instance
|
// this constructor is required so that the main database can create an instance
|
||||||
|
|
@ -26,6 +25,7 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
..where((t) =>
|
..where((t) =>
|
||||||
t.openedAt.isNull() &
|
t.openedAt.isNull() &
|
||||||
t.contactId.equals(contactId) &
|
t.contactId.equals(contactId) &
|
||||||
|
t.errorWhileSending.equals(false) &
|
||||||
t.messageOtherId.isNotNull() &
|
t.messageOtherId.isNotNull() &
|
||||||
t.kind.equals(MessageKind.media.name))
|
t.kind.equals(MessageKind.media.name))
|
||||||
..orderBy([(t) => OrderingTerm.asc(t.sendAt)]))
|
..orderBy([(t) => OrderingTerm.asc(t.sendAt)]))
|
||||||
|
|
@ -72,8 +72,17 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Message>> getAllMessagesForRetransmitting() {
|
Future<List<Message>> getAllMessagesPendingUploadOlderThanAMinute() {
|
||||||
return (select(messages)..where((t) => t.acknowledgeByServer.equals(false)))
|
return (select(messages)
|
||||||
|
..where(
|
||||||
|
(t) =>
|
||||||
|
t.acknowledgeByServer.equals(false) &
|
||||||
|
t.messageOtherId.isNull() &
|
||||||
|
t.errorWhileSending.equals(false) &
|
||||||
|
t.sendAt.isSmallerThanValue(
|
||||||
|
DateTime.now().subtract(Duration(minutes: 5))) &
|
||||||
|
t.kind.equals(MessageKind.media.name),
|
||||||
|
))
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,8 +122,10 @@ class MessagesDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
|
|
||||||
Future<int?> insertMessage(MessagesCompanion message) async {
|
Future<int?> insertMessage(MessagesCompanion message) async {
|
||||||
try {
|
try {
|
||||||
await twonlyDatabase.contactsDao
|
await (update(contacts)
|
||||||
.newMessageExchange(message.contactId.value);
|
..where((c) => c.userId.equals(message.contactId.value)))
|
||||||
|
.write(ContactsCompanion(lastMessageExchange: Value(DateTime.now())));
|
||||||
|
|
||||||
return await into(messages).insert(message);
|
return await into(messages).insert(message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger("twonlyDatabase").shout("Error while inserting message: $e");
|
Logger("twonlyDatabase").shout("Error while inserting message: $e");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
|
||||||
|
|
||||||
class Contacts extends Table {
|
class Contacts extends Table {
|
||||||
IntColumn get userId => integer()();
|
IntColumn get userId => integer()();
|
||||||
|
|
@ -31,28 +30,3 @@ class Contacts extends Table {
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {userId};
|
Set<Column> get primaryKey => {userId};
|
||||||
}
|
}
|
||||||
|
|
||||||
String getContactDisplayName(Contact user) {
|
|
||||||
if (user.nickName != null) {
|
|
||||||
return user.nickName!;
|
|
||||||
}
|
|
||||||
if (user.displayName != null) {
|
|
||||||
return user.displayName!;
|
|
||||||
}
|
|
||||||
return user.username;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getFlameCounterFromContact(Contact contact) {
|
|
||||||
if (contact.lastMessageSend == null || contact.lastMessageReceived == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
final now = DateTime.now();
|
|
||||||
final startOfToday = DateTime(now.year, now.month, now.day);
|
|
||||||
final twoDaysAgo = startOfToday.subtract(Duration(days: 2));
|
|
||||||
if (contact.lastMessageSend!.isAfter(twoDaysAgo) &&
|
|
||||||
contact.lastMessageReceived!.isAfter(twoDaysAgo)) {
|
|
||||||
return contact.flameCounter + 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,17 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/tables/contacts_table.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
|
||||||
|
enum MessageKind {
|
||||||
|
textMessage,
|
||||||
|
storedMediaFile,
|
||||||
|
media,
|
||||||
|
contactRequest,
|
||||||
|
profileChange,
|
||||||
|
rejectRequest,
|
||||||
|
acceptRequest,
|
||||||
|
opened,
|
||||||
|
ack
|
||||||
|
}
|
||||||
|
|
||||||
enum DownloadState {
|
enum DownloadState {
|
||||||
pending,
|
pending,
|
||||||
|
|
@ -25,6 +36,8 @@ class Messages extends Table {
|
||||||
BoolColumn get acknowledgeByServer =>
|
BoolColumn get acknowledgeByServer =>
|
||||||
boolean().withDefault(Constant(false))();
|
boolean().withDefault(Constant(false))();
|
||||||
|
|
||||||
|
BoolColumn get errorWhileSending => boolean().withDefault(Constant(false))();
|
||||||
|
|
||||||
TextColumn get kind => textEnum<MessageKind>()();
|
TextColumn get kind => textEnum<MessageKind>()();
|
||||||
TextColumn get contentJson => text().nullable()();
|
TextColumn get contentJson => text().nullable()();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_flutter/drift_flutter.dart';
|
import 'package:drift_flutter/drift_flutter.dart'
|
||||||
|
show driftDatabase, DriftNativeOptions;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/daos/messages_dao.dart';
|
import 'package:twonly/src/database/daos/messages_dao.dart';
|
||||||
|
|
@ -9,7 +10,7 @@ import 'package:twonly/src/database/tables/signal_identity_key_store_table.dart'
|
||||||
import 'package:twonly/src/database/tables/signal_pre_key_store_table.dart';
|
import 'package:twonly/src/database/tables/signal_pre_key_store_table.dart';
|
||||||
import 'package:twonly/src/database/tables/signal_sender_key_store_table.dart';
|
import 'package:twonly/src/database/tables/signal_sender_key_store_table.dart';
|
||||||
import 'package:twonly/src/database/tables/signal_session_store_table.dart';
|
import 'package:twonly/src/database/tables/signal_session_store_table.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
import 'package:twonly/src/database/twonly_database.steps.dart';
|
||||||
|
|
||||||
part 'twonly_database.g.dart';
|
part 'twonly_database.g.dart';
|
||||||
|
|
||||||
|
|
@ -26,10 +27,15 @@ part 'twonly_database.g.dart';
|
||||||
ContactsDao
|
ContactsDao
|
||||||
])
|
])
|
||||||
class TwonlyDatabase extends _$TwonlyDatabase {
|
class TwonlyDatabase extends _$TwonlyDatabase {
|
||||||
TwonlyDatabase() : super(_openConnection());
|
TwonlyDatabase([QueryExecutor? e])
|
||||||
|
: super(
|
||||||
|
e ?? _openConnection(),
|
||||||
|
);
|
||||||
|
|
||||||
|
TwonlyDatabase.forTesting(DatabaseConnection super.connection);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 1;
|
int get schemaVersion => 2;
|
||||||
|
|
||||||
static QueryExecutor _openConnection() {
|
static QueryExecutor _openConnection() {
|
||||||
return driftDatabase(
|
return driftDatabase(
|
||||||
|
|
@ -40,6 +46,15 @@ class TwonlyDatabase extends _$TwonlyDatabase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
MigrationStrategy get migration {
|
||||||
|
return MigrationStrategy(
|
||||||
|
onUpgrade: stepByStep(from1To2: (m, schema) async {
|
||||||
|
m.addColumn(schema.messages, schema.messages.errorWhileSending);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void markUpdated() {
|
void markUpdated() {
|
||||||
notifyUpdates({TableUpdate.onTable(messages, kind: UpdateKind.update)});
|
notifyUpdates({TableUpdate.onTable(messages, kind: UpdateKind.update)});
|
||||||
notifyUpdates({TableUpdate.onTable(contacts, kind: UpdateKind.update)});
|
notifyUpdates({TableUpdate.onTable(contacts, kind: UpdateKind.update)});
|
||||||
|
|
|
||||||
|
|
@ -904,6 +904,16 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
'CHECK ("acknowledge_by_server" IN (0, 1))'),
|
'CHECK ("acknowledge_by_server" IN (0, 1))'),
|
||||||
defaultValue: Constant(false));
|
defaultValue: Constant(false));
|
||||||
|
static const VerificationMeta _errorWhileSendingMeta =
|
||||||
|
const VerificationMeta('errorWhileSending');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> errorWhileSending = GeneratedColumn<bool>(
|
||||||
|
'error_while_sending', aliasedName, false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("error_while_sending" IN (0, 1))'),
|
||||||
|
defaultValue: Constant(false));
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<MessageKind, String> kind =
|
late final GeneratedColumnWithTypeConverter<MessageKind, String> kind =
|
||||||
GeneratedColumn<String>('kind', aliasedName, false,
|
GeneratedColumn<String>('kind', aliasedName, false,
|
||||||
|
|
@ -946,6 +956,7 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
acknowledgeByUser,
|
acknowledgeByUser,
|
||||||
downloadState,
|
downloadState,
|
||||||
acknowledgeByServer,
|
acknowledgeByServer,
|
||||||
|
errorWhileSending,
|
||||||
kind,
|
kind,
|
||||||
contentJson,
|
contentJson,
|
||||||
openedAt,
|
openedAt,
|
||||||
|
|
@ -1003,6 +1014,12 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
acknowledgeByServer.isAcceptableOrUnknown(
|
acknowledgeByServer.isAcceptableOrUnknown(
|
||||||
data['acknowledge_by_server']!, _acknowledgeByServerMeta));
|
data['acknowledge_by_server']!, _acknowledgeByServerMeta));
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('error_while_sending')) {
|
||||||
|
context.handle(
|
||||||
|
_errorWhileSendingMeta,
|
||||||
|
errorWhileSending.isAcceptableOrUnknown(
|
||||||
|
data['error_while_sending']!, _errorWhileSendingMeta));
|
||||||
|
}
|
||||||
if (data.containsKey('content_json')) {
|
if (data.containsKey('content_json')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_contentJsonMeta,
|
_contentJsonMeta,
|
||||||
|
|
@ -1048,6 +1065,8 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
DriftSqlType.int, data['${effectivePrefix}download_state'])!),
|
DriftSqlType.int, data['${effectivePrefix}download_state'])!),
|
||||||
acknowledgeByServer: attachedDatabase.typeMapping.read(
|
acknowledgeByServer: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.bool, data['${effectivePrefix}acknowledge_by_server'])!,
|
DriftSqlType.bool, data['${effectivePrefix}acknowledge_by_server'])!,
|
||||||
|
errorWhileSending: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool, data['${effectivePrefix}error_while_sending'])!,
|
||||||
kind: $MessagesTable.$converterkind.fromSql(attachedDatabase.typeMapping
|
kind: $MessagesTable.$converterkind.fromSql(attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}kind'])!),
|
.read(DriftSqlType.string, data['${effectivePrefix}kind'])!),
|
||||||
contentJson: attachedDatabase.typeMapping
|
contentJson: attachedDatabase.typeMapping
|
||||||
|
|
@ -1081,6 +1100,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
final bool acknowledgeByUser;
|
final bool acknowledgeByUser;
|
||||||
final DownloadState downloadState;
|
final DownloadState downloadState;
|
||||||
final bool acknowledgeByServer;
|
final bool acknowledgeByServer;
|
||||||
|
final bool errorWhileSending;
|
||||||
final MessageKind kind;
|
final MessageKind kind;
|
||||||
final String? contentJson;
|
final String? contentJson;
|
||||||
final DateTime? openedAt;
|
final DateTime? openedAt;
|
||||||
|
|
@ -1095,6 +1115,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
required this.acknowledgeByUser,
|
required this.acknowledgeByUser,
|
||||||
required this.downloadState,
|
required this.downloadState,
|
||||||
required this.acknowledgeByServer,
|
required this.acknowledgeByServer,
|
||||||
|
required this.errorWhileSending,
|
||||||
required this.kind,
|
required this.kind,
|
||||||
this.contentJson,
|
this.contentJson,
|
||||||
this.openedAt,
|
this.openedAt,
|
||||||
|
|
@ -1121,6 +1142,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
$MessagesTable.$converterdownloadState.toSql(downloadState));
|
$MessagesTable.$converterdownloadState.toSql(downloadState));
|
||||||
}
|
}
|
||||||
map['acknowledge_by_server'] = Variable<bool>(acknowledgeByServer);
|
map['acknowledge_by_server'] = Variable<bool>(acknowledgeByServer);
|
||||||
|
map['error_while_sending'] = Variable<bool>(errorWhileSending);
|
||||||
{
|
{
|
||||||
map['kind'] = Variable<String>($MessagesTable.$converterkind.toSql(kind));
|
map['kind'] = Variable<String>($MessagesTable.$converterkind.toSql(kind));
|
||||||
}
|
}
|
||||||
|
|
@ -1151,6 +1173,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
acknowledgeByUser: Value(acknowledgeByUser),
|
acknowledgeByUser: Value(acknowledgeByUser),
|
||||||
downloadState: Value(downloadState),
|
downloadState: Value(downloadState),
|
||||||
acknowledgeByServer: Value(acknowledgeByServer),
|
acknowledgeByServer: Value(acknowledgeByServer),
|
||||||
|
errorWhileSending: Value(errorWhileSending),
|
||||||
kind: Value(kind),
|
kind: Value(kind),
|
||||||
contentJson: contentJson == null && nullToAbsent
|
contentJson: contentJson == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
|
|
@ -1179,6 +1202,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
.fromJson(serializer.fromJson<int>(json['downloadState'])),
|
.fromJson(serializer.fromJson<int>(json['downloadState'])),
|
||||||
acknowledgeByServer:
|
acknowledgeByServer:
|
||||||
serializer.fromJson<bool>(json['acknowledgeByServer']),
|
serializer.fromJson<bool>(json['acknowledgeByServer']),
|
||||||
|
errorWhileSending: serializer.fromJson<bool>(json['errorWhileSending']),
|
||||||
kind: $MessagesTable.$converterkind
|
kind: $MessagesTable.$converterkind
|
||||||
.fromJson(serializer.fromJson<String>(json['kind'])),
|
.fromJson(serializer.fromJson<String>(json['kind'])),
|
||||||
contentJson: serializer.fromJson<String?>(json['contentJson']),
|
contentJson: serializer.fromJson<String?>(json['contentJson']),
|
||||||
|
|
@ -1201,6 +1225,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
'downloadState': serializer.toJson<int>(
|
'downloadState': serializer.toJson<int>(
|
||||||
$MessagesTable.$converterdownloadState.toJson(downloadState)),
|
$MessagesTable.$converterdownloadState.toJson(downloadState)),
|
||||||
'acknowledgeByServer': serializer.toJson<bool>(acknowledgeByServer),
|
'acknowledgeByServer': serializer.toJson<bool>(acknowledgeByServer),
|
||||||
|
'errorWhileSending': serializer.toJson<bool>(errorWhileSending),
|
||||||
'kind':
|
'kind':
|
||||||
serializer.toJson<String>($MessagesTable.$converterkind.toJson(kind)),
|
serializer.toJson<String>($MessagesTable.$converterkind.toJson(kind)),
|
||||||
'contentJson': serializer.toJson<String?>(contentJson),
|
'contentJson': serializer.toJson<String?>(contentJson),
|
||||||
|
|
@ -1219,6 +1244,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
bool? acknowledgeByUser,
|
bool? acknowledgeByUser,
|
||||||
DownloadState? downloadState,
|
DownloadState? downloadState,
|
||||||
bool? acknowledgeByServer,
|
bool? acknowledgeByServer,
|
||||||
|
bool? errorWhileSending,
|
||||||
MessageKind? kind,
|
MessageKind? kind,
|
||||||
Value<String?> contentJson = const Value.absent(),
|
Value<String?> contentJson = const Value.absent(),
|
||||||
Value<DateTime?> openedAt = const Value.absent(),
|
Value<DateTime?> openedAt = const Value.absent(),
|
||||||
|
|
@ -1238,6 +1264,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
acknowledgeByUser: acknowledgeByUser ?? this.acknowledgeByUser,
|
acknowledgeByUser: acknowledgeByUser ?? this.acknowledgeByUser,
|
||||||
downloadState: downloadState ?? this.downloadState,
|
downloadState: downloadState ?? this.downloadState,
|
||||||
acknowledgeByServer: acknowledgeByServer ?? this.acknowledgeByServer,
|
acknowledgeByServer: acknowledgeByServer ?? this.acknowledgeByServer,
|
||||||
|
errorWhileSending: errorWhileSending ?? this.errorWhileSending,
|
||||||
kind: kind ?? this.kind,
|
kind: kind ?? this.kind,
|
||||||
contentJson: contentJson.present ? contentJson.value : this.contentJson,
|
contentJson: contentJson.present ? contentJson.value : this.contentJson,
|
||||||
openedAt: openedAt.present ? openedAt.value : this.openedAt,
|
openedAt: openedAt.present ? openedAt.value : this.openedAt,
|
||||||
|
|
@ -1266,6 +1293,9 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
acknowledgeByServer: data.acknowledgeByServer.present
|
acknowledgeByServer: data.acknowledgeByServer.present
|
||||||
? data.acknowledgeByServer.value
|
? data.acknowledgeByServer.value
|
||||||
: this.acknowledgeByServer,
|
: this.acknowledgeByServer,
|
||||||
|
errorWhileSending: data.errorWhileSending.present
|
||||||
|
? data.errorWhileSending.value
|
||||||
|
: this.errorWhileSending,
|
||||||
kind: data.kind.present ? data.kind.value : this.kind,
|
kind: data.kind.present ? data.kind.value : this.kind,
|
||||||
contentJson:
|
contentJson:
|
||||||
data.contentJson.present ? data.contentJson.value : this.contentJson,
|
data.contentJson.present ? data.contentJson.value : this.contentJson,
|
||||||
|
|
@ -1286,6 +1316,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
..write('acknowledgeByUser: $acknowledgeByUser, ')
|
..write('acknowledgeByUser: $acknowledgeByUser, ')
|
||||||
..write('downloadState: $downloadState, ')
|
..write('downloadState: $downloadState, ')
|
||||||
..write('acknowledgeByServer: $acknowledgeByServer, ')
|
..write('acknowledgeByServer: $acknowledgeByServer, ')
|
||||||
|
..write('errorWhileSending: $errorWhileSending, ')
|
||||||
..write('kind: $kind, ')
|
..write('kind: $kind, ')
|
||||||
..write('contentJson: $contentJson, ')
|
..write('contentJson: $contentJson, ')
|
||||||
..write('openedAt: $openedAt, ')
|
..write('openedAt: $openedAt, ')
|
||||||
|
|
@ -1305,6 +1336,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
acknowledgeByUser,
|
acknowledgeByUser,
|
||||||
downloadState,
|
downloadState,
|
||||||
acknowledgeByServer,
|
acknowledgeByServer,
|
||||||
|
errorWhileSending,
|
||||||
kind,
|
kind,
|
||||||
contentJson,
|
contentJson,
|
||||||
openedAt,
|
openedAt,
|
||||||
|
|
@ -1322,6 +1354,7 @@ class Message extends DataClass implements Insertable<Message> {
|
||||||
other.acknowledgeByUser == this.acknowledgeByUser &&
|
other.acknowledgeByUser == this.acknowledgeByUser &&
|
||||||
other.downloadState == this.downloadState &&
|
other.downloadState == this.downloadState &&
|
||||||
other.acknowledgeByServer == this.acknowledgeByServer &&
|
other.acknowledgeByServer == this.acknowledgeByServer &&
|
||||||
|
other.errorWhileSending == this.errorWhileSending &&
|
||||||
other.kind == this.kind &&
|
other.kind == this.kind &&
|
||||||
other.contentJson == this.contentJson &&
|
other.contentJson == this.contentJson &&
|
||||||
other.openedAt == this.openedAt &&
|
other.openedAt == this.openedAt &&
|
||||||
|
|
@ -1338,6 +1371,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
final Value<bool> acknowledgeByUser;
|
final Value<bool> acknowledgeByUser;
|
||||||
final Value<DownloadState> downloadState;
|
final Value<DownloadState> downloadState;
|
||||||
final Value<bool> acknowledgeByServer;
|
final Value<bool> acknowledgeByServer;
|
||||||
|
final Value<bool> errorWhileSending;
|
||||||
final Value<MessageKind> kind;
|
final Value<MessageKind> kind;
|
||||||
final Value<String?> contentJson;
|
final Value<String?> contentJson;
|
||||||
final Value<DateTime?> openedAt;
|
final Value<DateTime?> openedAt;
|
||||||
|
|
@ -1352,6 +1386,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
this.acknowledgeByUser = const Value.absent(),
|
this.acknowledgeByUser = const Value.absent(),
|
||||||
this.downloadState = const Value.absent(),
|
this.downloadState = const Value.absent(),
|
||||||
this.acknowledgeByServer = const Value.absent(),
|
this.acknowledgeByServer = const Value.absent(),
|
||||||
|
this.errorWhileSending = const Value.absent(),
|
||||||
this.kind = const Value.absent(),
|
this.kind = const Value.absent(),
|
||||||
this.contentJson = const Value.absent(),
|
this.contentJson = const Value.absent(),
|
||||||
this.openedAt = const Value.absent(),
|
this.openedAt = const Value.absent(),
|
||||||
|
|
@ -1367,6 +1402,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
this.acknowledgeByUser = const Value.absent(),
|
this.acknowledgeByUser = const Value.absent(),
|
||||||
this.downloadState = const Value.absent(),
|
this.downloadState = const Value.absent(),
|
||||||
this.acknowledgeByServer = const Value.absent(),
|
this.acknowledgeByServer = const Value.absent(),
|
||||||
|
this.errorWhileSending = const Value.absent(),
|
||||||
required MessageKind kind,
|
required MessageKind kind,
|
||||||
this.contentJson = const Value.absent(),
|
this.contentJson = const Value.absent(),
|
||||||
this.openedAt = const Value.absent(),
|
this.openedAt = const Value.absent(),
|
||||||
|
|
@ -1383,6 +1419,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
Expression<bool>? acknowledgeByUser,
|
Expression<bool>? acknowledgeByUser,
|
||||||
Expression<int>? downloadState,
|
Expression<int>? downloadState,
|
||||||
Expression<bool>? acknowledgeByServer,
|
Expression<bool>? acknowledgeByServer,
|
||||||
|
Expression<bool>? errorWhileSending,
|
||||||
Expression<String>? kind,
|
Expression<String>? kind,
|
||||||
Expression<String>? contentJson,
|
Expression<String>? contentJson,
|
||||||
Expression<DateTime>? openedAt,
|
Expression<DateTime>? openedAt,
|
||||||
|
|
@ -1401,6 +1438,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
if (downloadState != null) 'download_state': downloadState,
|
if (downloadState != null) 'download_state': downloadState,
|
||||||
if (acknowledgeByServer != null)
|
if (acknowledgeByServer != null)
|
||||||
'acknowledge_by_server': acknowledgeByServer,
|
'acknowledge_by_server': acknowledgeByServer,
|
||||||
|
if (errorWhileSending != null) 'error_while_sending': errorWhileSending,
|
||||||
if (kind != null) 'kind': kind,
|
if (kind != null) 'kind': kind,
|
||||||
if (contentJson != null) 'content_json': contentJson,
|
if (contentJson != null) 'content_json': contentJson,
|
||||||
if (openedAt != null) 'opened_at': openedAt,
|
if (openedAt != null) 'opened_at': openedAt,
|
||||||
|
|
@ -1418,6 +1456,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
Value<bool>? acknowledgeByUser,
|
Value<bool>? acknowledgeByUser,
|
||||||
Value<DownloadState>? downloadState,
|
Value<DownloadState>? downloadState,
|
||||||
Value<bool>? acknowledgeByServer,
|
Value<bool>? acknowledgeByServer,
|
||||||
|
Value<bool>? errorWhileSending,
|
||||||
Value<MessageKind>? kind,
|
Value<MessageKind>? kind,
|
||||||
Value<String?>? contentJson,
|
Value<String?>? contentJson,
|
||||||
Value<DateTime?>? openedAt,
|
Value<DateTime?>? openedAt,
|
||||||
|
|
@ -1433,6 +1472,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
acknowledgeByUser: acknowledgeByUser ?? this.acknowledgeByUser,
|
acknowledgeByUser: acknowledgeByUser ?? this.acknowledgeByUser,
|
||||||
downloadState: downloadState ?? this.downloadState,
|
downloadState: downloadState ?? this.downloadState,
|
||||||
acknowledgeByServer: acknowledgeByServer ?? this.acknowledgeByServer,
|
acknowledgeByServer: acknowledgeByServer ?? this.acknowledgeByServer,
|
||||||
|
errorWhileSending: errorWhileSending ?? this.errorWhileSending,
|
||||||
kind: kind ?? this.kind,
|
kind: kind ?? this.kind,
|
||||||
contentJson: contentJson ?? this.contentJson,
|
contentJson: contentJson ?? this.contentJson,
|
||||||
openedAt: openedAt ?? this.openedAt,
|
openedAt: openedAt ?? this.openedAt,
|
||||||
|
|
@ -1470,6 +1510,9 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
if (acknowledgeByServer.present) {
|
if (acknowledgeByServer.present) {
|
||||||
map['acknowledge_by_server'] = Variable<bool>(acknowledgeByServer.value);
|
map['acknowledge_by_server'] = Variable<bool>(acknowledgeByServer.value);
|
||||||
}
|
}
|
||||||
|
if (errorWhileSending.present) {
|
||||||
|
map['error_while_sending'] = Variable<bool>(errorWhileSending.value);
|
||||||
|
}
|
||||||
if (kind.present) {
|
if (kind.present) {
|
||||||
map['kind'] =
|
map['kind'] =
|
||||||
Variable<String>($MessagesTable.$converterkind.toSql(kind.value));
|
Variable<String>($MessagesTable.$converterkind.toSql(kind.value));
|
||||||
|
|
@ -1500,6 +1543,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
|
||||||
..write('acknowledgeByUser: $acknowledgeByUser, ')
|
..write('acknowledgeByUser: $acknowledgeByUser, ')
|
||||||
..write('downloadState: $downloadState, ')
|
..write('downloadState: $downloadState, ')
|
||||||
..write('acknowledgeByServer: $acknowledgeByServer, ')
|
..write('acknowledgeByServer: $acknowledgeByServer, ')
|
||||||
|
..write('errorWhileSending: $errorWhileSending, ')
|
||||||
..write('kind: $kind, ')
|
..write('kind: $kind, ')
|
||||||
..write('contentJson: $contentJson, ')
|
..write('contentJson: $contentJson, ')
|
||||||
..write('openedAt: $openedAt, ')
|
..write('openedAt: $openedAt, ')
|
||||||
|
|
@ -2966,6 +3010,7 @@ typedef $$MessagesTableCreateCompanionBuilder = MessagesCompanion Function({
|
||||||
Value<bool> acknowledgeByUser,
|
Value<bool> acknowledgeByUser,
|
||||||
Value<DownloadState> downloadState,
|
Value<DownloadState> downloadState,
|
||||||
Value<bool> acknowledgeByServer,
|
Value<bool> acknowledgeByServer,
|
||||||
|
Value<bool> errorWhileSending,
|
||||||
required MessageKind kind,
|
required MessageKind kind,
|
||||||
Value<String?> contentJson,
|
Value<String?> contentJson,
|
||||||
Value<DateTime?> openedAt,
|
Value<DateTime?> openedAt,
|
||||||
|
|
@ -2981,6 +3026,7 @@ typedef $$MessagesTableUpdateCompanionBuilder = MessagesCompanion Function({
|
||||||
Value<bool> acknowledgeByUser,
|
Value<bool> acknowledgeByUser,
|
||||||
Value<DownloadState> downloadState,
|
Value<DownloadState> downloadState,
|
||||||
Value<bool> acknowledgeByServer,
|
Value<bool> acknowledgeByServer,
|
||||||
|
Value<bool> errorWhileSending,
|
||||||
Value<MessageKind> kind,
|
Value<MessageKind> kind,
|
||||||
Value<String?> contentJson,
|
Value<String?> contentJson,
|
||||||
Value<DateTime?> openedAt,
|
Value<DateTime?> openedAt,
|
||||||
|
|
@ -3045,6 +3091,10 @@ class $$MessagesTableFilterComposer
|
||||||
column: $table.acknowledgeByServer,
|
column: $table.acknowledgeByServer,
|
||||||
builder: (column) => ColumnFilters(column));
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<bool> get errorWhileSending => $composableBuilder(
|
||||||
|
column: $table.errorWhileSending,
|
||||||
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnWithTypeConverterFilters<MessageKind, MessageKind, String> get kind =>
|
ColumnWithTypeConverterFilters<MessageKind, MessageKind, String> get kind =>
|
||||||
$composableBuilder(
|
$composableBuilder(
|
||||||
column: $table.kind,
|
column: $table.kind,
|
||||||
|
|
@ -3119,6 +3169,10 @@ class $$MessagesTableOrderingComposer
|
||||||
column: $table.acknowledgeByServer,
|
column: $table.acknowledgeByServer,
|
||||||
builder: (column) => ColumnOrderings(column));
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<bool> get errorWhileSending => $composableBuilder(
|
||||||
|
column: $table.errorWhileSending,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get kind => $composableBuilder(
|
ColumnOrderings<String> get kind => $composableBuilder(
|
||||||
column: $table.kind, builder: (column) => ColumnOrderings(column));
|
column: $table.kind, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
|
@ -3186,6 +3240,9 @@ class $$MessagesTableAnnotationComposer
|
||||||
GeneratedColumn<bool> get acknowledgeByServer => $composableBuilder(
|
GeneratedColumn<bool> get acknowledgeByServer => $composableBuilder(
|
||||||
column: $table.acknowledgeByServer, builder: (column) => column);
|
column: $table.acknowledgeByServer, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<bool> get errorWhileSending => $composableBuilder(
|
||||||
|
column: $table.errorWhileSending, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumnWithTypeConverter<MessageKind, String> get kind =>
|
GeneratedColumnWithTypeConverter<MessageKind, String> get kind =>
|
||||||
$composableBuilder(column: $table.kind, builder: (column) => column);
|
$composableBuilder(column: $table.kind, builder: (column) => column);
|
||||||
|
|
||||||
|
|
@ -3253,6 +3310,7 @@ class $$MessagesTableTableManager extends RootTableManager<
|
||||||
Value<bool> acknowledgeByUser = const Value.absent(),
|
Value<bool> acknowledgeByUser = const Value.absent(),
|
||||||
Value<DownloadState> downloadState = const Value.absent(),
|
Value<DownloadState> downloadState = const Value.absent(),
|
||||||
Value<bool> acknowledgeByServer = const Value.absent(),
|
Value<bool> acknowledgeByServer = const Value.absent(),
|
||||||
|
Value<bool> errorWhileSending = const Value.absent(),
|
||||||
Value<MessageKind> kind = const Value.absent(),
|
Value<MessageKind> kind = const Value.absent(),
|
||||||
Value<String?> contentJson = const Value.absent(),
|
Value<String?> contentJson = const Value.absent(),
|
||||||
Value<DateTime?> openedAt = const Value.absent(),
|
Value<DateTime?> openedAt = const Value.absent(),
|
||||||
|
|
@ -3268,6 +3326,7 @@ class $$MessagesTableTableManager extends RootTableManager<
|
||||||
acknowledgeByUser: acknowledgeByUser,
|
acknowledgeByUser: acknowledgeByUser,
|
||||||
downloadState: downloadState,
|
downloadState: downloadState,
|
||||||
acknowledgeByServer: acknowledgeByServer,
|
acknowledgeByServer: acknowledgeByServer,
|
||||||
|
errorWhileSending: errorWhileSending,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
contentJson: contentJson,
|
contentJson: contentJson,
|
||||||
openedAt: openedAt,
|
openedAt: openedAt,
|
||||||
|
|
@ -3283,6 +3342,7 @@ class $$MessagesTableTableManager extends RootTableManager<
|
||||||
Value<bool> acknowledgeByUser = const Value.absent(),
|
Value<bool> acknowledgeByUser = const Value.absent(),
|
||||||
Value<DownloadState> downloadState = const Value.absent(),
|
Value<DownloadState> downloadState = const Value.absent(),
|
||||||
Value<bool> acknowledgeByServer = const Value.absent(),
|
Value<bool> acknowledgeByServer = const Value.absent(),
|
||||||
|
Value<bool> errorWhileSending = const Value.absent(),
|
||||||
required MessageKind kind,
|
required MessageKind kind,
|
||||||
Value<String?> contentJson = const Value.absent(),
|
Value<String?> contentJson = const Value.absent(),
|
||||||
Value<DateTime?> openedAt = const Value.absent(),
|
Value<DateTime?> openedAt = const Value.absent(),
|
||||||
|
|
@ -3298,6 +3358,7 @@ class $$MessagesTableTableManager extends RootTableManager<
|
||||||
acknowledgeByUser: acknowledgeByUser,
|
acknowledgeByUser: acknowledgeByUser,
|
||||||
downloadState: downloadState,
|
downloadState: downloadState,
|
||||||
acknowledgeByServer: acknowledgeByServer,
|
acknowledgeByServer: acknowledgeByServer,
|
||||||
|
errorWhileSending: errorWhileSending,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
contentJson: contentJson,
|
contentJson: contentJson,
|
||||||
openedAt: openedAt,
|
openedAt: openedAt,
|
||||||
|
|
|
||||||
433
lib/src/database/twonly_database.steps.dart
Normal file
433
lib/src/database/twonly_database.steps.dart
Normal file
|
|
@ -0,0 +1,433 @@
|
||||||
|
// dart format width=80
|
||||||
|
import 'package:drift/internal/versioned_schema.dart' as i0;
|
||||||
|
import 'package:drift/drift.dart' as i1;
|
||||||
|
import 'dart:typed_data' as i2;
|
||||||
|
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
|
||||||
|
|
||||||
|
// GENERATED BY drift_dev, DO NOT MODIFY.
|
||||||
|
final class Schema2 extends i0.VersionedSchema {
|
||||||
|
Schema2({required super.database}) : super(version: 2);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
contacts,
|
||||||
|
messages,
|
||||||
|
signalIdentityKeyStores,
|
||||||
|
signalPreKeyStores,
|
||||||
|
signalSenderKeyStores,
|
||||||
|
signalSessionStores,
|
||||||
|
];
|
||||||
|
late final Shape0 contacts = Shape0(
|
||||||
|
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_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_13,
|
||||||
|
_column_14,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null);
|
||||||
|
late final Shape1 messages = Shape1(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'messages',
|
||||||
|
withoutRowId: false,
|
||||||
|
isStrict: false,
|
||||||
|
tableConstraints: [],
|
||||||
|
columns: [
|
||||||
|
_column_17,
|
||||||
|
_column_18,
|
||||||
|
_column_19,
|
||||||
|
_column_20,
|
||||||
|
_column_21,
|
||||||
|
_column_22,
|
||||||
|
_column_23,
|
||||||
|
_column_24,
|
||||||
|
_column_25,
|
||||||
|
_column_26,
|
||||||
|
_column_27,
|
||||||
|
_column_28,
|
||||||
|
_column_29,
|
||||||
|
_column_30,
|
||||||
|
],
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape0 extends i0.VersionedTable {
|
||||||
|
Shape0({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<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 lastMessageExchange =>
|
||||||
|
columnsByName['last_message_exchange']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<int> get flameCounter =>
|
||||||
|
columnsByName['flame_counter']! as i1.GeneratedColumn<int>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_0(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('user_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<String> _column_1(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('username', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways('UNIQUE'));
|
||||||
|
i1.GeneratedColumn<String> _column_2(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('display_name', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_3(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('nick_name', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_4(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('avatar_svg', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<int> _column_5(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('my_avatar_counter', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int, defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<bool> _column_6(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('accepted', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("accepted" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<bool> _column_7(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('requested', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("requested" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<bool> _column_8(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('blocked', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("blocked" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<bool> _column_9(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('verified', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("verified" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<DateTime> _column_10(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('created_at', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.dateTime,
|
||||||
|
defaultValue: const CustomExpression(
|
||||||
|
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
|
||||||
|
i1.GeneratedColumn<int> _column_11(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('total_media_counter', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int, defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<DateTime> _column_12(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('last_message_send', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_13(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('last_message_received', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_14(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('last_flame_counter_change', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_15(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('last_message_exchange', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.dateTime,
|
||||||
|
defaultValue: const CustomExpression(
|
||||||
|
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
|
||||||
|
i1.GeneratedColumn<int> _column_16(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('flame_counter', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int, defaultValue: const CustomExpression('0'));
|
||||||
|
|
||||||
|
class Shape1 extends i0.VersionedTable {
|
||||||
|
Shape1({required super.source, required super.alias}) : super.aliased();
|
||||||
|
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<int> get messageOtherId =>
|
||||||
|
columnsByName['message_other_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get responseToMessageId =>
|
||||||
|
columnsByName['response_to_message_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get responseToOtherMessageId =>
|
||||||
|
columnsByName['response_to_other_message_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<bool> get acknowledgeByUser =>
|
||||||
|
columnsByName['acknowledge_by_user']! as i1.GeneratedColumn<bool>;
|
||||||
|
i1.GeneratedColumn<int> get downloadState =>
|
||||||
|
columnsByName['download_state']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<bool> get acknowledgeByServer =>
|
||||||
|
columnsByName['acknowledge_by_server']! as i1.GeneratedColumn<bool>;
|
||||||
|
i1.GeneratedColumn<bool> get errorWhileSending =>
|
||||||
|
columnsByName['error_while_sending']! as i1.GeneratedColumn<bool>;
|
||||||
|
i1.GeneratedColumn<String> get kind =>
|
||||||
|
columnsByName['kind']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get contentJson =>
|
||||||
|
columnsByName['content_json']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get openedAt =>
|
||||||
|
columnsByName['opened_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<DateTime> get sendAt =>
|
||||||
|
columnsByName['send_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<DateTime> get updatedAt =>
|
||||||
|
columnsByName['updated_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_17(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('contact_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'REFERENCES contacts (user_id)'));
|
||||||
|
i1.GeneratedColumn<int> _column_18(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('message_id', aliasedName, false,
|
||||||
|
hasAutoIncrement: true,
|
||||||
|
type: i1.DriftSqlType.int,
|
||||||
|
defaultConstraints:
|
||||||
|
i1.GeneratedColumn.constraintIsAlways('PRIMARY KEY AUTOINCREMENT'));
|
||||||
|
i1.GeneratedColumn<int> _column_19(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('message_other_id', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<int> _column_20(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('response_to_message_id', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<int> _column_21(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('response_to_other_message_id', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<bool> _column_22(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('acknowledge_by_user', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("acknowledge_by_user" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<int> _column_23(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('download_state', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int, defaultValue: const CustomExpression('2'));
|
||||||
|
i1.GeneratedColumn<bool> _column_24(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('acknowledge_by_server', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("acknowledge_by_server" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<bool> _column_25(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>('error_while_sending', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("error_while_sending" IN (0, 1))'),
|
||||||
|
defaultValue: const CustomExpression('0'));
|
||||||
|
i1.GeneratedColumn<String> _column_26(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('kind', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<String> _column_27(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('content_json', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_28(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('opened_at', aliasedName, true,
|
||||||
|
type: i1.DriftSqlType.dateTime);
|
||||||
|
i1.GeneratedColumn<DateTime> _column_29(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('send_at', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.dateTime,
|
||||||
|
defaultValue: const CustomExpression(
|
||||||
|
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
|
||||||
|
i1.GeneratedColumn<DateTime> _column_30(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<DateTime>('updated_at', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.dateTime,
|
||||||
|
defaultValue: const CustomExpression(
|
||||||
|
'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)'));
|
||||||
|
|
||||||
|
class Shape2 extends i0.VersionedTable {
|
||||||
|
Shape2({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get deviceId =>
|
||||||
|
columnsByName['device_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get name =>
|
||||||
|
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get identityKey =>
|
||||||
|
columnsByName['identity_key']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_31(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('device_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<String> _column_32(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('name', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> _column_33(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<i2.Uint8List>('identity_key', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.blob);
|
||||||
|
|
||||||
|
class Shape3 extends i0.VersionedTable {
|
||||||
|
Shape3({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get preKeyId =>
|
||||||
|
columnsByName['pre_key_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get preKey =>
|
||||||
|
columnsByName['pre_key']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<int> _column_34(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<int>('pre_key_id', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.int);
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> _column_35(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<i2.Uint8List>('pre_key', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.blob);
|
||||||
|
|
||||||
|
class Shape4 extends i0.VersionedTable {
|
||||||
|
Shape4({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<String> get senderKeyName =>
|
||||||
|
columnsByName['sender_key_name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get senderKey =>
|
||||||
|
columnsByName['sender_key']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<String> _column_36(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<String>('sender_key_name', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.string);
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> _column_37(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<i2.Uint8List>('sender_key', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.blob);
|
||||||
|
|
||||||
|
class Shape5 extends i0.VersionedTable {
|
||||||
|
Shape5({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<int> get deviceId =>
|
||||||
|
columnsByName['device_id']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get name =>
|
||||||
|
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> get sessionRecord =>
|
||||||
|
columnsByName['session_record']! as i1.GeneratedColumn<i2.Uint8List>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<i2.Uint8List> _column_38(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<i2.Uint8List>('session_record', aliasedName, false,
|
||||||
|
type: i1.DriftSqlType.blob);
|
||||||
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
|
}) {
|
||||||
|
return (currentVersion, database) async {
|
||||||
|
switch (currentVersion) {
|
||||||
|
case 1:
|
||||||
|
final schema = Schema2(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from1To2(migrator, schema);
|
||||||
|
return 2;
|
||||||
|
default:
|
||||||
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.OnUpgrade stepByStep({
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
|
}) =>
|
||||||
|
i0.VersionedSchema.stepByStepHelper(
|
||||||
|
step: migrationSteps(
|
||||||
|
from1To2: from1To2,
|
||||||
|
));
|
||||||
|
|
@ -1,16 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
enum MessageKind {
|
|
||||||
textMessage,
|
|
||||||
storedMediaFile,
|
|
||||||
media,
|
|
||||||
contactRequest,
|
|
||||||
profileChange,
|
|
||||||
rejectRequest,
|
|
||||||
acceptRequest,
|
|
||||||
opened,
|
|
||||||
ack
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Color> messageKindColors = {
|
Map<String, Color> messageKindColors = {
|
||||||
"video": Colors.deepPurple,
|
"video": Colors.deepPurple,
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
"messageSendState_Sending": "Wird gesendet",
|
"messageSendState_Sending": "Wird gesendet",
|
||||||
"messageSendState_TapToLoad": "Tippe zum Laden",
|
"messageSendState_TapToLoad": "Tippe zum Laden",
|
||||||
"messageSendState_Loading": "Herunterladen",
|
"messageSendState_Loading": "Herunterladen",
|
||||||
|
"messageStoredInGalery": "In Gallerie gespeichert",
|
||||||
"imageEditorDrawOk": "Zeichnung machen",
|
"imageEditorDrawOk": "Zeichnung machen",
|
||||||
"settingsTitle": "Einstellungen",
|
"settingsTitle": "Einstellungen",
|
||||||
"settingsProfile": "Profil",
|
"settingsProfile": "Profil",
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
"messageSendState_Sending": "Sending",
|
"messageSendState_Sending": "Sending",
|
||||||
"messageSendState_TapToLoad": "Tap to load",
|
"messageSendState_TapToLoad": "Tap to load",
|
||||||
"messageSendState_Loading": "Downloading",
|
"messageSendState_Loading": "Downloading",
|
||||||
|
"messageStoredInGalery": "Stored in gallery",
|
||||||
"imageEditorDrawOk": "Take drawing",
|
"imageEditorDrawOk": "Take drawing",
|
||||||
"settingsTitle": "Settings",
|
"settingsTitle": "Settings",
|
||||||
"settingsProfile": "Profile",
|
"settingsProfile": "Profile",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
@ -15,32 +16,75 @@ import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
|
||||||
Future tryTransmitMessages() async {
|
Future tryTransmitMessages() async {
|
||||||
List<Message> retransmit =
|
Map<String, dynamic> retransmit = await getAllMessagesForRetransmitting();
|
||||||
await twonlyDatabase.messagesDao.getAllMessagesForRetransmitting();
|
|
||||||
|
|
||||||
if (retransmit.isEmpty) return;
|
if (retransmit.isEmpty) return;
|
||||||
|
|
||||||
Logger("api.dart").info("try sending messages: ${retransmit.length}");
|
Logger("api.dart").info("try sending messages: ${retransmit.length}");
|
||||||
|
|
||||||
Box box = await getMediaStorage();
|
Map<String, dynamic> failed = {};
|
||||||
for (int i = 0; i < retransmit.length; i++) {
|
|
||||||
int msgId = retransmit[i].messageId;
|
|
||||||
|
|
||||||
Uint8List? bytes = box.get("retransmit-$msgId-textmessage");
|
for (String key in retransmit.keys) {
|
||||||
if (bytes != null) {
|
RetransmitMessage msg =
|
||||||
Result resp = await apiProvider.sendTextMessage(
|
RetransmitMessage.fromJson(jsonDecode(retransmit[key]));
|
||||||
retransmit[i].contactId,
|
|
||||||
bytes,
|
Result resp = await apiProvider.sendTextMessage(
|
||||||
);
|
msg.userId,
|
||||||
if (resp.isSuccess) {
|
msg.bytes,
|
||||||
|
);
|
||||||
|
if (resp.isSuccess) {
|
||||||
|
if (msg.messageId != null) {
|
||||||
await twonlyDatabase.messagesDao.updateMessageByMessageId(
|
await twonlyDatabase.messagesDao.updateMessageByMessageId(
|
||||||
msgId, MessagesCompanion(acknowledgeByServer: Value(true)));
|
msg.messageId!,
|
||||||
box.delete("retransmit-$msgId-textmessage");
|
MessagesCompanion(
|
||||||
} else {
|
acknowledgeByServer: Value(true),
|
||||||
// in case of error do nothing. As the message is not removed the app will try again when relaunched
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
failed[key] = retransmit[key];
|
||||||
|
} else {
|
||||||
|
// in case of error do nothing. As the message is not removed the app will try again when relaunched
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Box box = await getMediaStorage();
|
||||||
|
box.put("messages-to-retransmit", jsonEncode(failed));
|
||||||
|
}
|
||||||
|
|
||||||
|
class RetransmitMessage {
|
||||||
|
int? messageId;
|
||||||
|
int userId;
|
||||||
|
Uint8List bytes;
|
||||||
|
RetransmitMessage(
|
||||||
|
{this.messageId, required this.userId, required this.bytes});
|
||||||
|
|
||||||
|
// From JSON constructor
|
||||||
|
factory RetransmitMessage.fromJson(Map<String, dynamic> json) {
|
||||||
|
return RetransmitMessage(
|
||||||
|
messageId: json['messageId'],
|
||||||
|
userId: json['userId'],
|
||||||
|
bytes: base64Decode(json['bytes']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To JSON method
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'messageId': messageId,
|
||||||
|
'userId': userId,
|
||||||
|
'bytes': base64Encode(bytes),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> getAllMessagesForRetransmitting() async {
|
||||||
|
Box box = await getMediaStorage();
|
||||||
|
String? retransmitJson = box.get("messages-to-retransmit");
|
||||||
|
Map<String, dynamic> retransmit = {};
|
||||||
|
|
||||||
|
if (retransmitJson != null) {
|
||||||
|
retransmit = jsonDecode(retransmitJson);
|
||||||
|
}
|
||||||
|
return retransmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this functions ensures that the message is received by the server and in case of errors will try again later
|
// this functions ensures that the message is received by the server and in case of errors will try again later
|
||||||
|
|
@ -53,9 +97,19 @@ Future<Result> encryptAndSendMessage(
|
||||||
return Result.error(ErrorCode.InternalError);
|
return Result.error(ErrorCode.InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String stateId = (messageId ?? (60001 + Random().nextInt(100000))).toString();
|
||||||
Box box = await getMediaStorage();
|
Box box = await getMediaStorage();
|
||||||
if (messageId != null) {
|
|
||||||
box.put("retransmit-$messageId-textmessage", bytes);
|
{
|
||||||
|
var retransmit = await getAllMessagesForRetransmitting();
|
||||||
|
|
||||||
|
retransmit[stateId] = jsonEncode(RetransmitMessage(
|
||||||
|
messageId: messageId,
|
||||||
|
userId: userId,
|
||||||
|
bytes: bytes,
|
||||||
|
).toJson());
|
||||||
|
|
||||||
|
box.put("messages-to-retransmit", jsonEncode(retransmit));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result resp = await apiProvider.sendTextMessage(userId, bytes);
|
Result resp = await apiProvider.sendTextMessage(userId, bytes);
|
||||||
|
|
@ -66,6 +120,13 @@ Future<Result> encryptAndSendMessage(
|
||||||
messageId,
|
messageId,
|
||||||
MessagesCompanion(acknowledgeByServer: Value(true)),
|
MessagesCompanion(acknowledgeByServer: Value(true)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
var retransmit = await getAllMessagesForRetransmitting();
|
||||||
|
retransmit.remove(stateId);
|
||||||
|
box.put("messages-to-retransmit", jsonEncode(retransmit));
|
||||||
|
}
|
||||||
|
|
||||||
box.delete("retransmit-$messageId-textmessage");
|
box.delete("retransmit-$messageId-textmessage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ Future sendImage(
|
||||||
Map<String, dynamic> allMediaFiles = {};
|
Map<String, dynamic> allMediaFiles = {};
|
||||||
|
|
||||||
if (mediaFilesJson != null) {
|
if (mediaFilesJson != null) {
|
||||||
// allMediaFiles = jsonDecode(mediaFilesJson);
|
allMediaFiles = jsonDecode(mediaFilesJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
allMediaFiles[stateId] = jsonEncode(states.toJson());
|
allMediaFiles[stateId] = jsonEncode(states.toJson());
|
||||||
|
|
@ -361,26 +361,42 @@ Future retransmitMediaFiles() async {
|
||||||
|
|
||||||
Map<String, dynamic> allMediaFiles = jsonDecode(mediaFilesJson);
|
Map<String, dynamic> allMediaFiles = jsonDecode(mediaFilesJson);
|
||||||
|
|
||||||
|
bool allSuccess = true;
|
||||||
|
|
||||||
for (final entry in allMediaFiles.entries) {
|
for (final entry in allMediaFiles.entries) {
|
||||||
try {
|
try {
|
||||||
String stateId = entry.key;
|
String stateId = entry.key;
|
||||||
States states = States.fromJson(jsonDecode(entry.value));
|
States states = States.fromJson(jsonDecode(entry.value));
|
||||||
// upload one by one
|
// upload one by one
|
||||||
await uploadMediaState(stateId, states.prepareState, states.metadata);
|
allSuccess = allSuccess &
|
||||||
|
await uploadMediaState(stateId, states.prepareState, states.metadata);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger("media.dart").shout(e);
|
Logger("media.dart").shout(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allSuccess) {
|
||||||
|
// when all retransmittions where sucessfull tag the errors
|
||||||
|
final pendings = await twonlyDatabase.messagesDao
|
||||||
|
.getAllMessagesPendingUploadOlderThanAMinute();
|
||||||
|
for (final pending in pendings) {
|
||||||
|
twonlyDatabase.messagesDao.updateMessageByMessageId(
|
||||||
|
pending.messageId,
|
||||||
|
MessagesCompanion(errorWhileSending: Value(true)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// return allSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the upload failes this function is called again from the retransmitMediaFiles function which is
|
// if the upload failes this function is called again from the retransmitMediaFiles function which is
|
||||||
// called when the WebSocket is reconnected again.
|
// called when the WebSocket is reconnected again.
|
||||||
Future uploadMediaState(
|
Future<bool> uploadMediaState(
|
||||||
String stateId, PrepareState prepareState, Metadata metadata) async {
|
String stateId, PrepareState prepareState, Metadata metadata) async {
|
||||||
final uploadState =
|
final uploadState =
|
||||||
await ImageUploader.uploadState(prepareState, metadata.userIds.length);
|
await ImageUploader.uploadState(prepareState, metadata.userIds.length);
|
||||||
if (uploadState == null) {
|
if (uploadState == null) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -395,11 +411,8 @@ Future uploadMediaState(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final notifyState =
|
await ImageUploader.notifyState(prepareState, uploadState, metadata);
|
||||||
await ImageUploader.notifyState(prepareState, uploadState, metadata);
|
return true;
|
||||||
if (notifyState == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future tryDownloadMedia(
|
Future tryDownloadMedia(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:twonly/src/services/notification_service.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
Future initMediaStorage() async {
|
Future initMediaStorage() async {
|
||||||
|
|
@ -19,14 +21,21 @@ Future initMediaStorage() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box> getMediaStorage() async {
|
Future<Box> getMediaStorage() async {
|
||||||
final storage = getSecureStorage();
|
try {
|
||||||
await initMediaStorage();
|
await initMediaStorage();
|
||||||
|
final storage = getSecureStorage();
|
||||||
|
|
||||||
var encryptionKey =
|
var encryptionKey =
|
||||||
base64Url.decode((await storage.read(key: 'hive_encryption_key'))!);
|
base64Url.decode((await storage.read(key: 'hive_encryption_key'))!);
|
||||||
|
|
||||||
return await Hive.openBox(
|
return await Hive.openBox(
|
||||||
'media_storage',
|
'media_storage',
|
||||||
encryptionCipher: HiveAesCipher(encryptionKey),
|
encryptionCipher: HiveAesCipher(encryptionKey),
|
||||||
);
|
);
|
||||||
|
} catch (e) {
|
||||||
|
await customLocalPushNotification("Secure Storage Error",
|
||||||
|
"Settings > Apps > twonly > Storage and Cache > Press clear on both");
|
||||||
|
Logger("hive.dart").shout(e);
|
||||||
|
throw Exception(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart' as my;
|
import 'package:twonly/src/json_models/message.dart' as my;
|
||||||
|
|
||||||
|
|
@ -151,16 +152,16 @@ Future localPushNotificationNewMessage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.kind == my.MessageKind.contactRequest) {
|
if (message.kind == MessageKind.contactRequest) {
|
||||||
msg =
|
msg =
|
||||||
getPushNotificationText("contactRequest", getContactDisplayName(user));
|
getPushNotificationText("contactRequest", getContactDisplayName(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.kind == my.MessageKind.acceptRequest) {
|
if (message.kind == MessageKind.acceptRequest) {
|
||||||
msg = getPushNotificationText("acceptRequest", getContactDisplayName(user));
|
msg = getPushNotificationText("acceptRequest", getContactDisplayName(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.kind == my.MessageKind.storedMediaFile) {
|
if (message.kind == MessageKind.storedMediaFile) {
|
||||||
msg =
|
msg =
|
||||||
getPushNotificationText("storedMediaFile", getContactDisplayName(user));
|
getPushNotificationText("storedMediaFile", getContactDisplayName(user));
|
||||||
}
|
}
|
||||||
|
|
@ -193,3 +194,26 @@ Future localPushNotificationNewMessage(
|
||||||
payload: message.kind.index.toString(),
|
payload: message.kind.index.toString(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future customLocalPushNotification(String title, String msg) async {
|
||||||
|
const AndroidNotificationDetails androidNotificationDetails =
|
||||||
|
AndroidNotificationDetails(
|
||||||
|
'1',
|
||||||
|
'Error',
|
||||||
|
channelDescription: 'Error messages.',
|
||||||
|
importance: Importance.max,
|
||||||
|
priority: Priority.max,
|
||||||
|
);
|
||||||
|
|
||||||
|
const DarwinNotificationDetails darwinNotificationDetails =
|
||||||
|
DarwinNotificationDetails();
|
||||||
|
const NotificationDetails notificationDetails = NotificationDetails(
|
||||||
|
android: androidNotificationDetails, iOS: darwinNotificationDetails);
|
||||||
|
|
||||||
|
await flutterLocalNotificationsPlugin.show(
|
||||||
|
897898,
|
||||||
|
title,
|
||||||
|
msg,
|
||||||
|
notificationDetails,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/components/image_editor/action_button.dart';
|
import 'package:twonly/src/components/image_editor/action_button.dart';
|
||||||
import 'package:twonly/src/components/media_view_sizing.dart';
|
import 'package:twonly/src/components/media_view_sizing.dart';
|
||||||
import 'package:twonly/src/components/notification_badge.dart';
|
import 'package:twonly/src/components/notification_badge.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/providers/api/media.dart';
|
import 'package:twonly/src/providers/api/media.dart';
|
||||||
import 'package:twonly/src/providers/send_next_media_to.dart';
|
import 'package:twonly/src/providers/send_next_media_to.dart';
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import 'package:twonly/src/components/flame.dart';
|
||||||
import 'package:twonly/src/components/headline.dart';
|
import 'package:twonly/src/components/headline.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/components/verified_shield.dart';
|
import 'package:twonly/src/components/verified_shield.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/providers/api/media.dart';
|
import 'package:twonly/src/providers/api/media.dart';
|
||||||
import 'package:twonly/src/providers/send_next_media_to.dart';
|
import 'package:twonly/src/providers/send_next_media_to.dart';
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import 'package:twonly/src/components/better_text.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/components/message_send_state_icon.dart';
|
import 'package:twonly/src/components/message_send_state_icon.dart';
|
||||||
import 'package:twonly/src/components/verified_shield.dart';
|
import 'package:twonly/src/components/verified_shield.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
import 'package:twonly/src/json_models/message.dart';
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/components/message_send_state_icon.dart';
|
import 'package:twonly/src/components/message_send_state_icon.dart';
|
||||||
import 'package:twonly/src/components/notification_badge.dart';
|
import 'package:twonly/src/components/notification_badge.dart';
|
||||||
import 'package:twonly/src/components/user_context_menu.dart';
|
import 'package:twonly/src/components/user_context_menu.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
import 'package:twonly/src/json_models/message.dart';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ import 'dart:async';
|
||||||
import 'package:drift/drift.dart' hide Column;
|
import 'package:drift/drift.dart' hide Column;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/src/components/alert_dialog.dart';
|
import 'package:twonly/src/components/alert_dialog.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/components/format_long_string.dart';
|
import 'package:twonly/src/components/format_long_string.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/signal.dart';
|
import 'package:twonly/src/utils/signal.dart';
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import 'package:twonly/src/components/flame.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/components/verified_shield.dart';
|
import 'package:twonly/src/components/verified_shield.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/views/contact/contact_verify_view.dart';
|
import 'package:twonly/src/views/contact/contact_verify_view.dart';
|
||||||
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
|
|
||||||
class ContactView extends StatefulWidget {
|
class ContactView extends StatefulWidget {
|
||||||
const ContactView(this.userId, {super.key});
|
const ContactView(this.userId, {super.key});
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import 'package:drift/drift.dart' hide Column;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/database/tables/contacts_table.dart';
|
import 'package:twonly/src/database/daos/contacts_dao.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
|
|
|
||||||
23
test/drift/twonly_database/generated/schema.dart
Normal file
23
test/drift/twonly_database/generated/schema.dart
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// dart format width=80
|
||||||
|
// GENERATED CODE, DO NOT EDIT BY HAND.
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift/internal/migrations.dart';
|
||||||
|
import 'schema_v1.dart' as v1;
|
||||||
|
import 'schema_v2.dart' as v2;
|
||||||
|
|
||||||
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
|
@override
|
||||||
|
GeneratedDatabase databaseForVersion(QueryExecutor db, int version) {
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
return v1.DatabaseAtV1(db);
|
||||||
|
case 2:
|
||||||
|
return v2.DatabaseAtV2(db);
|
||||||
|
default:
|
||||||
|
throw MissingSchemaException(version, versions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const versions = const [1, 2];
|
||||||
|
}
|
||||||
2122
test/drift/twonly_database/generated/schema_v1.dart
Normal file
2122
test/drift/twonly_database/generated/schema_v1.dart
Normal file
File diff suppressed because it is too large
Load diff
2157
test/drift/twonly_database/generated/schema_v2.dart
Normal file
2157
test/drift/twonly_database/generated/schema_v2.dart
Normal file
File diff suppressed because it is too large
Load diff
103
test/drift/twonly_database/migration_test.dart
Normal file
103
test/drift/twonly_database/migration_test.dart
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
// dart format width=80
|
||||||
|
// ignore_for_file: unused_local_variable, unused_import
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift_dev/api/migrations_native.dart';
|
||||||
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'generated/schema.dart';
|
||||||
|
|
||||||
|
import 'generated/schema_v1.dart' as v1;
|
||||||
|
import 'generated/schema_v2.dart' as v2;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
|
||||||
|
late SchemaVerifier verifier;
|
||||||
|
|
||||||
|
setUpAll(() {
|
||||||
|
verifier = SchemaVerifier(GeneratedHelper());
|
||||||
|
});
|
||||||
|
|
||||||
|
group('simple database migrations', () {
|
||||||
|
// These simple tests verify all possible schema updates with a simple (no
|
||||||
|
// data) migration. This is a quick way to ensure that written database
|
||||||
|
// migrations properly alter the schema.
|
||||||
|
const versions = GeneratedHelper.versions;
|
||||||
|
for (final (i, fromVersion) in versions.indexed) {
|
||||||
|
group('from $fromVersion', () {
|
||||||
|
for (final toVersion in versions.skip(i + 1)) {
|
||||||
|
test('to $toVersion', () async {
|
||||||
|
final schema = await verifier.schemaAt(fromVersion);
|
||||||
|
final db = TwonlyDatabase(schema.newConnection());
|
||||||
|
await verifier.migrateAndValidate(db, toVersion);
|
||||||
|
await db.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The following template shows how to write tests ensuring your migrations
|
||||||
|
// preserve existing data.
|
||||||
|
// Testing this can be useful for migrations that change existing columns
|
||||||
|
// (e.g. by alterating their type or constraints). Migrations that only add
|
||||||
|
// tables or columns typically don't need these advanced tests. For more
|
||||||
|
// information, see https://drift.simonbinder.eu/migrations/tests/#verifying-data-integrity
|
||||||
|
// TODO: This generated template shows how these tests could be written. Adopt
|
||||||
|
// it to your own needs when testing migrations with data integrity.
|
||||||
|
test('migration from v1 to v2 does not corrupt data', () async {
|
||||||
|
// Add data to insert into the old database, and the expected rows after the
|
||||||
|
// migration.
|
||||||
|
// TODO: Fill these lists
|
||||||
|
final oldContactsData = <v1.ContactsData>[];
|
||||||
|
final expectedNewContactsData = <v2.ContactsData>[];
|
||||||
|
|
||||||
|
final oldMessagesData = <v1.MessagesData>[];
|
||||||
|
final expectedNewMessagesData = <v2.MessagesData>[];
|
||||||
|
|
||||||
|
final oldSignalIdentityKeyStoresData = <v1.SignalIdentityKeyStoresData>[];
|
||||||
|
final expectedNewSignalIdentityKeyStoresData =
|
||||||
|
<v2.SignalIdentityKeyStoresData>[];
|
||||||
|
|
||||||
|
final oldSignalPreKeyStoresData = <v1.SignalPreKeyStoresData>[];
|
||||||
|
final expectedNewSignalPreKeyStoresData = <v2.SignalPreKeyStoresData>[];
|
||||||
|
|
||||||
|
final oldSignalSenderKeyStoresData = <v1.SignalSenderKeyStoresData>[];
|
||||||
|
final expectedNewSignalSenderKeyStoresData =
|
||||||
|
<v2.SignalSenderKeyStoresData>[];
|
||||||
|
|
||||||
|
final oldSignalSessionStoresData = <v1.SignalSessionStoresData>[];
|
||||||
|
final expectedNewSignalSessionStoresData = <v2.SignalSessionStoresData>[];
|
||||||
|
|
||||||
|
await verifier.testWithDataIntegrity(
|
||||||
|
oldVersion: 1,
|
||||||
|
newVersion: 2,
|
||||||
|
createOld: v1.DatabaseAtV1.new,
|
||||||
|
createNew: v2.DatabaseAtV2.new,
|
||||||
|
openTestedDatabase: TwonlyDatabase.new,
|
||||||
|
createItems: (batch, oldDb) {
|
||||||
|
batch.insertAll(oldDb.contacts, oldContactsData);
|
||||||
|
batch.insertAll(oldDb.messages, oldMessagesData);
|
||||||
|
batch.insertAll(
|
||||||
|
oldDb.signalIdentityKeyStores, oldSignalIdentityKeyStoresData);
|
||||||
|
batch.insertAll(oldDb.signalPreKeyStores, oldSignalPreKeyStoresData);
|
||||||
|
batch.insertAll(
|
||||||
|
oldDb.signalSenderKeyStores, oldSignalSenderKeyStoresData);
|
||||||
|
batch.insertAll(oldDb.signalSessionStores, oldSignalSessionStoresData);
|
||||||
|
},
|
||||||
|
validateItems: (newDb) async {
|
||||||
|
expect(
|
||||||
|
expectedNewContactsData, await newDb.select(newDb.contacts).get());
|
||||||
|
expect(
|
||||||
|
expectedNewMessagesData, await newDb.select(newDb.messages).get());
|
||||||
|
expect(expectedNewSignalIdentityKeyStoresData,
|
||||||
|
await newDb.select(newDb.signalIdentityKeyStores).get());
|
||||||
|
expect(expectedNewSignalPreKeyStoresData,
|
||||||
|
await newDb.select(newDb.signalPreKeyStores).get());
|
||||||
|
expect(expectedNewSignalSenderKeyStoresData,
|
||||||
|
await newDb.select(newDb.signalSenderKeyStores).get());
|
||||||
|
expect(expectedNewSignalSessionStoresData,
|
||||||
|
await newDb.select(newDb.signalSessionStores).get());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue