✨ Basic messages & loading
This commit is contained in:
parent
63ec82891f
commit
b2c31bcf13
@ -75,5 +75,6 @@
|
|||||||
"editChatRoom": "Edit a Room",
|
"editChatRoom": "Edit a Room",
|
||||||
"chat": "Chat",
|
"chat": "Chat",
|
||||||
"chatMessageHint": "Message in {}",
|
"chatMessageHint": "Message in {}",
|
||||||
"chatDirectMessageHint": "Message to {}"
|
"chatDirectMessageHint": "Message to {}",
|
||||||
|
"loading": "Loading..."
|
||||||
}
|
}
|
||||||
|
@ -142,6 +142,28 @@ PODS:
|
|||||||
- sqflite_darwin (0.0.4):
|
- sqflite_darwin (0.0.4):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- sqlite3 (3.49.1):
|
||||||
|
- sqlite3/common (= 3.49.1)
|
||||||
|
- sqlite3/common (3.49.1)
|
||||||
|
- sqlite3/dbstatvtab (3.49.1):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/fts5 (3.49.1):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/math (3.49.1):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/perf-threadsafe (3.49.1):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3/rtree (3.49.1):
|
||||||
|
- sqlite3/common
|
||||||
|
- sqlite3_flutter_libs (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
|
- sqlite3 (~> 3.49.1)
|
||||||
|
- sqlite3/dbstatvtab
|
||||||
|
- sqlite3/fts5
|
||||||
|
- sqlite3/math
|
||||||
|
- sqlite3/perf-threadsafe
|
||||||
|
- sqlite3/rtree
|
||||||
- super_native_extensions (0.0.1):
|
- super_native_extensions (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- SwiftyGif (5.4.5)
|
- SwiftyGif (5.4.5)
|
||||||
@ -172,6 +194,7 @@ DEPENDENCIES:
|
|||||||
- quill_native_bridge_ios (from `.symlinks/plugins/quill_native_bridge_ios/ios`)
|
- quill_native_bridge_ios (from `.symlinks/plugins/quill_native_bridge_ios/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
|
||||||
|
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/darwin`)
|
||||||
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
|
- super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||||
@ -194,6 +217,7 @@ SPEC REPOS:
|
|||||||
- PromisesObjC
|
- PromisesObjC
|
||||||
- SAMKeychain
|
- SAMKeychain
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
|
- sqlite3
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@ -233,6 +257,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
sqflite_darwin:
|
sqflite_darwin:
|
||||||
:path: ".symlinks/plugins/sqflite_darwin/darwin"
|
:path: ".symlinks/plugins/sqflite_darwin/darwin"
|
||||||
|
sqlite3_flutter_libs:
|
||||||
|
:path: ".symlinks/plugins/sqlite3_flutter_libs/darwin"
|
||||||
super_native_extensions:
|
super_native_extensions:
|
||||||
:path: ".symlinks/plugins/super_native_extensions/ios"
|
:path: ".symlinks/plugins/super_native_extensions/ios"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
@ -276,6 +302,8 @@ SPEC CHECKSUMS:
|
|||||||
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
|
SDWebImage: f84b0feeb08d2d11e6a9b843cb06d75ebf5b8868
|
||||||
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
|
||||||
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
|
||||||
|
sqlite3: fc1400008a9b3525f5914ed715a5d1af0b8f4983
|
||||||
|
sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2
|
||||||
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
|
super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4
|
||||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||||
|
81
lib/database/drift_db.dart
Normal file
81
lib/database/drift_db.dart
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift/native.dart';
|
||||||
|
import 'package:island/database/message.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
|
part 'drift_db.g.dart';
|
||||||
|
|
||||||
|
// Define the database
|
||||||
|
@DriftDatabase(tables: [ChatMessages])
|
||||||
|
class AppDatabase extends _$AppDatabase {
|
||||||
|
AppDatabase() : super(_openConnection());
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get schemaVersion => 1;
|
||||||
|
|
||||||
|
// Methods for chat messages
|
||||||
|
Future<List<ChatMessage>> getMessagesForRoom(
|
||||||
|
int roomId, {
|
||||||
|
int offset = 0,
|
||||||
|
int limit = 20,
|
||||||
|
}) {
|
||||||
|
return (select(chatMessages)
|
||||||
|
..where((m) => m.roomId.equals(roomId))
|
||||||
|
..orderBy([(m) => OrderingTerm.desc(m.createdAt)])
|
||||||
|
..limit(limit, offset: offset))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> saveMessage(ChatMessagesCompanion message) {
|
||||||
|
return into(chatMessages).insert(message, mode: InsertMode.insertOrReplace);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> updateMessageStatus(String id, MessageStatus status) {
|
||||||
|
return (update(chatMessages)..where(
|
||||||
|
(m) => m.id.equals(id),
|
||||||
|
)).write(ChatMessagesCompanion(status: Value(status)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> deleteMessage(String id) {
|
||||||
|
return (delete(chatMessages)..where((m) => m.id.equals(id))).go();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert between Drift and model objects
|
||||||
|
ChatMessagesCompanion messageToCompanion(LocalChatMessage message) {
|
||||||
|
return ChatMessagesCompanion(
|
||||||
|
id: Value(message.id),
|
||||||
|
roomId: Value(message.roomId),
|
||||||
|
senderId: Value(message.senderId),
|
||||||
|
content: Value(message.toRemoteMessage().content),
|
||||||
|
nonce: Value(message.nonce),
|
||||||
|
data: Value(jsonEncode(message.data)),
|
||||||
|
createdAt: Value(message.createdAt),
|
||||||
|
status: Value(message.status),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalChatMessage companionToMessage(ChatMessage dbMessage) {
|
||||||
|
final data = jsonDecode(dbMessage.data);
|
||||||
|
return LocalChatMessage(
|
||||||
|
id: dbMessage.id,
|
||||||
|
roomId: dbMessage.roomId,
|
||||||
|
senderId: dbMessage.senderId,
|
||||||
|
data: data,
|
||||||
|
createdAt: dbMessage.createdAt,
|
||||||
|
status: dbMessage.status,
|
||||||
|
nonce: dbMessage.nonce,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to open the database connection
|
||||||
|
LazyDatabase _openConnection() {
|
||||||
|
return LazyDatabase(() async {
|
||||||
|
final dbFolder = await getApplicationDocumentsDirectory();
|
||||||
|
final file = File(p.join(dbFolder.path, 'island_chat.sqlite'));
|
||||||
|
return NativeDatabase(file);
|
||||||
|
});
|
||||||
|
}
|
807
lib/database/drift_db.g.dart
Normal file
807
lib/database/drift_db.g.dart
Normal file
@ -0,0 +1,807 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'drift_db.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
class $ChatMessagesTable extends ChatMessages
|
||||||
|
with TableInfo<$ChatMessagesTable, ChatMessage> {
|
||||||
|
@override
|
||||||
|
final GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$ChatMessagesTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
||||||
|
'id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _roomIdMeta = const VerificationMeta('roomId');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> roomId = GeneratedColumn<int>(
|
||||||
|
'room_id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _senderIdMeta = const VerificationMeta(
|
||||||
|
'senderId',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> senderId = GeneratedColumn<String>(
|
||||||
|
'sender_id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _contentMeta = const VerificationMeta(
|
||||||
|
'content',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> content = GeneratedColumn<String>(
|
||||||
|
'content',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _nonceMeta = const VerificationMeta('nonce');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> nonce = GeneratedColumn<String>(
|
||||||
|
'nonce',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _dataMeta = const VerificationMeta('data');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> data = GeneratedColumn<String>(
|
||||||
|
'data',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const VerificationMeta _createdAtMeta = const VerificationMeta(
|
||||||
|
'createdAt',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<DateTime> createdAt = GeneratedColumn<DateTime>(
|
||||||
|
'created_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final GeneratedColumnWithTypeConverter<MessageStatus, int> status =
|
||||||
|
GeneratedColumn<int>(
|
||||||
|
'status',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
).withConverter<MessageStatus>($ChatMessagesTable.$converterstatus);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [
|
||||||
|
id,
|
||||||
|
roomId,
|
||||||
|
senderId,
|
||||||
|
content,
|
||||||
|
nonce,
|
||||||
|
data,
|
||||||
|
createdAt,
|
||||||
|
status,
|
||||||
|
];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'chat_messages';
|
||||||
|
@override
|
||||||
|
VerificationContext validateIntegrity(
|
||||||
|
Insertable<ChatMessage> instance, {
|
||||||
|
bool isInserting = false,
|
||||||
|
}) {
|
||||||
|
final context = VerificationContext();
|
||||||
|
final data = instance.toColumns(true);
|
||||||
|
if (data.containsKey('id')) {
|
||||||
|
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_idMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('room_id')) {
|
||||||
|
context.handle(
|
||||||
|
_roomIdMeta,
|
||||||
|
roomId.isAcceptableOrUnknown(data['room_id']!, _roomIdMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_roomIdMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('sender_id')) {
|
||||||
|
context.handle(
|
||||||
|
_senderIdMeta,
|
||||||
|
senderId.isAcceptableOrUnknown(data['sender_id']!, _senderIdMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_senderIdMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('content')) {
|
||||||
|
context.handle(
|
||||||
|
_contentMeta,
|
||||||
|
content.isAcceptableOrUnknown(data['content']!, _contentMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('nonce')) {
|
||||||
|
context.handle(
|
||||||
|
_nonceMeta,
|
||||||
|
nonce.isAcceptableOrUnknown(data['nonce']!, _nonceMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('data')) {
|
||||||
|
context.handle(
|
||||||
|
_dataMeta,
|
||||||
|
this.data.isAcceptableOrUnknown(data['data']!, _dataMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_dataMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_createdAtMeta);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<GeneratedColumn> get $primaryKey => {id};
|
||||||
|
@override
|
||||||
|
ChatMessage map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return ChatMessage(
|
||||||
|
id:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}id'],
|
||||||
|
)!,
|
||||||
|
roomId:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}room_id'],
|
||||||
|
)!,
|
||||||
|
senderId:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}sender_id'],
|
||||||
|
)!,
|
||||||
|
content: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}content'],
|
||||||
|
),
|
||||||
|
nonce: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}nonce'],
|
||||||
|
),
|
||||||
|
data:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}data'],
|
||||||
|
)!,
|
||||||
|
createdAt:
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
|
status: $ChatMessagesTable.$converterstatus.fromSql(
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}status'],
|
||||||
|
)!,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$ChatMessagesTable createAlias(String alias) {
|
||||||
|
return $ChatMessagesTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JsonTypeConverter2<MessageStatus, int, int> $converterstatus =
|
||||||
|
const EnumIndexConverter<MessageStatus>(MessageStatus.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatMessage extends DataClass implements Insertable<ChatMessage> {
|
||||||
|
final String id;
|
||||||
|
final int roomId;
|
||||||
|
final String senderId;
|
||||||
|
final String? content;
|
||||||
|
final String? nonce;
|
||||||
|
final String data;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final MessageStatus status;
|
||||||
|
const ChatMessage({
|
||||||
|
required this.id,
|
||||||
|
required this.roomId,
|
||||||
|
required this.senderId,
|
||||||
|
this.content,
|
||||||
|
this.nonce,
|
||||||
|
required this.data,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.status,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
map['id'] = Variable<String>(id);
|
||||||
|
map['room_id'] = Variable<int>(roomId);
|
||||||
|
map['sender_id'] = Variable<String>(senderId);
|
||||||
|
if (!nullToAbsent || content != null) {
|
||||||
|
map['content'] = Variable<String>(content);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || nonce != null) {
|
||||||
|
map['nonce'] = Variable<String>(nonce);
|
||||||
|
}
|
||||||
|
map['data'] = Variable<String>(data);
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
|
{
|
||||||
|
map['status'] = Variable<int>(
|
||||||
|
$ChatMessagesTable.$converterstatus.toSql(status),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessagesCompanion toCompanion(bool nullToAbsent) {
|
||||||
|
return ChatMessagesCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
roomId: Value(roomId),
|
||||||
|
senderId: Value(senderId),
|
||||||
|
content:
|
||||||
|
content == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(content),
|
||||||
|
nonce:
|
||||||
|
nonce == null && nullToAbsent ? const Value.absent() : Value(nonce),
|
||||||
|
data: Value(data),
|
||||||
|
createdAt: Value(createdAt),
|
||||||
|
status: Value(status),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ChatMessage.fromJson(
|
||||||
|
Map<String, dynamic> json, {
|
||||||
|
ValueSerializer? serializer,
|
||||||
|
}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return ChatMessage(
|
||||||
|
id: serializer.fromJson<String>(json['id']),
|
||||||
|
roomId: serializer.fromJson<int>(json['roomId']),
|
||||||
|
senderId: serializer.fromJson<String>(json['senderId']),
|
||||||
|
content: serializer.fromJson<String?>(json['content']),
|
||||||
|
nonce: serializer.fromJson<String?>(json['nonce']),
|
||||||
|
data: serializer.fromJson<String>(json['data']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
|
status: $ChatMessagesTable.$converterstatus.fromJson(
|
||||||
|
serializer.fromJson<int>(json['status']),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': serializer.toJson<String>(id),
|
||||||
|
'roomId': serializer.toJson<int>(roomId),
|
||||||
|
'senderId': serializer.toJson<String>(senderId),
|
||||||
|
'content': serializer.toJson<String?>(content),
|
||||||
|
'nonce': serializer.toJson<String?>(nonce),
|
||||||
|
'data': serializer.toJson<String>(data),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
|
'status': serializer.toJson<int>(
|
||||||
|
$ChatMessagesTable.$converterstatus.toJson(status),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessage copyWith({
|
||||||
|
String? id,
|
||||||
|
int? roomId,
|
||||||
|
String? senderId,
|
||||||
|
Value<String?> content = const Value.absent(),
|
||||||
|
Value<String?> nonce = const Value.absent(),
|
||||||
|
String? data,
|
||||||
|
DateTime? createdAt,
|
||||||
|
MessageStatus? status,
|
||||||
|
}) => ChatMessage(
|
||||||
|
id: id ?? this.id,
|
||||||
|
roomId: roomId ?? this.roomId,
|
||||||
|
senderId: senderId ?? this.senderId,
|
||||||
|
content: content.present ? content.value : this.content,
|
||||||
|
nonce: nonce.present ? nonce.value : this.nonce,
|
||||||
|
data: data ?? this.data,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
status: status ?? this.status,
|
||||||
|
);
|
||||||
|
ChatMessage copyWithCompanion(ChatMessagesCompanion data) {
|
||||||
|
return ChatMessage(
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
roomId: data.roomId.present ? data.roomId.value : this.roomId,
|
||||||
|
senderId: data.senderId.present ? data.senderId.value : this.senderId,
|
||||||
|
content: data.content.present ? data.content.value : this.content,
|
||||||
|
nonce: data.nonce.present ? data.nonce.value : this.nonce,
|
||||||
|
data: data.data.present ? data.data.value : this.data,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
|
status: data.status.present ? data.status.value : this.status,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('ChatMessage(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('roomId: $roomId, ')
|
||||||
|
..write('senderId: $senderId, ')
|
||||||
|
..write('content: $content, ')
|
||||||
|
..write('nonce: $nonce, ')
|
||||||
|
..write('data: $data, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
|
..write('status: $status')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
id,
|
||||||
|
roomId,
|
||||||
|
senderId,
|
||||||
|
content,
|
||||||
|
nonce,
|
||||||
|
data,
|
||||||
|
createdAt,
|
||||||
|
status,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is ChatMessage &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.roomId == this.roomId &&
|
||||||
|
other.senderId == this.senderId &&
|
||||||
|
other.content == this.content &&
|
||||||
|
other.nonce == this.nonce &&
|
||||||
|
other.data == this.data &&
|
||||||
|
other.createdAt == this.createdAt &&
|
||||||
|
other.status == this.status);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatMessagesCompanion extends UpdateCompanion<ChatMessage> {
|
||||||
|
final Value<String> id;
|
||||||
|
final Value<int> roomId;
|
||||||
|
final Value<String> senderId;
|
||||||
|
final Value<String?> content;
|
||||||
|
final Value<String?> nonce;
|
||||||
|
final Value<String> data;
|
||||||
|
final Value<DateTime> createdAt;
|
||||||
|
final Value<MessageStatus> status;
|
||||||
|
final Value<int> rowid;
|
||||||
|
const ChatMessagesCompanion({
|
||||||
|
this.id = const Value.absent(),
|
||||||
|
this.roomId = const Value.absent(),
|
||||||
|
this.senderId = const Value.absent(),
|
||||||
|
this.content = const Value.absent(),
|
||||||
|
this.nonce = const Value.absent(),
|
||||||
|
this.data = const Value.absent(),
|
||||||
|
this.createdAt = const Value.absent(),
|
||||||
|
this.status = const Value.absent(),
|
||||||
|
this.rowid = const Value.absent(),
|
||||||
|
});
|
||||||
|
ChatMessagesCompanion.insert({
|
||||||
|
required String id,
|
||||||
|
required int roomId,
|
||||||
|
required String senderId,
|
||||||
|
this.content = const Value.absent(),
|
||||||
|
this.nonce = const Value.absent(),
|
||||||
|
required String data,
|
||||||
|
required DateTime createdAt,
|
||||||
|
required MessageStatus status,
|
||||||
|
this.rowid = const Value.absent(),
|
||||||
|
}) : id = Value(id),
|
||||||
|
roomId = Value(roomId),
|
||||||
|
senderId = Value(senderId),
|
||||||
|
data = Value(data),
|
||||||
|
createdAt = Value(createdAt),
|
||||||
|
status = Value(status);
|
||||||
|
static Insertable<ChatMessage> custom({
|
||||||
|
Expression<String>? id,
|
||||||
|
Expression<int>? roomId,
|
||||||
|
Expression<String>? senderId,
|
||||||
|
Expression<String>? content,
|
||||||
|
Expression<String>? nonce,
|
||||||
|
Expression<String>? data,
|
||||||
|
Expression<DateTime>? createdAt,
|
||||||
|
Expression<int>? status,
|
||||||
|
Expression<int>? rowid,
|
||||||
|
}) {
|
||||||
|
return RawValuesInsertable({
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (roomId != null) 'room_id': roomId,
|
||||||
|
if (senderId != null) 'sender_id': senderId,
|
||||||
|
if (content != null) 'content': content,
|
||||||
|
if (nonce != null) 'nonce': nonce,
|
||||||
|
if (data != null) 'data': data,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
|
if (status != null) 'status': status,
|
||||||
|
if (rowid != null) 'rowid': rowid,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessagesCompanion copyWith({
|
||||||
|
Value<String>? id,
|
||||||
|
Value<int>? roomId,
|
||||||
|
Value<String>? senderId,
|
||||||
|
Value<String?>? content,
|
||||||
|
Value<String?>? nonce,
|
||||||
|
Value<String>? data,
|
||||||
|
Value<DateTime>? createdAt,
|
||||||
|
Value<MessageStatus>? status,
|
||||||
|
Value<int>? rowid,
|
||||||
|
}) {
|
||||||
|
return ChatMessagesCompanion(
|
||||||
|
id: id ?? this.id,
|
||||||
|
roomId: roomId ?? this.roomId,
|
||||||
|
senderId: senderId ?? this.senderId,
|
||||||
|
content: content ?? this.content,
|
||||||
|
nonce: nonce ?? this.nonce,
|
||||||
|
data: data ?? this.data,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
status: status ?? this.status,
|
||||||
|
rowid: rowid ?? this.rowid,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = Variable<String>(id.value);
|
||||||
|
}
|
||||||
|
if (roomId.present) {
|
||||||
|
map['room_id'] = Variable<int>(roomId.value);
|
||||||
|
}
|
||||||
|
if (senderId.present) {
|
||||||
|
map['sender_id'] = Variable<String>(senderId.value);
|
||||||
|
}
|
||||||
|
if (content.present) {
|
||||||
|
map['content'] = Variable<String>(content.value);
|
||||||
|
}
|
||||||
|
if (nonce.present) {
|
||||||
|
map['nonce'] = Variable<String>(nonce.value);
|
||||||
|
}
|
||||||
|
if (data.present) {
|
||||||
|
map['data'] = Variable<String>(data.value);
|
||||||
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
|
if (status.present) {
|
||||||
|
map['status'] = Variable<int>(
|
||||||
|
$ChatMessagesTable.$converterstatus.toSql(status.value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (rowid.present) {
|
||||||
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('ChatMessagesCompanion(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('roomId: $roomId, ')
|
||||||
|
..write('senderId: $senderId, ')
|
||||||
|
..write('content: $content, ')
|
||||||
|
..write('nonce: $nonce, ')
|
||||||
|
..write('data: $data, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
|
..write('status: $status, ')
|
||||||
|
..write('rowid: $rowid')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _$AppDatabase extends GeneratedDatabase {
|
||||||
|
_$AppDatabase(QueryExecutor e) : super(e);
|
||||||
|
$AppDatabaseManager get managers => $AppDatabaseManager(this);
|
||||||
|
late final $ChatMessagesTable chatMessages = $ChatMessagesTable(this);
|
||||||
|
@override
|
||||||
|
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||||
|
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||||
|
@override
|
||||||
|
List<DatabaseSchemaEntity> get allSchemaEntities => [chatMessages];
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$ChatMessagesTableCreateCompanionBuilder =
|
||||||
|
ChatMessagesCompanion Function({
|
||||||
|
required String id,
|
||||||
|
required int roomId,
|
||||||
|
required String senderId,
|
||||||
|
Value<String?> content,
|
||||||
|
Value<String?> nonce,
|
||||||
|
required String data,
|
||||||
|
required DateTime createdAt,
|
||||||
|
required MessageStatus status,
|
||||||
|
Value<int> rowid,
|
||||||
|
});
|
||||||
|
typedef $$ChatMessagesTableUpdateCompanionBuilder =
|
||||||
|
ChatMessagesCompanion Function({
|
||||||
|
Value<String> id,
|
||||||
|
Value<int> roomId,
|
||||||
|
Value<String> senderId,
|
||||||
|
Value<String?> content,
|
||||||
|
Value<String?> nonce,
|
||||||
|
Value<String> data,
|
||||||
|
Value<DateTime> createdAt,
|
||||||
|
Value<MessageStatus> status,
|
||||||
|
Value<int> rowid,
|
||||||
|
});
|
||||||
|
|
||||||
|
class $$ChatMessagesTableFilterComposer
|
||||||
|
extends Composer<_$AppDatabase, $ChatMessagesTable> {
|
||||||
|
$$ChatMessagesTableFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<int> get roomId => $composableBuilder(
|
||||||
|
column: $table.roomId,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get senderId => $composableBuilder(
|
||||||
|
column: $table.senderId,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get content => $composableBuilder(
|
||||||
|
column: $table.content,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get nonce => $composableBuilder(
|
||||||
|
column: $table.nonce,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<String> get data => $composableBuilder(
|
||||||
|
column: $table.data,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnWithTypeConverterFilters<MessageStatus, MessageStatus, int>
|
||||||
|
get status => $composableBuilder(
|
||||||
|
column: $table.status,
|
||||||
|
builder: (column) => ColumnWithTypeConverterFilters(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$ChatMessagesTableOrderingComposer
|
||||||
|
extends Composer<_$AppDatabase, $ChatMessagesTable> {
|
||||||
|
$$ChatMessagesTableOrderingComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<int> get roomId => $composableBuilder(
|
||||||
|
column: $table.roomId,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get senderId => $composableBuilder(
|
||||||
|
column: $table.senderId,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get content => $composableBuilder(
|
||||||
|
column: $table.content,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get nonce => $composableBuilder(
|
||||||
|
column: $table.nonce,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<String> get data => $composableBuilder(
|
||||||
|
column: $table.data,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
ColumnOrderings<int> get status => $composableBuilder(
|
||||||
|
column: $table.status,
|
||||||
|
builder: (column) => ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$ChatMessagesTableAnnotationComposer
|
||||||
|
extends Composer<_$AppDatabase, $ChatMessagesTable> {
|
||||||
|
$$ChatMessagesTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get roomId =>
|
||||||
|
$composableBuilder(column: $table.roomId, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get senderId =>
|
||||||
|
$composableBuilder(column: $table.senderId, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get content =>
|
||||||
|
$composableBuilder(column: $table.content, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get nonce =>
|
||||||
|
$composableBuilder(column: $table.nonce, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get data =>
|
||||||
|
$composableBuilder(column: $table.data, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumnWithTypeConverter<MessageStatus, int> get status =>
|
||||||
|
$composableBuilder(column: $table.status, builder: (column) => column);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$ChatMessagesTableTableManager
|
||||||
|
extends
|
||||||
|
RootTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$ChatMessagesTable,
|
||||||
|
ChatMessage,
|
||||||
|
$$ChatMessagesTableFilterComposer,
|
||||||
|
$$ChatMessagesTableOrderingComposer,
|
||||||
|
$$ChatMessagesTableAnnotationComposer,
|
||||||
|
$$ChatMessagesTableCreateCompanionBuilder,
|
||||||
|
$$ChatMessagesTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
ChatMessage,
|
||||||
|
BaseReferences<_$AppDatabase, $ChatMessagesTable, ChatMessage>,
|
||||||
|
),
|
||||||
|
ChatMessage,
|
||||||
|
PrefetchHooks Function()
|
||||||
|
> {
|
||||||
|
$$ChatMessagesTableTableManager(_$AppDatabase db, $ChatMessagesTable table)
|
||||||
|
: super(
|
||||||
|
TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
createFilteringComposer:
|
||||||
|
() => $$ChatMessagesTableFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer:
|
||||||
|
() => $$ChatMessagesTableOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer:
|
||||||
|
() =>
|
||||||
|
$$ChatMessagesTableAnnotationComposer($db: db, $table: table),
|
||||||
|
updateCompanionCallback:
|
||||||
|
({
|
||||||
|
Value<String> id = const Value.absent(),
|
||||||
|
Value<int> roomId = const Value.absent(),
|
||||||
|
Value<String> senderId = const Value.absent(),
|
||||||
|
Value<String?> content = const Value.absent(),
|
||||||
|
Value<String?> nonce = const Value.absent(),
|
||||||
|
Value<String> data = const Value.absent(),
|
||||||
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
|
Value<MessageStatus> status = const Value.absent(),
|
||||||
|
Value<int> rowid = const Value.absent(),
|
||||||
|
}) => ChatMessagesCompanion(
|
||||||
|
id: id,
|
||||||
|
roomId: roomId,
|
||||||
|
senderId: senderId,
|
||||||
|
content: content,
|
||||||
|
nonce: nonce,
|
||||||
|
data: data,
|
||||||
|
createdAt: createdAt,
|
||||||
|
status: status,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
|
createCompanionCallback:
|
||||||
|
({
|
||||||
|
required String id,
|
||||||
|
required int roomId,
|
||||||
|
required String senderId,
|
||||||
|
Value<String?> content = const Value.absent(),
|
||||||
|
Value<String?> nonce = const Value.absent(),
|
||||||
|
required String data,
|
||||||
|
required DateTime createdAt,
|
||||||
|
required MessageStatus status,
|
||||||
|
Value<int> rowid = const Value.absent(),
|
||||||
|
}) => ChatMessagesCompanion.insert(
|
||||||
|
id: id,
|
||||||
|
roomId: roomId,
|
||||||
|
senderId: senderId,
|
||||||
|
content: content,
|
||||||
|
nonce: nonce,
|
||||||
|
data: data,
|
||||||
|
createdAt: createdAt,
|
||||||
|
status: status,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
|
withReferenceMapper:
|
||||||
|
(p0) =>
|
||||||
|
p0
|
||||||
|
.map(
|
||||||
|
(e) => (
|
||||||
|
e.readTable(table),
|
||||||
|
BaseReferences(db, table, e),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$ChatMessagesTableProcessedTableManager =
|
||||||
|
ProcessedTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$ChatMessagesTable,
|
||||||
|
ChatMessage,
|
||||||
|
$$ChatMessagesTableFilterComposer,
|
||||||
|
$$ChatMessagesTableOrderingComposer,
|
||||||
|
$$ChatMessagesTableAnnotationComposer,
|
||||||
|
$$ChatMessagesTableCreateCompanionBuilder,
|
||||||
|
$$ChatMessagesTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
ChatMessage,
|
||||||
|
BaseReferences<_$AppDatabase, $ChatMessagesTable, ChatMessage>,
|
||||||
|
),
|
||||||
|
ChatMessage,
|
||||||
|
PrefetchHooks Function()
|
||||||
|
>;
|
||||||
|
|
||||||
|
class $AppDatabaseManager {
|
||||||
|
final _$AppDatabase _db;
|
||||||
|
$AppDatabaseManager(this._db);
|
||||||
|
$$ChatMessagesTableTableManager get chatMessages =>
|
||||||
|
$$ChatMessagesTableTableManager(_db, _db.chatMessages);
|
||||||
|
}
|
58
lib/database/message.dart
Normal file
58
lib/database/message.dart
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:island/models/chat.dart';
|
||||||
|
|
||||||
|
class ChatMessages extends Table {
|
||||||
|
TextColumn get id => text()();
|
||||||
|
IntColumn get roomId => integer()();
|
||||||
|
TextColumn get senderId => text()();
|
||||||
|
TextColumn get content => text().nullable()();
|
||||||
|
TextColumn get nonce => text().nullable()();
|
||||||
|
TextColumn get data => text()();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
IntColumn get status => intEnum<MessageStatus>()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalChatMessage {
|
||||||
|
final String id;
|
||||||
|
final int roomId;
|
||||||
|
final String senderId;
|
||||||
|
final Map<String, dynamic> data;
|
||||||
|
final DateTime createdAt;
|
||||||
|
MessageStatus status;
|
||||||
|
final String? nonce;
|
||||||
|
|
||||||
|
LocalChatMessage({
|
||||||
|
required this.id,
|
||||||
|
required this.roomId,
|
||||||
|
required this.senderId,
|
||||||
|
required this.data,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.status,
|
||||||
|
this.nonce,
|
||||||
|
});
|
||||||
|
|
||||||
|
SnChatMessage toRemoteMessage() {
|
||||||
|
return SnChatMessage.fromJson(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LocalChatMessage fromRemoteMessage(
|
||||||
|
SnChatMessage message,
|
||||||
|
MessageStatus status, {
|
||||||
|
String? nonce,
|
||||||
|
}) {
|
||||||
|
return LocalChatMessage(
|
||||||
|
id: message.id,
|
||||||
|
roomId: message.chatRoomId,
|
||||||
|
senderId: message.senderId,
|
||||||
|
data: message.toJson(),
|
||||||
|
createdAt: message.createdAt,
|
||||||
|
status: status,
|
||||||
|
nonce: nonce ?? message.nonce,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MessageStatus { pending, sent, failed }
|
263
lib/database/message_repository.dart
Normal file
263
lib/database/message_repository.dart
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:island/database/drift_db.dart';
|
||||||
|
import 'package:island/database/message.dart';
|
||||||
|
import 'package:island/models/chat.dart';
|
||||||
|
import 'package:island/models/file.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
class MessageRepository {
|
||||||
|
final SnChat room;
|
||||||
|
final Dio _apiClient;
|
||||||
|
final AppDatabase _database;
|
||||||
|
|
||||||
|
SnChatMember? _identity;
|
||||||
|
|
||||||
|
final Map<String, LocalChatMessage> _pendingMessages = {};
|
||||||
|
|
||||||
|
MessageRepository(this.room, this._apiClient, this._database) {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
|
Future<void> initialize() async {
|
||||||
|
if (initialized) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await _apiClient.get('/chat/${room.id}/members/me');
|
||||||
|
_identity = SnChatMember.fromJson(response.data);
|
||||||
|
initialized = true;
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<LocalChatMessage>> listMessages({
|
||||||
|
int offset = 0,
|
||||||
|
int take = 20,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
final localMessages = await _getCachedMessages(
|
||||||
|
room.id,
|
||||||
|
offset: offset,
|
||||||
|
take: take,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
// Always fetch latest messages in background if we're loading the first page
|
||||||
|
_fetchAndCacheMessages(room.id, offset: offset, take: take);
|
||||||
|
|
||||||
|
if (localMessages.isNotEmpty) {
|
||||||
|
return localMessages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _fetchAndCacheMessages(room.id, offset: offset, take: take);
|
||||||
|
} catch (e) {
|
||||||
|
// If API fails but we have local messages, return them
|
||||||
|
final localMessages = await _getCachedMessages(
|
||||||
|
room.id,
|
||||||
|
offset: offset,
|
||||||
|
take: take,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (localMessages.isNotEmpty) {
|
||||||
|
return localMessages;
|
||||||
|
}
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<LocalChatMessage>> _getCachedMessages(
|
||||||
|
int roomId, {
|
||||||
|
int offset = 0,
|
||||||
|
int take = 20,
|
||||||
|
}) async {
|
||||||
|
// Get messages from local database
|
||||||
|
final dbMessages = await _database.getMessagesForRoom(
|
||||||
|
roomId,
|
||||||
|
offset: offset,
|
||||||
|
limit: take,
|
||||||
|
);
|
||||||
|
final dbLocalMessages =
|
||||||
|
dbMessages.map(_database.companionToMessage).toList();
|
||||||
|
|
||||||
|
// Combine with pending messages
|
||||||
|
final pendingForRoom =
|
||||||
|
_pendingMessages.values.where((msg) => msg.roomId == roomId).toList();
|
||||||
|
|
||||||
|
// Sort by timestamp descending (newest first)
|
||||||
|
final allMessages = [...pendingForRoom, ...dbLocalMessages];
|
||||||
|
allMessages.sort((a, b) => b.createdAt.compareTo(a.createdAt));
|
||||||
|
|
||||||
|
// Apply pagination
|
||||||
|
if (offset >= allMessages.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final end =
|
||||||
|
(offset + take) > allMessages.length
|
||||||
|
? allMessages.length
|
||||||
|
: (offset + take);
|
||||||
|
return allMessages.sublist(offset, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<LocalChatMessage>> _fetchAndCacheMessages(
|
||||||
|
int roomId, {
|
||||||
|
int offset = 0,
|
||||||
|
int take = 20,
|
||||||
|
}) async {
|
||||||
|
final response = await _apiClient.get(
|
||||||
|
'/chat/$roomId/messages',
|
||||||
|
queryParameters: {'offset': offset, 'take': take},
|
||||||
|
);
|
||||||
|
|
||||||
|
final total = int.parse(response.headers.value('X-Total') ?? '0');
|
||||||
|
final List<dynamic> data = response.data;
|
||||||
|
|
||||||
|
final messages =
|
||||||
|
data.map((json) {
|
||||||
|
final remoteMessage = SnChatMessage.fromJson(json);
|
||||||
|
return LocalChatMessage.fromRemoteMessage(
|
||||||
|
remoteMessage,
|
||||||
|
MessageStatus.sent,
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
for (final message in messages) {
|
||||||
|
await _database.saveMessage(_database.messageToCompanion(message));
|
||||||
|
if (message.nonce != null) {
|
||||||
|
_pendingMessages.removeWhere(
|
||||||
|
(_, pendingMsg) => pendingMsg.nonce == message.nonce,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LocalChatMessage> sendMessage(
|
||||||
|
int roomId,
|
||||||
|
String content, {
|
||||||
|
List<SnCloudFile>? attachments,
|
||||||
|
Map<String, dynamic>? meta,
|
||||||
|
}) async {
|
||||||
|
if (!initialized) {
|
||||||
|
throw UnsupportedError(
|
||||||
|
"The message repository is not ready for send message.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a unique nonce for this message
|
||||||
|
final nonce = const Uuid().v4();
|
||||||
|
|
||||||
|
// Create a local message with pending status
|
||||||
|
final mockMessage = SnChatMessage(
|
||||||
|
id: 'pending_$nonce',
|
||||||
|
chatRoomId: roomId,
|
||||||
|
senderId: _identity!.id,
|
||||||
|
content: content,
|
||||||
|
createdAt: DateTime.now(),
|
||||||
|
updatedAt: DateTime.now(),
|
||||||
|
nonce: nonce,
|
||||||
|
sender: _identity!,
|
||||||
|
);
|
||||||
|
|
||||||
|
final localMessage = LocalChatMessage.fromRemoteMessage(
|
||||||
|
mockMessage,
|
||||||
|
MessageStatus.pending,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Store in memory and database
|
||||||
|
_pendingMessages[localMessage.id] = localMessage;
|
||||||
|
await _database.saveMessage(_database.messageToCompanion(localMessage));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send to server
|
||||||
|
final response = await _apiClient.post(
|
||||||
|
'/chat/$roomId/messages',
|
||||||
|
data: {
|
||||||
|
'content': content,
|
||||||
|
'attachments_id': attachments,
|
||||||
|
'meta': meta,
|
||||||
|
'nonce': nonce,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update with server response
|
||||||
|
final remoteMessage = SnChatMessage.fromJson(response.data);
|
||||||
|
final updatedMessage = LocalChatMessage.fromRemoteMessage(
|
||||||
|
remoteMessage,
|
||||||
|
MessageStatus.sent,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove from pending and update in database
|
||||||
|
_pendingMessages.remove(localMessage.id);
|
||||||
|
await _database.deleteMessage(localMessage.id);
|
||||||
|
await _database.saveMessage(_database.messageToCompanion(updatedMessage));
|
||||||
|
|
||||||
|
return updatedMessage;
|
||||||
|
} catch (e) {
|
||||||
|
// Update status to failed
|
||||||
|
localMessage.status = MessageStatus.failed;
|
||||||
|
_pendingMessages[localMessage.id] = localMessage;
|
||||||
|
await _database.updateMessageStatus(
|
||||||
|
localMessage.id,
|
||||||
|
MessageStatus.failed,
|
||||||
|
);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LocalChatMessage> retryMessage(String pendingMessageId) async {
|
||||||
|
final message = _pendingMessages[pendingMessageId];
|
||||||
|
if (message == null) {
|
||||||
|
throw Exception('Message not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update status back to pending
|
||||||
|
message.status = MessageStatus.pending;
|
||||||
|
_pendingMessages[pendingMessageId] = message;
|
||||||
|
await _database.updateMessageStatus(
|
||||||
|
pendingMessageId,
|
||||||
|
MessageStatus.pending,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send to server
|
||||||
|
var remoteMessage = message.toRemoteMessage();
|
||||||
|
final response = await _apiClient.post(
|
||||||
|
'/chat/${message.roomId}/messages',
|
||||||
|
data: {
|
||||||
|
'content': remoteMessage.content,
|
||||||
|
'attachments_id': remoteMessage.attachments,
|
||||||
|
'meta': remoteMessage.meta,
|
||||||
|
'nonce': message.nonce,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update with server response
|
||||||
|
remoteMessage = SnChatMessage.fromJson(response.data);
|
||||||
|
final updatedMessage = LocalChatMessage.fromRemoteMessage(
|
||||||
|
remoteMessage,
|
||||||
|
MessageStatus.sent,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove from pending and update in database
|
||||||
|
_pendingMessages.remove(pendingMessageId);
|
||||||
|
await _database.deleteMessage(pendingMessageId);
|
||||||
|
await _database.saveMessage(_database.messageToCompanion(updatedMessage));
|
||||||
|
|
||||||
|
return updatedMessage;
|
||||||
|
} catch (e) {
|
||||||
|
// Update status to failed
|
||||||
|
message.status = MessageStatus.failed;
|
||||||
|
_pendingMessages[pendingMessageId] = message;
|
||||||
|
await _database.updateMessageStatus(
|
||||||
|
pendingMessageId,
|
||||||
|
MessageStatus.failed,
|
||||||
|
);
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,3 +24,68 @@ abstract class SnChat with _$SnChat {
|
|||||||
|
|
||||||
factory SnChat.fromJson(Map<String, dynamic> json) => _$SnChatFromJson(json);
|
factory SnChat.fromJson(Map<String, dynamic> json) => _$SnChatFromJson(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class SnChatMessage with _$SnChatMessage {
|
||||||
|
const factory SnChatMessage({
|
||||||
|
required DateTime createdAt,
|
||||||
|
required DateTime updatedAt,
|
||||||
|
DateTime? deletedAt,
|
||||||
|
required String id,
|
||||||
|
String? content,
|
||||||
|
String? nonce,
|
||||||
|
@Default({}) Map<String, dynamic> meta,
|
||||||
|
@Default([]) List<String> membersMetioned,
|
||||||
|
DateTime? editedAt,
|
||||||
|
@Default([]) List<SnCloudFile> attachments,
|
||||||
|
@Default([]) List<SnChatReaction> reactions,
|
||||||
|
String? repliedMessageId,
|
||||||
|
SnChatMessage? repliedMessage,
|
||||||
|
String? forwardedMessageId,
|
||||||
|
SnChatMessage? forwardedMessage,
|
||||||
|
required String senderId,
|
||||||
|
required SnChatMember sender,
|
||||||
|
required int chatRoomId,
|
||||||
|
}) = _SnChatMessage;
|
||||||
|
|
||||||
|
factory SnChatMessage.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnChatMessageFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class SnChatReaction with _$SnChatReaction {
|
||||||
|
const factory SnChatReaction({
|
||||||
|
required DateTime createdAt,
|
||||||
|
required DateTime updatedAt,
|
||||||
|
required DateTime? deletedAt,
|
||||||
|
required String id,
|
||||||
|
required String messageId,
|
||||||
|
required String senderId,
|
||||||
|
required SnChatMember sender,
|
||||||
|
required String symbol,
|
||||||
|
required int attitude,
|
||||||
|
}) = _SnChatReaction;
|
||||||
|
|
||||||
|
factory SnChatReaction.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnChatReactionFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class SnChatMember with _$SnChatMember {
|
||||||
|
const factory SnChatMember({
|
||||||
|
required DateTime createdAt,
|
||||||
|
required DateTime updatedAt,
|
||||||
|
required DateTime? deletedAt,
|
||||||
|
required String id,
|
||||||
|
required int chatRoomId,
|
||||||
|
required int accountId,
|
||||||
|
required String? nick,
|
||||||
|
required int role,
|
||||||
|
required int notify,
|
||||||
|
required DateTime? joinedAt,
|
||||||
|
required bool isBot,
|
||||||
|
}) = _SnChatMember;
|
||||||
|
|
||||||
|
factory SnChatMember.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SnChatMemberFromJson(json);
|
||||||
|
}
|
||||||
|
@ -250,4 +250,616 @@ $SnRealmCopyWith<$Res>? get realm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnChatMessage {
|
||||||
|
|
||||||
|
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String? get content; String? get nonce; Map<String, dynamic> get meta; List<String> get membersMetioned; DateTime? get editedAt; List<SnCloudFile> get attachments; List<SnChatReaction> get reactions; String? get repliedMessageId; SnChatMessage? get repliedMessage; String? get forwardedMessageId; SnChatMessage? get forwardedMessage; String get senderId; SnChatMember get sender; int get chatRoomId;
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMessageCopyWith<SnChatMessage> get copyWith => _$SnChatMessageCopyWithImpl<SnChatMessage>(this as SnChatMessage, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnChatMessage to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other.meta, meta)&&const DeepCollectionEquality().equals(other.membersMetioned, membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.repliedMessage, repliedMessage) || other.repliedMessage == repliedMessage)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.forwardedMessage, forwardedMessage) || other.forwardedMessage == forwardedMessage)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,content,nonce,const DeepCollectionEquality().hash(meta),const DeepCollectionEquality().hash(membersMetioned),editedAt,const DeepCollectionEquality().hash(attachments),const DeepCollectionEquality().hash(reactions),repliedMessageId,repliedMessage,forwardedMessageId,forwardedMessage,senderId,sender,chatRoomId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, repliedMessage: $repliedMessage, forwardedMessageId: $forwardedMessageId, forwardedMessage: $forwardedMessage, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnChatMessageCopyWith<$Res> {
|
||||||
|
factory $SnChatMessageCopyWith(SnChatMessage value, $Res Function(SnChatMessage) _then) = _$SnChatMessageCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, SnChatMessage? repliedMessage, String? forwardedMessageId, SnChatMessage? forwardedMessage, String senderId, SnChatMember sender, int chatRoomId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnChatMessageCopyWith<$Res>? get repliedMessage;$SnChatMessageCopyWith<$Res>? get forwardedMessage;$SnChatMemberCopyWith<$Res> get sender;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnChatMessageCopyWithImpl<$Res>
|
||||||
|
implements $SnChatMessageCopyWith<$Res> {
|
||||||
|
_$SnChatMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnChatMessage _self;
|
||||||
|
final $Res Function(SnChatMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? repliedMessage = freezed,Object? forwardedMessageId = freezed,Object? forwardedMessage = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,membersMetioned: null == membersMetioned ? _self.membersMetioned : membersMetioned // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,attachments: null == attachments ? _self.attachments : attachments // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnCloudFile>,reactions: null == reactions ? _self.reactions : reactions // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnChatReaction>,repliedMessageId: freezed == repliedMessageId ? _self.repliedMessageId : repliedMessageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,repliedMessage: freezed == repliedMessage ? _self.repliedMessage : repliedMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMessage?,forwardedMessageId: freezed == forwardedMessageId ? _self.forwardedMessageId : forwardedMessageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,forwardedMessage: freezed == forwardedMessage ? _self.forwardedMessage : forwardedMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMessage?,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMember,chatRoomId: null == chatRoomId ? _self.chatRoomId : chatRoomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMessageCopyWith<$Res>? get repliedMessage {
|
||||||
|
if (_self.repliedMessage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnChatMessageCopyWith<$Res>(_self.repliedMessage!, (value) {
|
||||||
|
return _then(_self.copyWith(repliedMessage: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMessageCopyWith<$Res>? get forwardedMessage {
|
||||||
|
if (_self.forwardedMessage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnChatMessageCopyWith<$Res>(_self.forwardedMessage!, (value) {
|
||||||
|
return _then(_self.copyWith(forwardedMessage: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMemberCopyWith<$Res> get sender {
|
||||||
|
|
||||||
|
return $SnChatMemberCopyWith<$Res>(_self.sender, (value) {
|
||||||
|
return _then(_self.copyWith(sender: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnChatMessage implements SnChatMessage {
|
||||||
|
const _SnChatMessage({required this.createdAt, required this.updatedAt, this.deletedAt, required this.id, this.content, this.nonce, final Map<String, dynamic> meta = const {}, final List<String> membersMetioned = const [], this.editedAt, final List<SnCloudFile> attachments = const [], final List<SnChatReaction> reactions = const [], this.repliedMessageId, this.repliedMessage, this.forwardedMessageId, this.forwardedMessage, required this.senderId, required this.sender, required this.chatRoomId}): _meta = meta,_membersMetioned = membersMetioned,_attachments = attachments,_reactions = reactions;
|
||||||
|
factory _SnChatMessage.fromJson(Map<String, dynamic> json) => _$SnChatMessageFromJson(json);
|
||||||
|
|
||||||
|
@override final DateTime createdAt;
|
||||||
|
@override final DateTime updatedAt;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
@override final String id;
|
||||||
|
@override final String? content;
|
||||||
|
@override final String? nonce;
|
||||||
|
final Map<String, dynamic> _meta;
|
||||||
|
@override@JsonKey() Map<String, dynamic> get meta {
|
||||||
|
if (_meta is EqualUnmodifiableMapView) return _meta;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> _membersMetioned;
|
||||||
|
@override@JsonKey() List<String> get membersMetioned {
|
||||||
|
if (_membersMetioned is EqualUnmodifiableListView) return _membersMetioned;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_membersMetioned);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final DateTime? editedAt;
|
||||||
|
final List<SnCloudFile> _attachments;
|
||||||
|
@override@JsonKey() List<SnCloudFile> get attachments {
|
||||||
|
if (_attachments is EqualUnmodifiableListView) return _attachments;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_attachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<SnChatReaction> _reactions;
|
||||||
|
@override@JsonKey() List<SnChatReaction> get reactions {
|
||||||
|
if (_reactions is EqualUnmodifiableListView) return _reactions;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_reactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final String? repliedMessageId;
|
||||||
|
@override final SnChatMessage? repliedMessage;
|
||||||
|
@override final String? forwardedMessageId;
|
||||||
|
@override final SnChatMessage? forwardedMessage;
|
||||||
|
@override final String senderId;
|
||||||
|
@override final SnChatMember sender;
|
||||||
|
@override final int chatRoomId;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnChatMessageCopyWith<_SnChatMessage> get copyWith => __$SnChatMessageCopyWithImpl<_SnChatMessage>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnChatMessageToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMessage&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.content, content) || other.content == content)&&(identical(other.nonce, nonce) || other.nonce == nonce)&&const DeepCollectionEquality().equals(other._meta, _meta)&&const DeepCollectionEquality().equals(other._membersMetioned, _membersMetioned)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&(identical(other.repliedMessageId, repliedMessageId) || other.repliedMessageId == repliedMessageId)&&(identical(other.repliedMessage, repliedMessage) || other.repliedMessage == repliedMessage)&&(identical(other.forwardedMessageId, forwardedMessageId) || other.forwardedMessageId == forwardedMessageId)&&(identical(other.forwardedMessage, forwardedMessage) || other.forwardedMessage == forwardedMessage)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,content,nonce,const DeepCollectionEquality().hash(_meta),const DeepCollectionEquality().hash(_membersMetioned),editedAt,const DeepCollectionEquality().hash(_attachments),const DeepCollectionEquality().hash(_reactions),repliedMessageId,repliedMessage,forwardedMessageId,forwardedMessage,senderId,sender,chatRoomId);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatMessage(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, content: $content, nonce: $nonce, meta: $meta, membersMetioned: $membersMetioned, editedAt: $editedAt, attachments: $attachments, reactions: $reactions, repliedMessageId: $repliedMessageId, repliedMessage: $repliedMessage, forwardedMessageId: $forwardedMessageId, forwardedMessage: $forwardedMessage, senderId: $senderId, sender: $sender, chatRoomId: $chatRoomId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnChatMessageCopyWith<$Res> implements $SnChatMessageCopyWith<$Res> {
|
||||||
|
factory _$SnChatMessageCopyWith(_SnChatMessage value, $Res Function(_SnChatMessage) _then) = __$SnChatMessageCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String? content, String? nonce, Map<String, dynamic> meta, List<String> membersMetioned, DateTime? editedAt, List<SnCloudFile> attachments, List<SnChatReaction> reactions, String? repliedMessageId, SnChatMessage? repliedMessage, String? forwardedMessageId, SnChatMessage? forwardedMessage, String senderId, SnChatMember sender, int chatRoomId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnChatMessageCopyWith<$Res>? get repliedMessage;@override $SnChatMessageCopyWith<$Res>? get forwardedMessage;@override $SnChatMemberCopyWith<$Res> get sender;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnChatMessageCopyWithImpl<$Res>
|
||||||
|
implements _$SnChatMessageCopyWith<$Res> {
|
||||||
|
__$SnChatMessageCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnChatMessage _self;
|
||||||
|
final $Res Function(_SnChatMessage) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? content = freezed,Object? nonce = freezed,Object? meta = null,Object? membersMetioned = null,Object? editedAt = freezed,Object? attachments = null,Object? reactions = null,Object? repliedMessageId = freezed,Object? repliedMessage = freezed,Object? forwardedMessageId = freezed,Object? forwardedMessage = freezed,Object? senderId = null,Object? sender = null,Object? chatRoomId = null,}) {
|
||||||
|
return _then(_SnChatMessage(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,content: freezed == content ? _self.content : content // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,nonce: freezed == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, dynamic>,membersMetioned: null == membersMetioned ? _self._membersMetioned : membersMetioned // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<String>,editedAt: freezed == editedAt ? _self.editedAt : editedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,attachments: null == attachments ? _self._attachments : attachments // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnCloudFile>,reactions: null == reactions ? _self._reactions : reactions // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<SnChatReaction>,repliedMessageId: freezed == repliedMessageId ? _self.repliedMessageId : repliedMessageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,repliedMessage: freezed == repliedMessage ? _self.repliedMessage : repliedMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMessage?,forwardedMessageId: freezed == forwardedMessageId ? _self.forwardedMessageId : forwardedMessageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,forwardedMessage: freezed == forwardedMessage ? _self.forwardedMessage : forwardedMessage // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMessage?,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMember,chatRoomId: null == chatRoomId ? _self.chatRoomId : chatRoomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMessageCopyWith<$Res>? get repliedMessage {
|
||||||
|
if (_self.repliedMessage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnChatMessageCopyWith<$Res>(_self.repliedMessage!, (value) {
|
||||||
|
return _then(_self.copyWith(repliedMessage: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMessageCopyWith<$Res>? get forwardedMessage {
|
||||||
|
if (_self.forwardedMessage == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $SnChatMessageCopyWith<$Res>(_self.forwardedMessage!, (value) {
|
||||||
|
return _then(_self.copyWith(forwardedMessage: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of SnChatMessage
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMemberCopyWith<$Res> get sender {
|
||||||
|
|
||||||
|
return $SnChatMemberCopyWith<$Res>(_self.sender, (value) {
|
||||||
|
return _then(_self.copyWith(sender: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnChatReaction {
|
||||||
|
|
||||||
|
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; String get messageId; String get senderId; SnChatMember get sender; String get symbol; int get attitude;
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatReactionCopyWith<SnChatReaction> get copyWith => _$SnChatReactionCopyWithImpl<SnChatReaction>(this as SnChatReaction, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnChatReaction to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatReaction&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.messageId, messageId) || other.messageId == messageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,messageId,senderId,sender,symbol,attitude);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatReaction(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, messageId: $messageId, senderId: $senderId, sender: $sender, symbol: $symbol, attitude: $attitude)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnChatReactionCopyWith<$Res> {
|
||||||
|
factory $SnChatReactionCopyWith(SnChatReaction value, $Res Function(SnChatReaction) _then) = _$SnChatReactionCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String messageId, String senderId, SnChatMember sender, String symbol, int attitude
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$SnChatMemberCopyWith<$Res> get sender;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnChatReactionCopyWithImpl<$Res>
|
||||||
|
implements $SnChatReactionCopyWith<$Res> {
|
||||||
|
_$SnChatReactionCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnChatReaction _self;
|
||||||
|
final $Res Function(SnChatReaction) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? messageId = null,Object? senderId = null,Object? sender = null,Object? symbol = null,Object? attitude = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,messageId: null == messageId ? _self.messageId : messageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMember,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMemberCopyWith<$Res> get sender {
|
||||||
|
|
||||||
|
return $SnChatMemberCopyWith<$Res>(_self.sender, (value) {
|
||||||
|
return _then(_self.copyWith(sender: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnChatReaction implements SnChatReaction {
|
||||||
|
const _SnChatReaction({required this.createdAt, required this.updatedAt, required this.deletedAt, required this.id, required this.messageId, required this.senderId, required this.sender, required this.symbol, required this.attitude});
|
||||||
|
factory _SnChatReaction.fromJson(Map<String, dynamic> json) => _$SnChatReactionFromJson(json);
|
||||||
|
|
||||||
|
@override final DateTime createdAt;
|
||||||
|
@override final DateTime updatedAt;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
@override final String id;
|
||||||
|
@override final String messageId;
|
||||||
|
@override final String senderId;
|
||||||
|
@override final SnChatMember sender;
|
||||||
|
@override final String symbol;
|
||||||
|
@override final int attitude;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnChatReactionCopyWith<_SnChatReaction> get copyWith => __$SnChatReactionCopyWithImpl<_SnChatReaction>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnChatReactionToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatReaction&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.messageId, messageId) || other.messageId == messageId)&&(identical(other.senderId, senderId) || other.senderId == senderId)&&(identical(other.sender, sender) || other.sender == sender)&&(identical(other.symbol, symbol) || other.symbol == symbol)&&(identical(other.attitude, attitude) || other.attitude == attitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,messageId,senderId,sender,symbol,attitude);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatReaction(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, messageId: $messageId, senderId: $senderId, sender: $sender, symbol: $symbol, attitude: $attitude)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnChatReactionCopyWith<$Res> implements $SnChatReactionCopyWith<$Res> {
|
||||||
|
factory _$SnChatReactionCopyWith(_SnChatReaction value, $Res Function(_SnChatReaction) _then) = __$SnChatReactionCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, String messageId, String senderId, SnChatMember sender, String symbol, int attitude
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $SnChatMemberCopyWith<$Res> get sender;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnChatReactionCopyWithImpl<$Res>
|
||||||
|
implements _$SnChatReactionCopyWith<$Res> {
|
||||||
|
__$SnChatReactionCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnChatReaction _self;
|
||||||
|
final $Res Function(_SnChatReaction) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? messageId = null,Object? senderId = null,Object? sender = null,Object? symbol = null,Object? attitude = null,}) {
|
||||||
|
return _then(_SnChatReaction(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,messageId: null == messageId ? _self.messageId : messageId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,senderId: null == senderId ? _self.senderId : senderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,sender: null == sender ? _self.sender : sender // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SnChatMember,symbol: null == symbol ? _self.symbol : symbol // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,attitude: null == attitude ? _self.attitude : attitude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of SnChatReaction
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMemberCopyWith<$Res> get sender {
|
||||||
|
|
||||||
|
return $SnChatMemberCopyWith<$Res>(_self.sender, (value) {
|
||||||
|
return _then(_self.copyWith(sender: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SnChatMember {
|
||||||
|
|
||||||
|
DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt; String get id; int get chatRoomId; int get accountId; String? get nick; int get role; int get notify; DateTime? get joinedAt; bool get isBot;
|
||||||
|
/// Create a copy of SnChatMember
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SnChatMemberCopyWith<SnChatMember> get copyWith => _$SnChatMemberCopyWithImpl<SnChatMember>(this as SnChatMember, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SnChatMember to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.isBot, isBot) || other.isBot == isBot));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,accountId,nick,role,notify,joinedAt,isBot);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, accountId: $accountId, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, isBot: $isBot)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SnChatMemberCopyWith<$Res> {
|
||||||
|
factory $SnChatMemberCopyWith(SnChatMember value, $Res Function(SnChatMember) _then) = _$SnChatMemberCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, int chatRoomId, int accountId, String? nick, int role, int notify, DateTime? joinedAt, bool isBot
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$SnChatMemberCopyWithImpl<$Res>
|
||||||
|
implements $SnChatMemberCopyWith<$Res> {
|
||||||
|
_$SnChatMemberCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SnChatMember _self;
|
||||||
|
final $Res Function(SnChatMember) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMember
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? accountId = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? isBot = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,chatRoomId: null == chatRoomId ? _self.chatRoomId : chatRoomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,nick: freezed == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,notify: null == notify ? _self.notify : notify // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,isBot: null == isBot ? _self.isBot : isBot // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _SnChatMember implements SnChatMember {
|
||||||
|
const _SnChatMember({required this.createdAt, required this.updatedAt, required this.deletedAt, required this.id, required this.chatRoomId, required this.accountId, required this.nick, required this.role, required this.notify, required this.joinedAt, required this.isBot});
|
||||||
|
factory _SnChatMember.fromJson(Map<String, dynamic> json) => _$SnChatMemberFromJson(json);
|
||||||
|
|
||||||
|
@override final DateTime createdAt;
|
||||||
|
@override final DateTime updatedAt;
|
||||||
|
@override final DateTime? deletedAt;
|
||||||
|
@override final String id;
|
||||||
|
@override final int chatRoomId;
|
||||||
|
@override final int accountId;
|
||||||
|
@override final String? nick;
|
||||||
|
@override final int role;
|
||||||
|
@override final int notify;
|
||||||
|
@override final DateTime? joinedAt;
|
||||||
|
@override final bool isBot;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMember
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SnChatMemberCopyWith<_SnChatMember> get copyWith => __$SnChatMemberCopyWithImpl<_SnChatMember>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SnChatMemberToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnChatMember&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt)&&(identical(other.id, id) || other.id == id)&&(identical(other.chatRoomId, chatRoomId) || other.chatRoomId == chatRoomId)&&(identical(other.accountId, accountId) || other.accountId == accountId)&&(identical(other.nick, nick) || other.nick == nick)&&(identical(other.role, role) || other.role == role)&&(identical(other.notify, notify) || other.notify == notify)&&(identical(other.joinedAt, joinedAt) || other.joinedAt == joinedAt)&&(identical(other.isBot, isBot) || other.isBot == isBot));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,createdAt,updatedAt,deletedAt,id,chatRoomId,accountId,nick,role,notify,joinedAt,isBot);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SnChatMember(createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, id: $id, chatRoomId: $chatRoomId, accountId: $accountId, nick: $nick, role: $role, notify: $notify, joinedAt: $joinedAt, isBot: $isBot)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SnChatMemberCopyWith<$Res> implements $SnChatMemberCopyWith<$Res> {
|
||||||
|
factory _$SnChatMemberCopyWith(_SnChatMember value, $Res Function(_SnChatMember) _then) = __$SnChatMemberCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
DateTime createdAt, DateTime updatedAt, DateTime? deletedAt, String id, int chatRoomId, int accountId, String? nick, int role, int notify, DateTime? joinedAt, bool isBot
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SnChatMemberCopyWithImpl<$Res>
|
||||||
|
implements _$SnChatMemberCopyWith<$Res> {
|
||||||
|
__$SnChatMemberCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SnChatMember _self;
|
||||||
|
final $Res Function(_SnChatMember) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SnChatMember
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,Object? id = null,Object? chatRoomId = null,Object? accountId = null,Object? nick = freezed,Object? role = null,Object? notify = null,Object? joinedAt = freezed,Object? isBot = null,}) {
|
||||||
|
return _then(_SnChatMember(
|
||||||
|
createdAt: null == createdAt ? _self.createdAt : createdAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime,deletedAt: freezed == deletedAt ? _self.deletedAt : deletedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,chatRoomId: null == chatRoomId ? _self.chatRoomId : chatRoomId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,accountId: null == accountId ? _self.accountId : accountId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,nick: freezed == nick ? _self.nick : nick // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,notify: null == notify ? _self.notify : notify // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,joinedAt: freezed == joinedAt ? _self.joinedAt : joinedAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,isBot: null == isBot ? _self.isBot : isBot // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
@ -47,3 +47,140 @@ Map<String, dynamic> _$SnChatToJson(_SnChat instance) => <String, dynamic>{
|
|||||||
'updated_at': instance.updatedAt.toIso8601String(),
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
'deleted_at': instance.deletedAt?.toIso8601String(),
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_SnChatMessage _$SnChatMessageFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SnChatMessage(
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt:
|
||||||
|
json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
id: json['id'] as String,
|
||||||
|
content: json['content'] as String?,
|
||||||
|
nonce: json['nonce'] as String?,
|
||||||
|
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
||||||
|
membersMetioned:
|
||||||
|
(json['members_metioned'] as List<dynamic>?)
|
||||||
|
?.map((e) => e as String)
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
editedAt:
|
||||||
|
json['edited_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['edited_at'] as String),
|
||||||
|
attachments:
|
||||||
|
(json['attachments'] as List<dynamic>?)
|
||||||
|
?.map((e) => SnCloudFile.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
reactions:
|
||||||
|
(json['reactions'] as List<dynamic>?)
|
||||||
|
?.map((e) => SnChatReaction.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList() ??
|
||||||
|
const [],
|
||||||
|
repliedMessageId: json['replied_message_id'] as String?,
|
||||||
|
repliedMessage:
|
||||||
|
json['replied_message'] == null
|
||||||
|
? null
|
||||||
|
: SnChatMessage.fromJson(
|
||||||
|
json['replied_message'] as Map<String, dynamic>,
|
||||||
|
),
|
||||||
|
forwardedMessageId: json['forwarded_message_id'] as String?,
|
||||||
|
forwardedMessage:
|
||||||
|
json['forwarded_message'] == null
|
||||||
|
? null
|
||||||
|
: SnChatMessage.fromJson(
|
||||||
|
json['forwarded_message'] as Map<String, dynamic>,
|
||||||
|
),
|
||||||
|
senderId: json['sender_id'] as String,
|
||||||
|
sender: SnChatMember.fromJson(json['sender'] as Map<String, dynamic>),
|
||||||
|
chatRoomId: (json['chat_room_id'] as num).toInt(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnChatMessageToJson(_SnChatMessage instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'id': instance.id,
|
||||||
|
'content': instance.content,
|
||||||
|
'nonce': instance.nonce,
|
||||||
|
'meta': instance.meta,
|
||||||
|
'members_metioned': instance.membersMetioned,
|
||||||
|
'edited_at': instance.editedAt?.toIso8601String(),
|
||||||
|
'attachments': instance.attachments.map((e) => e.toJson()).toList(),
|
||||||
|
'reactions': instance.reactions.map((e) => e.toJson()).toList(),
|
||||||
|
'replied_message_id': instance.repliedMessageId,
|
||||||
|
'replied_message': instance.repliedMessage?.toJson(),
|
||||||
|
'forwarded_message_id': instance.forwardedMessageId,
|
||||||
|
'forwarded_message': instance.forwardedMessage?.toJson(),
|
||||||
|
'sender_id': instance.senderId,
|
||||||
|
'sender': instance.sender.toJson(),
|
||||||
|
'chat_room_id': instance.chatRoomId,
|
||||||
|
};
|
||||||
|
|
||||||
|
_SnChatReaction _$SnChatReactionFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SnChatReaction(
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt:
|
||||||
|
json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
id: json['id'] as String,
|
||||||
|
messageId: json['message_id'] as String,
|
||||||
|
senderId: json['sender_id'] as String,
|
||||||
|
sender: SnChatMember.fromJson(json['sender'] as Map<String, dynamic>),
|
||||||
|
symbol: json['symbol'] as String,
|
||||||
|
attitude: (json['attitude'] as num).toInt(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnChatReactionToJson(_SnChatReaction instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'id': instance.id,
|
||||||
|
'message_id': instance.messageId,
|
||||||
|
'sender_id': instance.senderId,
|
||||||
|
'sender': instance.sender.toJson(),
|
||||||
|
'symbol': instance.symbol,
|
||||||
|
'attitude': instance.attitude,
|
||||||
|
};
|
||||||
|
|
||||||
|
_SnChatMember _$SnChatMemberFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SnChatMember(
|
||||||
|
createdAt: DateTime.parse(json['created_at'] as String),
|
||||||
|
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||||
|
deletedAt:
|
||||||
|
json['deleted_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['deleted_at'] as String),
|
||||||
|
id: json['id'] as String,
|
||||||
|
chatRoomId: (json['chat_room_id'] as num).toInt(),
|
||||||
|
accountId: (json['account_id'] as num).toInt(),
|
||||||
|
nick: json['nick'] as String?,
|
||||||
|
role: (json['role'] as num).toInt(),
|
||||||
|
notify: (json['notify'] as num).toInt(),
|
||||||
|
joinedAt:
|
||||||
|
json['joined_at'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['joined_at'] as String),
|
||||||
|
isBot: json['is_bot'] as bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SnChatMemberToJson(_SnChatMember instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'created_at': instance.createdAt.toIso8601String(),
|
||||||
|
'updated_at': instance.updatedAt.toIso8601String(),
|
||||||
|
'deleted_at': instance.deletedAt?.toIso8601String(),
|
||||||
|
'id': instance.id,
|
||||||
|
'chat_room_id': instance.chatRoomId,
|
||||||
|
'account_id': instance.accountId,
|
||||||
|
'nick': instance.nick,
|
||||||
|
'role': instance.role,
|
||||||
|
'notify': instance.notify,
|
||||||
|
'joined_at': instance.joinedAt?.toIso8601String(),
|
||||||
|
'is_bot': instance.isBot,
|
||||||
|
};
|
||||||
|
100
lib/pods/message.dart
Normal file
100
lib/pods/message.dart
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/database/drift_db.dart';
|
||||||
|
import 'package:island/database/message.dart';
|
||||||
|
import 'package:island/database/message_repository.dart';
|
||||||
|
import 'package:island/models/chat.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/alert.dart';
|
||||||
|
|
||||||
|
// Global database instance
|
||||||
|
final databaseProvider = Provider<AppDatabase>((ref) {
|
||||||
|
final db = AppDatabase();
|
||||||
|
ref.onDispose(() => db.close());
|
||||||
|
return db;
|
||||||
|
});
|
||||||
|
|
||||||
|
final messageRepositoryProvider =
|
||||||
|
FutureProvider.family<MessageRepository, SnChat>((ref, chat) async {
|
||||||
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
|
final database = ref.watch(databaseProvider);
|
||||||
|
return MessageRepository(chat, apiClient, database);
|
||||||
|
});
|
||||||
|
|
||||||
|
final chatMessagesProvider =
|
||||||
|
FutureProvider.family<List<LocalChatMessage>, SnChat>((ref, room) async {
|
||||||
|
final repository = await ref.watch(
|
||||||
|
messageRepositoryProvider(room).future,
|
||||||
|
);
|
||||||
|
return repository.listMessages();
|
||||||
|
});
|
||||||
|
|
||||||
|
class ChatMessageNotifier
|
||||||
|
extends StateNotifier<AsyncValue<List<LocalChatMessage>>> {
|
||||||
|
final MessageRepository _repository;
|
||||||
|
final int roomId;
|
||||||
|
int _currentOffset = 0;
|
||||||
|
final int _pageSize = 20;
|
||||||
|
bool _hasMore = true;
|
||||||
|
|
||||||
|
ChatMessageNotifier(this._repository, this.roomId)
|
||||||
|
: super(const AsyncValue.loading()) {
|
||||||
|
loadInitial();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadInitial() async {
|
||||||
|
state = const AsyncValue.loading();
|
||||||
|
try {
|
||||||
|
final messages = await _repository.listMessages(
|
||||||
|
offset: 0,
|
||||||
|
take: _pageSize,
|
||||||
|
);
|
||||||
|
_currentOffset = messages.length;
|
||||||
|
_hasMore = messages.length >= _pageSize;
|
||||||
|
state = AsyncValue.data(messages);
|
||||||
|
} catch (e, stack) {
|
||||||
|
state = AsyncValue.error(e, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadMore() async {
|
||||||
|
if (!_hasMore) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final newMessages = await _repository.listMessages(
|
||||||
|
offset: _currentOffset,
|
||||||
|
take: _pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newMessages.isEmpty) {
|
||||||
|
_hasMore = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentOffset += newMessages.length;
|
||||||
|
_hasMore = newMessages.length >= _pageSize;
|
||||||
|
|
||||||
|
state = AsyncValue.data([...state.value ?? [], ...newMessages]);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> sendMessage(String content) async {
|
||||||
|
try {
|
||||||
|
final message = await _repository.sendMessage(roomId, content);
|
||||||
|
|
||||||
|
final currentMessages = state.value ?? [];
|
||||||
|
state = AsyncValue.data([message, ...currentMessages]);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get hasMore => _hasMore;
|
||||||
|
}
|
||||||
|
|
||||||
|
final chatMessageNotifierProvider = StateNotifierProvider.family<
|
||||||
|
ChatMessageNotifier,
|
||||||
|
AsyncValue<List<LocalChatMessage>>,
|
||||||
|
MessageRepository
|
||||||
|
>((ref, repository) => ChatMessageNotifier(repository, repository.room.id));
|
@ -4,11 +4,123 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:island/database/message.dart';
|
||||||
|
import 'package:island/database/message_repository.dart';
|
||||||
|
import 'package:island/pods/message.dart';
|
||||||
|
import 'package:island/pods/network.dart';
|
||||||
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'chat.dart';
|
import 'chat.dart';
|
||||||
|
|
||||||
|
final messageRepositoryProvider = FutureProvider.family<MessageRepository, int>(
|
||||||
|
(ref, roomId) async {
|
||||||
|
final room = ref.watch(chatroomProvider(roomId)).value;
|
||||||
|
final apiClient = ref.watch(apiClientProvider);
|
||||||
|
final database = ref.watch(databaseProvider);
|
||||||
|
return MessageRepository(room!, apiClient, database);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Provider for messages with pagination
|
||||||
|
final messagesProvider = StateNotifierProvider.family<
|
||||||
|
MessagesNotifier,
|
||||||
|
AsyncValue<List<LocalChatMessage>>,
|
||||||
|
int
|
||||||
|
>((ref, roomId) => MessagesNotifier(ref, roomId));
|
||||||
|
|
||||||
|
class MessagesNotifier
|
||||||
|
extends StateNotifier<AsyncValue<List<LocalChatMessage>>> {
|
||||||
|
final Ref _ref;
|
||||||
|
final int _roomId;
|
||||||
|
int _currentPage = 0;
|
||||||
|
static const int _pageSize = 20;
|
||||||
|
bool _hasMore = true;
|
||||||
|
|
||||||
|
MessagesNotifier(this._ref, this._roomId)
|
||||||
|
: super(const AsyncValue.loading()) {
|
||||||
|
loadInitial();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadInitial() async {
|
||||||
|
try {
|
||||||
|
final repository = await _ref.read(
|
||||||
|
messageRepositoryProvider(_roomId).future,
|
||||||
|
);
|
||||||
|
final messages = await repository.listMessages(
|
||||||
|
offset: 0,
|
||||||
|
take: _pageSize,
|
||||||
|
);
|
||||||
|
state = AsyncValue.data(messages);
|
||||||
|
_currentPage = 0;
|
||||||
|
_hasMore = messages.length == _pageSize;
|
||||||
|
} catch (e, stack) {
|
||||||
|
state = AsyncValue.error(e, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadMore() async {
|
||||||
|
if (!_hasMore || state is AsyncLoading) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final currentMessages = state.value ?? [];
|
||||||
|
_currentPage++;
|
||||||
|
final repository = await _ref.read(
|
||||||
|
messageRepositoryProvider(_roomId).future,
|
||||||
|
);
|
||||||
|
final newMessages = await repository.listMessages(
|
||||||
|
offset: _currentPage * _pageSize,
|
||||||
|
take: _pageSize,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newMessages.isEmpty || newMessages.length < _pageSize) {
|
||||||
|
_hasMore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = AsyncValue.data([...currentMessages, ...newMessages]);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
_currentPage--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> sendMessage(String content) async {
|
||||||
|
try {
|
||||||
|
final repository = await _ref.read(
|
||||||
|
messageRepositoryProvider(_roomId).future,
|
||||||
|
);
|
||||||
|
final message = await repository.sendMessage(_roomId, content);
|
||||||
|
|
||||||
|
// Add the new message to the list
|
||||||
|
final currentMessages = state.value ?? [];
|
||||||
|
state = AsyncValue.data([message, ...currentMessages]);
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> retryMessage(String pendingMessageId) async {
|
||||||
|
try {
|
||||||
|
final repository = await _ref.read(
|
||||||
|
messageRepositoryProvider(_roomId).future,
|
||||||
|
);
|
||||||
|
final updatedMessage = await repository.retryMessage(pendingMessageId);
|
||||||
|
|
||||||
|
// Update the message in the list
|
||||||
|
final currentMessages = state.value ?? [];
|
||||||
|
final index = currentMessages.indexWhere((m) => m.id == pendingMessageId);
|
||||||
|
if (index >= 0) {
|
||||||
|
final newList = [...currentMessages];
|
||||||
|
newList[index] = updatedMessage;
|
||||||
|
state = AsyncValue.data(newList);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
showErrorAlert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class ChatRoomScreen extends HookConsumerWidget {
|
class ChatRoomScreen extends HookConsumerWidget {
|
||||||
final int id;
|
final int id;
|
||||||
@ -17,8 +129,24 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final chatRoom = ref.watch(chatroomProvider(id));
|
final chatRoom = ref.watch(chatroomProvider(id));
|
||||||
|
final messages = ref.watch(messagesProvider(id));
|
||||||
|
final messagesNotifier = ref.read(messagesProvider(id).notifier);
|
||||||
|
|
||||||
final messageController = useTextEditingController();
|
final messageController = useTextEditingController();
|
||||||
|
final scrollController = useScrollController();
|
||||||
|
|
||||||
|
// Add scroll listener for pagination
|
||||||
|
useEffect(() {
|
||||||
|
void onScroll() {
|
||||||
|
if (scrollController.position.pixels >=
|
||||||
|
scrollController.position.maxScrollExtent - 200) {
|
||||||
|
messagesNotifier.loadMore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollController.addListener(onScroll);
|
||||||
|
return () => scrollController.removeListener(onScroll);
|
||||||
|
}, [scrollController]);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@ -59,10 +187,34 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: chatRoom.when(
|
child: messages.when(
|
||||||
data: (room) => SizedBox.expand(),
|
data:
|
||||||
|
(messageList) =>
|
||||||
|
messageList.isEmpty
|
||||||
|
? Center(child: Text('No messages yet'.tr()))
|
||||||
|
: ListView.builder(
|
||||||
|
controller: scrollController,
|
||||||
|
reverse: true, // Show newest messages at the bottom
|
||||||
|
itemCount: messageList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final message = messageList[index];
|
||||||
|
return MessageBubble(message: message);
|
||||||
|
},
|
||||||
|
),
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
error: (error, stack) => Center(child: Text('Error: $error')),
|
error:
|
||||||
|
(error, stack) => Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text('Error: $error'),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () => messagesNotifier.loadInitial(),
|
||||||
|
child: Text('Retry'.tr()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Material(
|
Material(
|
||||||
@ -105,7 +257,14 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.send),
|
icon: const Icon(Icons.send),
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
if (messageController.text.trim().isNotEmpty) {
|
||||||
|
messagesNotifier.sendMessage(
|
||||||
|
messageController.text.trim(),
|
||||||
|
);
|
||||||
|
messageController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).padding(bottom: MediaQuery.of(context).padding.bottom),
|
).padding(bottom: MediaQuery.of(context).padding.bottom),
|
||||||
@ -116,3 +275,99 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MessageBubble extends StatelessWidget {
|
||||||
|
final LocalChatMessage message;
|
||||||
|
|
||||||
|
const MessageBubble({Key? key, required this.message}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final isCurrentUser =
|
||||||
|
message.senderId == 'current_user_id'; // Replace with actual check
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
isCurrentUser ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
if (!isCurrentUser)
|
||||||
|
CircleAvatar(
|
||||||
|
radius: 16,
|
||||||
|
child: Text(message.senderId[0].toUpperCase()),
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color:
|
||||||
|
isCurrentUser
|
||||||
|
? Theme.of(context).colorScheme.primary.withOpacity(0.8)
|
||||||
|
: Colors.grey.shade200,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
message.toRemoteMessage().content ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
color: isCurrentUser ? Colors.white : Colors.black,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
DateFormat.Hm().format(message.createdAt),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color:
|
||||||
|
isCurrentUser ? Colors.white70 : Colors.black54,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(4),
|
||||||
|
if (isCurrentUser)
|
||||||
|
_buildStatusIcon(context, message.status),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Gap(8),
|
||||||
|
if (isCurrentUser)
|
||||||
|
const SizedBox(width: 32), // Balance with avatar on the other side
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStatusIcon(BuildContext context, MessageStatus status) {
|
||||||
|
switch (status) {
|
||||||
|
case MessageStatus.pending:
|
||||||
|
return const Icon(Icons.access_time, size: 12, color: Colors.white70);
|
||||||
|
case MessageStatus.sent:
|
||||||
|
return const Icon(Icons.check, size: 12, color: Colors.white70);
|
||||||
|
case MessageStatus.failed:
|
||||||
|
return Consumer(
|
||||||
|
builder:
|
||||||
|
(context, ref, _) => GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
ref
|
||||||
|
.read(messagesProvider(message.roomId).notifier)
|
||||||
|
.retryMessage(message.id);
|
||||||
|
},
|
||||||
|
child: const Icon(
|
||||||
|
Icons.error_outline,
|
||||||
|
size: 12,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <irondash_engine_context/irondash_engine_context_plugin.h>
|
#include <irondash_engine_context/irondash_engine_context_plugin.h>
|
||||||
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin.h>
|
#include <media_kit_video/media_kit_video_plugin.h>
|
||||||
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <super_native_extensions/super_native_extensions_plugin.h>
|
#include <super_native_extensions/super_native_extensions_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
@ -38,6 +39,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
|
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
|
||||||
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
|
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
|
||||||
|
sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) super_native_extensions_registrar =
|
g_autoptr(FlPluginRegistrar) super_native_extensions_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin");
|
||||||
super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar);
|
super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar);
|
||||||
|
@ -10,6 +10,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
irondash_engine_context
|
irondash_engine_context
|
||||||
media_kit_libs_linux
|
media_kit_libs_linux
|
||||||
media_kit_video
|
media_kit_video
|
||||||
|
sqlite3_flutter_libs
|
||||||
super_native_extensions
|
super_native_extensions
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
@ -22,6 +22,7 @@ import path_provider_foundation
|
|||||||
import quill_native_bridge_macos
|
import quill_native_bridge_macos
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite_darwin
|
import sqflite_darwin
|
||||||
|
import sqlite3_flutter_libs
|
||||||
import super_native_extensions
|
import super_native_extensions
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
import volume_controller
|
import volume_controller
|
||||||
@ -45,6 +46,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin"))
|
QuillNativeBridgePlugin.register(with: registry.registrar(forPlugin: "QuillNativeBridgePlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
|
||||||
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
|
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin"))
|
VolumeControllerPlugin.register(with: registry.registrar(forPlugin: "VolumeControllerPlugin"))
|
||||||
|
58
pubspec.lock
58
pubspec.lock
@ -425,6 +425,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
drift:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: drift
|
||||||
|
sha256: "14a61af39d4584faf1d73b5b35e4b758a43008cf4c0fdb0576ec8e7032c0d9a5"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.26.0"
|
||||||
|
drift_dev:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: drift_dev
|
||||||
|
sha256: "0d3f8b33b76cf1c6a82ee34d9511c40957549c4674b8f1688609e6d6c7306588"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.26.0"
|
||||||
|
drift_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: drift_flutter
|
||||||
|
sha256: "0cadbf3b8733409a6cf61d18ba2e94e149df81df7de26f48ae0695b48fd71922"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.4"
|
||||||
easy_localization:
|
easy_localization:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1270,7 +1294,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||||
@ -1477,6 +1501,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.2"
|
version: "3.2.2"
|
||||||
|
recase:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: recase
|
||||||
|
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
responsive_framework:
|
responsive_framework:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -1714,6 +1746,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.0"
|
||||||
|
sqlite3:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlite3
|
||||||
|
sha256: "310af39c40dd0bb2058538333c9d9840a2725ae0b9f77e4fd09ad6696aa8f66e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.5"
|
||||||
|
sqlite3_flutter_libs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlite3_flutter_libs
|
||||||
|
sha256: "1a96b59227828d9eb1463191d684b37a27d66ee5ed7597fcf42eee6452c88a14"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.32"
|
||||||
|
sqlparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlparser
|
||||||
|
sha256: "27dd0a9f0c02e22ac0eb42a23df9ea079ce69b52bb4a3b478d64e0ef34a263ee"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.41.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -85,6 +85,9 @@ dependencies:
|
|||||||
web_socket_channel: ^3.0.3
|
web_socket_channel: ^3.0.3
|
||||||
flutter_quill: ^11.4.0
|
flutter_quill: ^11.4.0
|
||||||
material_symbols_icons: ^4.2815.0
|
material_symbols_icons: ^4.2815.0
|
||||||
|
drift: ^2.26.0
|
||||||
|
drift_flutter: ^0.2.4
|
||||||
|
path: ^1.9.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -103,6 +106,7 @@ dev_dependencies:
|
|||||||
riverpod_generator: ^2.6.5
|
riverpod_generator: ^2.6.5
|
||||||
custom_lint: ^0.7.5
|
custom_lint: ^0.7.5
|
||||||
riverpod_lint: ^2.6.5
|
riverpod_lint: ^2.6.5
|
||||||
|
drift_dev: ^2.26.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <irondash_engine_context/irondash_engine_context_plugin_c_api.h>
|
#include <irondash_engine_context/irondash_engine_context_plugin_c_api.h>
|
||||||
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
|
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
|
||||||
#include <media_kit_video/media_kit_video_plugin_c_api.h>
|
#include <media_kit_video/media_kit_video_plugin_c_api.h>
|
||||||
|
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
|
||||||
#include <super_native_extensions/super_native_extensions_plugin_c_api.h>
|
#include <super_native_extensions/super_native_extensions_plugin_c_api.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
#include <volume_controller/volume_controller_plugin_c_api.h>
|
#include <volume_controller/volume_controller_plugin_c_api.h>
|
||||||
@ -38,6 +39,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi"));
|
registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi"));
|
||||||
MediaKitVideoPluginCApiRegisterWithRegistrar(
|
MediaKitVideoPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi"));
|
registry->GetRegistrarForPlugin("MediaKitVideoPluginCApi"));
|
||||||
|
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin"));
|
||||||
SuperNativeExtensionsPluginCApiRegisterWithRegistrar(
|
SuperNativeExtensionsPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi"));
|
registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
|
@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
|||||||
irondash_engine_context
|
irondash_engine_context
|
||||||
media_kit_libs_windows_video
|
media_kit_libs_windows_video
|
||||||
media_kit_video
|
media_kit_video
|
||||||
|
sqlite3_flutter_libs
|
||||||
super_native_extensions
|
super_native_extensions
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
volume_controller
|
volume_controller
|
||||||
|
Loading…
x
Reference in New Issue
Block a user