From 3e75d90c6a5d39fe5d932711c68fad3116107eee Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 12:45:29 +0900 Subject: [PATCH 01/15] feat: membership --- lib/account/account_server.dart | 4 +- lib/db/converter/membership_converter.dart | 29 +++++++++ lib/db/dao/user_dao.dart | 1 + lib/db/mixin_database.dart | 6 +- lib/db/mixin_database.g.dart | 63 +++++++++++++++++++ lib/db/moor/mixin.drift | 3 +- .../device_transfer/transfer_data_user.dart | 6 ++ pubspec.lock | 9 ++- pubspec.yaml | 19 +++--- 9 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 lib/db/converter/membership_converter.dart diff --git a/lib/account/account_server.dart b/lib/account/account_server.dart index fd357d924d..644583f066 100644 --- a/lib/account/account_server.dart +++ b/lib/account/account_server.dart @@ -745,8 +745,7 @@ class AccountServer { await database.userDao.insert(db.User( userId: me.userId, identityNumber: me.identityNumber, - relationship: - const UserRelationshipJsonConverter().fromJson(me.relationship), + relationship: me.relationship, fullName: me.fullName, avatarUrl: me.avatarUrl, phone: me.phone, @@ -757,6 +756,7 @@ class AccountServer { isScam: me.isScam ? 1 : 0, codeId: me.codeId, codeUrl: me.codeUrl, + membership: me.membership, )); multiAuthNotifier.updateAccount(me); } diff --git a/lib/db/converter/membership_converter.dart b/lib/db/converter/membership_converter.dart new file mode 100644 index 0000000000..77e6a917be --- /dev/null +++ b/lib/db/converter/membership_converter.dart @@ -0,0 +1,29 @@ +import 'dart:convert'; + +import 'package:drift/drift.dart'; +import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; +import 'package:mixin_logger/mixin_logger.dart'; + +class MembershipConverter extends TypeConverter { + @override + Membership? fromSql(String? fromDb) { + if (fromDb == null) { + return null; + } + try { + final json = jsonDecode(fromDb) as Map; + return Membership.fromJson(json); + } catch (error, stackTrace) { + e('failed to decode membership', error, stackTrace); + return null; + } + } + + @override + String? toSql(Membership? value) { + if (value == null) { + return null; + } + return jsonEncode(value.toJson()); + } +} diff --git a/lib/db/dao/user_dao.dart b/lib/db/dao/user_dao.dart index 169a794898..63da698e75 100644 --- a/lib/db/dao/user_dao.dart +++ b/lib/db/dao/user_dao.dart @@ -27,6 +27,7 @@ extension UserExtension on sdk.User { codeId: codeId, codeUrl: codeUrl, isDeactivated: isDeactivated, + membership: membership, ); } diff --git a/lib/db/mixin_database.dart b/lib/db/mixin_database.dart index c9003f908e..7e15466621 100644 --- a/lib/db/mixin_database.dart +++ b/lib/db/mixin_database.dart @@ -9,6 +9,7 @@ import '../enum/property_group.dart'; import 'converter/conversation_category_type_converter.dart'; import 'converter/conversation_status_type_converter.dart'; import 'converter/media_status_type_converter.dart'; +import 'converter/membership_converter.dart'; import 'converter/message_status_type_converter.dart'; import 'converter/millis_date_converter.dart'; import 'converter/participant_role_converter.dart'; @@ -101,7 +102,7 @@ class MixinDatabase extends _$MixinDatabase { MixinDatabase(super.e); @override - int get schemaVersion => 26; + int get schemaVersion => 27; final eventBus = DataBaseEventBus.instance; @@ -251,6 +252,9 @@ class MixinDatabase extends _$MixinDatabase { await m.createTable(inscriptionCollections); await m.createTable(inscriptionItems); } + if (from <= 26) { + await _addColumnIfNotExists(m, users, users.membership); + } }, beforeOpen: (details) async { if (details.hadUpgrade && details.versionBefore! <= 20) { diff --git a/lib/db/mixin_database.g.dart b/lib/db/mixin_database.g.dart index 855fbc09bb..d3dd686f71 100644 --- a/lib/db/mixin_database.g.dart +++ b/lib/db/mixin_database.g.dart @@ -2408,6 +2408,14 @@ class Users extends Table with TableInfo { requiredDuringInsert: false, $customConstraints: '') .withConverter(Users.$converterrelationship); + static const VerificationMeta _membershipMeta = + const VerificationMeta('membership'); + late final GeneratedColumnWithTypeConverter membership = + GeneratedColumn('membership', aliasedName, true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: '') + .withConverter(Users.$convertermembership); static const VerificationMeta _fullNameMeta = const VerificationMeta('fullName'); late final GeneratedColumn fullName = GeneratedColumn( @@ -2501,6 +2509,7 @@ class Users extends Table with TableInfo { userId, identityNumber, relationship, + membership, fullName, avatarUrl, phone, @@ -2540,6 +2549,7 @@ class Users extends Table with TableInfo { context.missing(_identityNumberMeta); } context.handle(_relationshipMeta, const VerificationResult.success()); + context.handle(_membershipMeta, const VerificationResult.success()); if (data.containsKey('full_name')) { context.handle(_fullNameMeta, fullName.isAcceptableOrUnknown(data['full_name']!, _fullNameMeta)); @@ -2606,6 +2616,9 @@ class Users extends Table with TableInfo { relationship: Users.$converterrelationship.fromSql(attachedDatabase .typeMapping .read(DriftSqlType.string, data['${effectivePrefix}relationship'])), + membership: Users.$convertermembership.fromSql(attachedDatabase + .typeMapping + .read(DriftSqlType.string, data['${effectivePrefix}membership'])), fullName: attachedDatabase.typeMapping .read(DriftSqlType.string, data['${effectivePrefix}full_name']), avatarUrl: attachedDatabase.typeMapping @@ -2642,6 +2655,8 @@ class Users extends Table with TableInfo { static TypeConverter $converterrelationship = const UserRelationshipConverter(); + static TypeConverter $convertermembership = + const MembershipConverter(); static TypeConverter $convertercreatedAt = const MillisDateConverter(); static TypeConverter $convertercreatedAtn = @@ -2660,6 +2675,7 @@ class User extends DataClass implements Insertable { final String userId; final String identityNumber; final UserRelationship? relationship; + final Membership? membership; final String? fullName; final String? avatarUrl; final String? phone; @@ -2677,6 +2693,7 @@ class User extends DataClass implements Insertable { {required this.userId, required this.identityNumber, this.relationship, + this.membership, this.fullName, this.avatarUrl, this.phone, @@ -2699,6 +2716,10 @@ class User extends DataClass implements Insertable { map['relationship'] = Variable(Users.$converterrelationship.toSql(relationship)); } + if (!nullToAbsent || membership != null) { + map['membership'] = + Variable(Users.$convertermembership.toSql(membership)); + } if (!nullToAbsent || fullName != null) { map['full_name'] = Variable(fullName); } @@ -2750,6 +2771,9 @@ class User extends DataClass implements Insertable { relationship: relationship == null && nullToAbsent ? const Value.absent() : Value(relationship), + membership: membership == null && nullToAbsent + ? const Value.absent() + : Value(membership), fullName: fullName == null && nullToAbsent ? const Value.absent() : Value(fullName), @@ -2795,6 +2819,7 @@ class User extends DataClass implements Insertable { identityNumber: serializer.fromJson(json['identity_number']), relationship: serializer.fromJson(json['relationship']), + membership: serializer.fromJson(json['membership']), fullName: serializer.fromJson(json['full_name']), avatarUrl: serializer.fromJson(json['avatar_url']), phone: serializer.fromJson(json['phone']), @@ -2817,6 +2842,7 @@ class User extends DataClass implements Insertable { 'user_id': serializer.toJson(userId), 'identity_number': serializer.toJson(identityNumber), 'relationship': serializer.toJson(relationship), + 'membership': serializer.toJson(membership), 'full_name': serializer.toJson(fullName), 'avatar_url': serializer.toJson(avatarUrl), 'phone': serializer.toJson(phone), @@ -2837,6 +2863,7 @@ class User extends DataClass implements Insertable { {String? userId, String? identityNumber, Value relationship = const Value.absent(), + Value membership = const Value.absent(), Value fullName = const Value.absent(), Value avatarUrl = const Value.absent(), Value phone = const Value.absent(), @@ -2855,6 +2882,7 @@ class User extends DataClass implements Insertable { identityNumber: identityNumber ?? this.identityNumber, relationship: relationship.present ? relationship.value : this.relationship, + membership: membership.present ? membership.value : this.membership, fullName: fullName.present ? fullName.value : this.fullName, avatarUrl: avatarUrl.present ? avatarUrl.value : this.avatarUrl, phone: phone.present ? phone.value : this.phone, @@ -2879,6 +2907,8 @@ class User extends DataClass implements Insertable { relationship: data.relationship.present ? data.relationship.value : this.relationship, + membership: + data.membership.present ? data.membership.value : this.membership, fullName: data.fullName.present ? data.fullName.value : this.fullName, avatarUrl: data.avatarUrl.present ? data.avatarUrl.value : this.avatarUrl, phone: data.phone.present ? data.phone.value : this.phone, @@ -2904,6 +2934,7 @@ class User extends DataClass implements Insertable { ..write('userId: $userId, ') ..write('identityNumber: $identityNumber, ') ..write('relationship: $relationship, ') + ..write('membership: $membership, ') ..write('fullName: $fullName, ') ..write('avatarUrl: $avatarUrl, ') ..write('phone: $phone, ') @@ -2926,6 +2957,7 @@ class User extends DataClass implements Insertable { userId, identityNumber, relationship, + membership, fullName, avatarUrl, phone, @@ -2946,6 +2978,7 @@ class User extends DataClass implements Insertable { other.userId == this.userId && other.identityNumber == this.identityNumber && other.relationship == this.relationship && + other.membership == this.membership && other.fullName == this.fullName && other.avatarUrl == this.avatarUrl && other.phone == this.phone && @@ -2965,6 +2998,7 @@ class UsersCompanion extends UpdateCompanion { final Value userId; final Value identityNumber; final Value relationship; + final Value membership; final Value fullName; final Value avatarUrl; final Value phone; @@ -2983,6 +3017,7 @@ class UsersCompanion extends UpdateCompanion { this.userId = const Value.absent(), this.identityNumber = const Value.absent(), this.relationship = const Value.absent(), + this.membership = const Value.absent(), this.fullName = const Value.absent(), this.avatarUrl = const Value.absent(), this.phone = const Value.absent(), @@ -3002,6 +3037,7 @@ class UsersCompanion extends UpdateCompanion { required String userId, required String identityNumber, this.relationship = const Value.absent(), + this.membership = const Value.absent(), this.fullName = const Value.absent(), this.avatarUrl = const Value.absent(), this.phone = const Value.absent(), @@ -3022,6 +3058,7 @@ class UsersCompanion extends UpdateCompanion { Expression? userId, Expression? identityNumber, Expression? relationship, + Expression? membership, Expression? fullName, Expression? avatarUrl, Expression? phone, @@ -3041,6 +3078,7 @@ class UsersCompanion extends UpdateCompanion { if (userId != null) 'user_id': userId, if (identityNumber != null) 'identity_number': identityNumber, if (relationship != null) 'relationship': relationship, + if (membership != null) 'membership': membership, if (fullName != null) 'full_name': fullName, if (avatarUrl != null) 'avatar_url': avatarUrl, if (phone != null) 'phone': phone, @@ -3062,6 +3100,7 @@ class UsersCompanion extends UpdateCompanion { {Value? userId, Value? identityNumber, Value? relationship, + Value? membership, Value? fullName, Value? avatarUrl, Value? phone, @@ -3080,6 +3119,7 @@ class UsersCompanion extends UpdateCompanion { userId: userId ?? this.userId, identityNumber: identityNumber ?? this.identityNumber, relationship: relationship ?? this.relationship, + membership: membership ?? this.membership, fullName: fullName ?? this.fullName, avatarUrl: avatarUrl ?? this.avatarUrl, phone: phone ?? this.phone, @@ -3110,6 +3150,10 @@ class UsersCompanion extends UpdateCompanion { map['relationship'] = Variable( Users.$converterrelationship.toSql(relationship.value)); } + if (membership.present) { + map['membership'] = + Variable(Users.$convertermembership.toSql(membership.value)); + } if (fullName.present) { map['full_name'] = Variable(fullName.value); } @@ -3163,6 +3207,7 @@ class UsersCompanion extends UpdateCompanion { ..write('userId: $userId, ') ..write('identityNumber: $identityNumber, ') ..write('relationship: $relationship, ') + ..write('membership: $membership, ') ..write('fullName: $fullName, ') ..write('avatarUrl: $avatarUrl, ') ..write('phone: $phone, ') @@ -17556,6 +17601,7 @@ typedef $UsersCreateCompanionBuilder = UsersCompanion Function({ required String userId, required String identityNumber, Value relationship, + Value membership, Value fullName, Value avatarUrl, Value phone, @@ -17575,6 +17621,7 @@ typedef $UsersUpdateCompanionBuilder = UsersCompanion Function({ Value userId, Value identityNumber, Value relationship, + Value membership, Value fullName, Value avatarUrl, Value phone, @@ -17609,6 +17656,7 @@ class $UsersTableManager extends RootTableManager< Value userId = const Value.absent(), Value identityNumber = const Value.absent(), Value relationship = const Value.absent(), + Value membership = const Value.absent(), Value fullName = const Value.absent(), Value avatarUrl = const Value.absent(), Value phone = const Value.absent(), @@ -17628,6 +17676,7 @@ class $UsersTableManager extends RootTableManager< userId: userId, identityNumber: identityNumber, relationship: relationship, + membership: membership, fullName: fullName, avatarUrl: avatarUrl, phone: phone, @@ -17647,6 +17696,7 @@ class $UsersTableManager extends RootTableManager< required String userId, required String identityNumber, Value relationship = const Value.absent(), + Value membership = const Value.absent(), Value fullName = const Value.absent(), Value avatarUrl = const Value.absent(), Value phone = const Value.absent(), @@ -17666,6 +17716,7 @@ class $UsersTableManager extends RootTableManager< userId: userId, identityNumber: identityNumber, relationship: relationship, + membership: membership, fullName: fullName, avatarUrl: avatarUrl, phone: phone, @@ -17703,6 +17754,13 @@ class $UsersFilterComposer extends FilterComposer<_$MixinDatabase, Users> { column, joinBuilders: joinBuilders)); + ColumnWithTypeConverterFilters + get membership => $state.composableBuilder( + column: $state.table.membership, + builder: (column, joinBuilders) => ColumnWithTypeConverterFilters( + column, + joinBuilders: joinBuilders)); + ColumnFilters get fullName => $state.composableBuilder( column: $state.table.fullName, builder: (column, joinBuilders) => @@ -17790,6 +17848,11 @@ class $UsersOrderingComposer extends OrderingComposer<_$MixinDatabase, Users> { builder: (column, joinBuilders) => ColumnOrderings(column, joinBuilders: joinBuilders)); + ColumnOrderings get membership => $state.composableBuilder( + column: $state.table.membership, + builder: (column, joinBuilders) => + ColumnOrderings(column, joinBuilders: joinBuilders)); + ColumnOrderings get fullName => $state.composableBuilder( column: $state.table.fullName, builder: (column, joinBuilders) => diff --git a/lib/db/moor/mixin.drift b/lib/db/moor/mixin.drift index e48d6c2912..7738d9f5d0 100644 --- a/lib/db/moor/mixin.drift +++ b/lib/db/moor/mixin.drift @@ -4,6 +4,7 @@ import '../converter/conversation_status_type_converter.dart'; import '../converter/media_status_type_converter.dart'; import '../converter/message_status_type_converter.dart'; import '../converter/user_relationship_converter.dart'; +import '../converter/membership_converter.dart'; import '../converter/participant_role_converter.dart'; import '../converter/millis_date_converter.dart'; import '../converter/property_group_converter.dart'; @@ -56,7 +57,7 @@ CREATE TABLE sticker_relationships ( album_id TEXT NOT NULL, sticker_id TEXT NOT CREATE TABLE stickers ( sticker_id TEXT NOT NULL, album_id TEXT, name TEXT NOT NULL, asset_url TEXT NOT NULL, asset_type TEXT NOT NULL, asset_width INTEGER NOT NULL, asset_height INTEGER NOT NULL, created_at INTEGER NOT NULL MAPPED BY `const MillisDateConverter()`, last_use_at INTEGER MAPPED BY `const MillisDateConverter()`, PRIMARY KEY(sticker_id) ); -CREATE TABLE users ( user_id TEXT NOT NULL, identity_number TEXT NOT NULL, relationship TEXT MAPPED BY `const UserRelationshipConverter()`, full_name TEXT, avatar_url TEXT, phone TEXT, is_verified BOOLEAN, created_at INTEGER MAPPED BY `const MillisDateConverter()`, mute_until INTEGER MAPPED BY `const MillisDateConverter()`, has_pin INTEGER, app_id TEXT, biography TEXT, is_scam INTEGER, code_url TEXT, code_id TEXT, is_deactivated BOOLEAN, PRIMARY KEY(user_id) ); +CREATE TABLE users ( user_id TEXT NOT NULL, identity_number TEXT NOT NULL, relationship TEXT MAPPED BY `const UserRelationshipConverter()`, membership TEXT MAPPED BY `const MembershipConverter()`, full_name TEXT, avatar_url TEXT, phone TEXT, is_verified BOOLEAN, created_at INTEGER MAPPED BY `const MillisDateConverter()`, mute_until INTEGER MAPPED BY `const MillisDateConverter()`, has_pin INTEGER, app_id TEXT, biography TEXT, is_scam INTEGER, code_url TEXT, code_id TEXT, is_deactivated BOOLEAN, PRIMARY KEY(user_id) ); CREATE TABLE transcript_messages (transcript_id TEXT NOT NULL, message_id TEXT NOT NULL, user_id TEXT, user_full_name TEXT, category TEXT NOT NULL, created_at INTEGER NOT NULL MAPPED BY `const MillisDateConverter()`, content TEXT, media_url TEXT, media_name TEXT, media_size INTEGER, media_width INTEGER, media_height INTEGER, media_mime_type TEXT, media_duration TEXT, media_status TEXT MAPPED BY `const MediaStatusTypeConverter()`, media_waveform TEXT, thumb_image TEXT, thumb_url TEXT, media_key TEXT, media_digest TEXT, media_created_at INTEGER MAPPED BY `const MillisDateConverter()`, sticker_id TEXT, shared_user_id TEXT, mentions TEXT, quote_id TEXT, quote_content TEXT, caption TEXT, PRIMARY KEY(transcript_id, message_id)); diff --git a/lib/utils/device_transfer/transfer_data_user.dart b/lib/utils/device_transfer/transfer_data_user.dart index 4ded9f8711..fb92617541 100644 --- a/lib/utils/device_transfer/transfer_data_user.dart +++ b/lib/utils/device_transfer/transfer_data_user.dart @@ -24,6 +24,7 @@ class TransferDataUser { this.isScam, this.codeUrl, this.codeId, + this.membership, }); factory TransferDataUser.fromJson(Map json) => @@ -45,6 +46,7 @@ class TransferDataUser { isScam: user.isScam == 1, codeUrl: user.codeUrl, codeId: user.codeId, + membership: user.membership, ); @JsonKey(name: 'user_id') @@ -90,6 +92,9 @@ class TransferDataUser { @JsonKey(name: 'code_id') final String? codeId; + @JsonKey(name: 'membership') + final Membership? membership; + Map toJson() => _$TransferDataUserToJson(this); db.User toDbUser() => db.User( @@ -108,6 +113,7 @@ class TransferDataUser { isScam: isScam == true ? 1 : 0, codeUrl: codeUrl, codeId: codeId, + membership: membership, ); @override diff --git a/pubspec.lock b/pubspec.lock index cb121db6da..ad7d90a8a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -264,7 +264,7 @@ packages: source: hosted version: "4.10.0" collection: - dependency: transitive + dependency: "direct overridden" description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a @@ -1291,10 +1291,9 @@ packages: mixin_bot_sdk_dart: dependency: "direct main" description: - name: mixin_bot_sdk_dart - sha256: f8620f631e5af819eeb8fc3fa3f2053c67b7e8ed89923d8da13b569ec03b0799 - url: "https://pub.dev" - source: hosted + path: "../mixin_bot_sdk_dart" + relative: true + source: path version: "1.2.4" mixin_logger: dependency: "direct main" diff --git a/pubspec.yaml b/pubspec.yaml index 93054ba210..a0703476fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: none version: 1.10.1+285 environment: - sdk: '^3.5.0' + sdk: "^3.5.0" dependencies: android_id: ^0.4.0 @@ -93,7 +93,8 @@ dependencies: map: ^2.0.2 markdown_widget: ^2.3.2+2 mime: ^1.0.2 - mixin_bot_sdk_dart: ^1.2.3 + mixin_bot_sdk_dart: + path: ../mixin_bot_sdk_dart mixin_logger: ^0.1.2 native_dio_adapter: ^1.3.0 network_info_plus: ^6.0.0 @@ -186,6 +187,7 @@ dev_dependencies: dependency_overrides: very_good_analysis: ^6.0.0 + collection: ^1.18.0 # pixel_snap 0.1.3 not compat with latest flutter master channel. # pixel_snap: 0.1.2 # intl: ^0.19.0 @@ -200,13 +202,12 @@ flutter: # the material Icons class. uses-material-design: true assets: + # assets start - # assets start - - # GENERATED CODE - DO NOT MODIFY MANUALLY - # ************************************************************************** - # Auto generated by https://github.com/fluttercandies/assets_generator - # ************************************************************************** + # GENERATED CODE - DO NOT MODIFY MANUALLY + # ************************************************************************** + # Auto generated by https://github.com/fluttercandies/assets_generator + # ************************************************************************** - assets/ - assets/fonts/ @@ -245,7 +246,7 @@ msix_config: vs_generated_images_folder_path: ./dist/icons icons_background_color: transparent architecture: x64 - capabilities: 'internetClient,microphone' + capabilities: "internetClient,microphone" store: true toast_activator: clsid: "94B64592-528D-48B4-B37B-C82D634F1BE7" From e569f4217dcf8a6a64ba6fd11edfaaa6056fcf3a Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 13:55:36 +0900 Subject: [PATCH 02/15] update --- agen.sh | 8 +- assets/images/plan_basic.svg | 34 +++ assets/images/plan_premium.svg | 55 +++++ assets/images/plan_standard.svg | 206 ++++++++++++++++++ lib/constants/resources.dart | 11 + lib/db/dao/conversation_dao.g.dart | 30 ++- lib/db/dao/message_dao.g.dart | 13 +- lib/db/dao/participant_dao.g.dart | 15 +- lib/db/mixin_database.g.dart | 13 +- lib/db/moor/dao/common.drift | 2 + lib/db/moor/dao/conversation.drift | 7 +- lib/db/moor/dao/message.drift | 60 +++-- lib/db/moor/dao/participant.drift | 26 ++- lib/ui/home/chat/chat_bar.dart | 5 +- .../group_participants_page.dart | 5 +- .../home/conversation/conversation_list.dart | 5 +- lib/ui/home/conversation/search_list.dart | 11 +- lib/ui/provider/conversation_provider.dart | 2 + .../device_transfer/transfer_data_user.g.dart | 4 + .../actions/command_palette_action.dart | 8 +- lib/widgets/conversation/badges_widget.dart | 70 ++++++ .../conversation/verified_or_bot_widget.dart | 38 ---- .../message/item/contact_message_widget.dart | 24 +- .../send_message_dialog.dart | 1 + lib/widgets/user/user_dialog.dart | 5 +- .../user_selector/conversation_selector.dart | 11 +- pubspec.lock | 2 +- pubspec.yaml | 1 - 28 files changed, 568 insertions(+), 104 deletions(-) create mode 100644 assets/images/plan_basic.svg create mode 100644 assets/images/plan_premium.svg create mode 100644 assets/images/plan_standard.svg create mode 100644 lib/widgets/conversation/badges_widget.dart delete mode 100644 lib/widgets/conversation/verified_or_bot_widget.dart diff --git a/agen.sh b/agen.sh index 07a71cc468..db274682fc 100755 --- a/agen.sh +++ b/agen.sh @@ -1,11 +1,9 @@ #!/bin/bash -if ! command -v agen &> /dev/null -then +if ! command -v agen &>/dev/null; then echo "agen not found, active assets_generator..." dart pub global activate assets_generator - if ! command -v agen &> /dev/null - then + if ! command -v agen &>/dev/null; then echo "install assets_generator failed" exit 1 else @@ -13,4 +11,4 @@ then fi fi -agen --no-watch -t d -r lcc -o lib/constants -c Resources \ No newline at end of file +agen --no-watch -t d -r lcc -o lib/constants -c Resources diff --git a/assets/images/plan_basic.svg b/assets/images/plan_basic.svg new file mode 100644 index 0000000000..33bde8a243 --- /dev/null +++ b/assets/images/plan_basic.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/plan_premium.svg b/assets/images/plan_premium.svg new file mode 100644 index 0000000000..04a19ca1aa --- /dev/null +++ b/assets/images/plan_premium.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/plan_standard.svg b/assets/images/plan_standard.svg new file mode 100644 index 0000000000..2678635540 --- /dev/null +++ b/assets/images/plan_standard.svg @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/constants/resources.dart b/lib/constants/resources.dart index 908a0941e0..94679adbab 100644 --- a/lib/constants/resources.dart +++ b/lib/constants/resources.dart @@ -443,6 +443,17 @@ class Resources { /// {@macro assets_generator.assetsImagesPinArrowSvg.preview} static const String assetsImagesPinArrowSvg = 'assets/images/pin_arrow.svg'; + /// {@macro assets_generator.assetsImagesPlanBasicSvg.preview} + static const String assetsImagesPlanBasicSvg = 'assets/images/plan_basic.svg'; + + /// {@macro assets_generator.assetsImagesPlanPremiumSvg.preview} + static const String assetsImagesPlanPremiumSvg = + 'assets/images/plan_premium.svg'; + + /// {@macro assets_generator.assetsImagesPlanStandardSvg.preview} + static const String assetsImagesPlanStandardSvg = + 'assets/images/plan_standard.svg'; + /// {@macro assets_generator.assetsImagesPlaySvg.preview} static const String assetsImagesPlaySvg = 'assets/images/play.svg'; diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index a68e6d712f..44be1ecca7 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -154,6 +154,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { Users.$convertermuteUntil, row.readNullable('ownerMuteUntil')), appId: row.readNullable('appId'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), content: row.readNullable('content'), contentType: row.readNullable('contentType'), createdAt: Conversations.$convertercreatedAt @@ -224,7 +226,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -268,6 +270,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { Users.$convertermuteUntil, row.readNullable('ownerMuteUntil')), appId: row.readNullable('appId'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), content: row.readNullable('content'), contentType: row.readNullable('contentType'), createdAt: Conversations.$convertercreatedAt @@ -366,7 +370,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), ...generatedwhere.introducedVariables, @@ -399,6 +403,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { avatarUrl: row.readNullable('avatarUrl'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), messageStatus: NullAwareTypeConverter.wrapFromSql( Messages.$converterstatus, row.readNullable('messageStatus')), @@ -429,7 +435,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedorder.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', variables: [ for (var $ in ids) Variable($), ...generatedorder.introducedVariables @@ -460,6 +466,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { avatarUrl: row.readNullable('avatarUrl'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), messageStatus: NullAwareTypeConverter.wrapFromSql( Messages.$converterstatus, row.readNullable('messageStatus')), @@ -502,7 +510,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), Variable(circleId), @@ -537,6 +545,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { avatarUrl: row.readNullable('avatarUrl'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), messageStatus: NullAwareTypeConverter.wrapFromSql( Messages.$converterstatus, row.readNullable('messageStatus')), @@ -650,6 +660,7 @@ class ConversationItem { final String ownerIdentityNumber; final DateTime? ownerMuteUntil; final String? appId; + final Membership? membership; final String? content; final String? contentType; final DateTime createdAt; @@ -684,6 +695,7 @@ class ConversationItem { required this.ownerIdentityNumber, this.ownerMuteUntil, this.appId, + this.membership, this.content, this.contentType, required this.createdAt, @@ -720,6 +732,7 @@ class ConversationItem { ownerIdentityNumber, ownerMuteUntil, appId, + membership, content, contentType, createdAt, @@ -758,6 +771,7 @@ class ConversationItem { other.ownerIdentityNumber == this.ownerIdentityNumber && other.ownerMuteUntil == this.ownerMuteUntil && other.appId == this.appId && + other.membership == this.membership && other.content == this.content && other.contentType == this.contentType && other.createdAt == this.createdAt && @@ -794,6 +808,7 @@ class ConversationItem { ..write('ownerIdentityNumber: $ownerIdentityNumber, ') ..write('ownerMuteUntil: $ownerMuteUntil, ') ..write('appId: $appId, ') + ..write('membership: $membership, ') ..write('content: $content, ') ..write('contentType: $contentType, ') ..write('createdAt: $createdAt, ') @@ -914,6 +929,7 @@ class SearchConversationItem { final String? avatarUrl; final bool? isVerified; final String? appId; + final Membership? membership; final MessageStatus? messageStatus; final String? content; final String? contentType; @@ -936,6 +952,7 @@ class SearchConversationItem { this.avatarUrl, this.isVerified, this.appId, + this.membership, this.messageStatus, this.content, this.contentType, @@ -960,6 +977,7 @@ class SearchConversationItem { avatarUrl, isVerified, appId, + membership, messageStatus, content, contentType, @@ -986,6 +1004,7 @@ class SearchConversationItem { other.avatarUrl == this.avatarUrl && other.isVerified == this.isVerified && other.appId == this.appId && + other.membership == this.membership && other.messageStatus == this.messageStatus && other.content == this.content && other.contentType == this.contentType && @@ -1010,6 +1029,7 @@ class SearchConversationItem { ..write('avatarUrl: $avatarUrl, ') ..write('isVerified: $isVerified, ') ..write('appId: $appId, ') + ..write('membership: $membership, ') ..write('messageStatus: $messageStatus, ') ..write('content: $content, ') ..write('contentType: $contentType, ') diff --git a/lib/db/dao/message_dao.g.dart b/lib/db/dao/message_dao.g.dart index fc7d26b0ee..d9cd592b67 100644 --- a/lib/db/dao/message_dao.g.dart +++ b/lib/db/dao/message_dao.g.dart @@ -245,7 +245,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { final expandedmessageIds = $expandVar($arrayStartIndex, messageIds.length); $arrayStartIndex += messageIds.length; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', variables: [ for (var $ in messageIds) Variable($) ], @@ -266,6 +266,8 @@ mixin _$MessageDaoMixin on DatabaseAccessor { mediaName: row.readNullable('mediaName'), appId: row.readNullable('appId'), verified: row.readNullable('verified'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), ownerId: row.readNullable('ownerId'), groupIconUrl: row.readNullable('groupIconUrl'), category: Conversations.$convertercategory @@ -310,7 +312,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedlimit.introducedVariables @@ -334,6 +336,8 @@ mixin _$MessageDaoMixin on DatabaseAccessor { mediaName: row.readNullable('mediaName'), appId: row.readNullable('appId'), verified: row.readNullable('verified'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), ownerId: row.readNullable('ownerId'), groupIconUrl: row.readNullable('groupIconUrl'), category: Conversations.$convertercategory @@ -888,6 +892,7 @@ class SearchMessageDetailItem { final String? mediaName; final String? appId; final bool? verified; + final Membership? membership; final String? ownerId; final String? groupIconUrl; final ConversationCategory? category; @@ -907,6 +912,7 @@ class SearchMessageDetailItem { this.mediaName, this.appId, this.verified, + this.membership, this.ownerId, this.groupIconUrl, this.category, @@ -928,6 +934,7 @@ class SearchMessageDetailItem { mediaName, appId, verified, + membership, ownerId, groupIconUrl, category, @@ -950,6 +957,7 @@ class SearchMessageDetailItem { other.mediaName == this.mediaName && other.appId == this.appId && other.verified == this.verified && + other.membership == this.membership && other.ownerId == this.ownerId && other.groupIconUrl == this.groupIconUrl && other.category == this.category && @@ -971,6 +979,7 @@ class SearchMessageDetailItem { ..write('mediaName: $mediaName, ') ..write('appId: $appId, ') ..write('verified: $verified, ') + ..write('membership: $membership, ') ..write('ownerId: $ownerId, ') ..write('groupIconUrl: $groupIconUrl, ') ..write('category: $category, ') diff --git a/lib/db/dao/participant_dao.g.dart b/lib/db/dao/participant_dao.g.dart index a7547b0993..18944fd470 100644 --- a/lib/db/dao/participant_dao.g.dart +++ b/lib/db/dao/participant_dao.g.dart @@ -59,7 +59,7 @@ mixin _$ParticipantDaoMixin on DatabaseAccessor { Selectable groupParticipantsByConversationId( String conversationId) { return customSelect( - 'SELECT p.conversation_id AS conversationId, p.role AS role, p.created_at AS createdAt, u.user_id AS userId, u.identity_number AS identityNumber, u.relationship AS relationship, u.biography AS biography, u.full_name AS fullName, u.avatar_url AS avatarUrl, u.phone AS phone, u.is_verified AS isVerified, u.created_at AS userCreatedAt, u.mute_until AS muteUntil, u.has_pin AS hasPin, u.app_id AS appId, u.is_scam AS isScam FROM participants AS p,users AS u WHERE p.conversation_id = ?1 AND p.user_id = u.user_id ORDER BY p.created_at DESC', + 'SELECT p.conversation_id AS conversationId, p.role AS role, p.created_at AS createdAt, u.user_id AS userId, u.identity_number AS identityNumber, u.relationship AS relationship, u.biography AS biography, u.full_name AS fullName, u.avatar_url AS avatarUrl, u.phone AS phone, u.is_verified AS isVerified, u.created_at AS userCreatedAt, u.mute_until AS muteUntil, u.has_pin AS hasPin, u.app_id AS appId, u.is_scam AS isScam, u.membership AS membership FROM participants AS p,users AS u WHERE p.conversation_id = ?1 AND p.user_id = u.user_id ORDER BY p.created_at DESC', variables: [ Variable(conversationId) ], @@ -89,6 +89,8 @@ mixin _$ParticipantDaoMixin on DatabaseAccessor { hasPin: row.readNullable('hasPin'), appId: row.readNullable('appId'), isScam: row.readNullable('isScam'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), )); } @@ -155,6 +157,7 @@ class ParticipantUser { final int? hasPin; final String? appId; final int? isScam; + final Membership? membership; ParticipantUser({ required this.conversationId, this.role, @@ -172,6 +175,7 @@ class ParticipantUser { this.hasPin, this.appId, this.isScam, + this.membership, }); @override int get hashCode => Object.hash( @@ -190,7 +194,8 @@ class ParticipantUser { muteUntil, hasPin, appId, - isScam); + isScam, + membership); @override bool operator ==(Object other) => identical(this, other) || @@ -210,7 +215,8 @@ class ParticipantUser { other.muteUntil == this.muteUntil && other.hasPin == this.hasPin && other.appId == this.appId && - other.isScam == this.isScam); + other.isScam == this.isScam && + other.membership == this.membership); @override String toString() { return (StringBuffer('ParticipantUser(') @@ -229,7 +235,8 @@ class ParticipantUser { ..write('muteUntil: $muteUntil, ') ..write('hasPin: $hasPin, ') ..write('appId: $appId, ') - ..write('isScam: $isScam') + ..write('isScam: $isScam, ') + ..write('membership: $membership') ..write(')')) .toString(); } diff --git a/lib/db/mixin_database.g.dart b/lib/db/mixin_database.g.dart index d3dd686f71..e9782c2c9e 100644 --- a/lib/db/mixin_database.g.dart +++ b/lib/db/mixin_database.g.dart @@ -16403,7 +16403,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -16465,6 +16465,8 @@ abstract class _$MixinDatabase extends GeneratedDatabase { sharedUserAvatarUrl: row.readNullable('sharedUserAvatarUrl'), sharedUserIsVerified: row.readNullable('sharedUserIsVerified'), sharedUserAppId: row.readNullable('sharedUserAppId'), + sharedUserMembership: Users.$convertermembership + .fromSql(row.readNullable('sharedUserMembership')), conversationOwnerId: row.readNullable('conversationOwnerId'), conversionCategory: Conversations.$convertercategory .fromSql(row.readNullable('conversionCategory')), @@ -16539,7 +16541,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', variables: [ Variable(conversationId), ...generatedorder.introducedVariables, @@ -16600,6 +16602,8 @@ abstract class _$MixinDatabase extends GeneratedDatabase { sharedUserAvatarUrl: row.readNullable('sharedUserAvatarUrl'), sharedUserIsVerified: row.readNullable('sharedUserIsVerified'), sharedUserAppId: row.readNullable('sharedUserAppId'), + sharedUserMembership: Users.$convertermembership + .fromSql(row.readNullable('sharedUserMembership')), conversationOwnerId: row.readNullable('conversationOwnerId'), conversionCategory: Conversations.$convertercategory .fromSql(row.readNullable('conversionCategory')), @@ -23021,6 +23025,7 @@ class MessageItem { final String? sharedUserAvatarUrl; final bool? sharedUserIsVerified; final String? sharedUserAppId; + final Membership? sharedUserMembership; final String? conversationOwnerId; final ConversationCategory? conversionCategory; final String? groupName; @@ -23081,6 +23086,7 @@ class MessageItem { this.sharedUserAvatarUrl, this.sharedUserIsVerified, this.sharedUserAppId, + this.sharedUserMembership, this.conversationOwnerId, this.conversionCategory, this.groupName, @@ -23143,6 +23149,7 @@ class MessageItem { sharedUserAvatarUrl, sharedUserIsVerified, sharedUserAppId, + sharedUserMembership, conversationOwnerId, conversionCategory, groupName, @@ -23207,6 +23214,7 @@ class MessageItem { other.sharedUserAvatarUrl == this.sharedUserAvatarUrl && other.sharedUserIsVerified == this.sharedUserIsVerified && other.sharedUserAppId == this.sharedUserAppId && + other.sharedUserMembership == this.sharedUserMembership && other.conversationOwnerId == this.conversationOwnerId && other.conversionCategory == this.conversionCategory && other.groupName == this.groupName && @@ -23269,6 +23277,7 @@ class MessageItem { ..write('sharedUserAvatarUrl: $sharedUserAvatarUrl, ') ..write('sharedUserIsVerified: $sharedUserIsVerified, ') ..write('sharedUserAppId: $sharedUserAppId, ') + ..write('sharedUserMembership: $sharedUserMembership, ') ..write('conversationOwnerId: $conversationOwnerId, ') ..write('conversionCategory: $conversionCategory, ') ..write('groupName: $groupName, ') diff --git a/lib/db/moor/dao/common.drift b/lib/db/moor/dao/common.drift index ca3799051c..8bd3f2e41d 100644 --- a/lib/db/moor/dao/common.drift +++ b/lib/db/moor/dao/common.drift @@ -34,6 +34,7 @@ SELECT message.message_id AS messageId, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, + sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, @@ -112,6 +113,7 @@ SELECT message.message_id AS messageId, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, + sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 4a7d51a744..71a139faee 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -17,7 +17,7 @@ SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS conversation.expire_in as expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, - owner.app_id AS appId, + owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, @@ -52,7 +52,7 @@ SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS conversation.expire_in as expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, - owner.app_id AS appId, + owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, @@ -123,6 +123,7 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -166,6 +167,7 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -196,6 +198,7 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, diff --git a/lib/db/moor/dao/message.drift b/lib/db/moor/dao/message.drift index 0926857c7a..5f2ce30c0d 100644 --- a/lib/db/moor/dao/message.drift +++ b/lib/db/moor/dao/message.drift @@ -81,30 +81,64 @@ ORDER BY m.created_at DESC; searchMessageByIds AS SearchMessageDetailItem: -SELECT m.message_id messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, - m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, - c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl - FROM messages m +SELECT m.message_id messageId, + u.user_id AS senderId, + u.avatar_url AS senderAvatarUrl, + u.full_name AS senderFullName, + m.status AS status, + m.category AS type, + m.content AS content, + m.created_at AS createdAt, + m.name AS mediaName, + u.app_id AS appId, + u.is_verified AS verified, + u.membership AS membership, + c.owner_id AS ownerId, + c.icon_url AS groupIconUrl, + c.category AS category, + c.name AS groupName, + c.conversation_id AS conversationId, + owner.full_name AS ownerFullName, + owner.avatar_url AS ownerAvatarUrl +FROM messages m INNER JOIN conversations c ON c.conversation_id = m.conversation_id INNER JOIN users u ON m.user_id = u.user_id INNER JOIN users owner ON c.owner_id = owner.user_id - WHERE m.message_id IN :messageIds - ORDER BY m.created_at DESC, m.rowid DESC; +WHERE m.message_id IN :messageIds +ORDER BY m.created_at DESC, + m.rowid DESC; miniMessageByIds AS MiniMessageItem: SELECT conversation_id as conversationId, message_id as messageId FROM messages WHERE message_id IN :messageIds; _searchMessage AS SearchMessageDetailItem: -SELECT m.message_id messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, - m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, - c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl - FROM messages m +SELECT m.message_id messageId, + u.user_id AS senderId, + u.avatar_url AS senderAvatarUrl, + u.full_name AS senderFullName, + m.status AS status, + m.category AS type, + m.content AS content, + m.created_at AS createdAt, + m.name AS mediaName, + u.app_id AS appId, + u.is_verified AS verified, + u.membership AS membership, + c.owner_id AS ownerId, + c.icon_url AS groupIconUrl, + c.category AS category, + c.name AS groupName, + c.conversation_id AS conversationId, + owner.full_name AS ownerFullName, + owner.avatar_url AS ownerAvatarUrl +FROM messages m INNER JOIN conversations c ON c.conversation_id = m.conversation_id INNER JOIN users u ON m.user_id = u.user_id INNER JOIN users owner ON c.owner_id = owner.user_id - WHERE $where - ORDER BY m.created_at DESC, m.rowid DESC - LIMIT $limit; +WHERE $where +ORDER BY m.created_at DESC, + m.rowid DESC +LIMIT $limit; countMessages: SELECT count(1) FROM messages; diff --git a/lib/db/moor/dao/participant.drift b/lib/db/moor/dao/participant.drift index 8a6d620ce1..7e73b1608f 100644 --- a/lib/db/moor/dao/participant.drift +++ b/lib/db/moor/dao/participant.drift @@ -9,13 +9,27 @@ ORDER BY participant.created_at ASC LIMIT 4; groupParticipantsByConversationId AS ParticipantUser: -SELECT p.conversation_id AS conversationId, p.role AS role, p.created_at AS createdAt, -u.user_id AS userId, u.identity_number AS identityNumber, u.relationship AS relationship, u.biography AS biography, u.full_name AS fullName, -u.avatar_url AS avatarUrl, u.phone AS phone, u.is_verified AS isVerified, u.created_at AS userCreatedAt, u.mute_until AS muteUntil, -u.has_pin AS hasPin, u.app_id AS appId, u.is_scam AS isScam -FROM participants p, users u +SELECT p.conversation_id AS conversationId, + p.role AS role, + p.created_at AS createdAt, + u.user_id AS userId, + u.identity_number AS identityNumber, + u.relationship AS relationship, + u.biography AS biography, + u.full_name AS fullName, + u.avatar_url AS avatarUrl, + u.phone AS phone, + u.is_verified AS isVerified, + u.created_at AS userCreatedAt, + u.mute_until AS muteUntil, + u.has_pin AS hasPin, + u.app_id AS appId, + u.is_scam AS isScam, + u.membership AS membership +FROM participants p, + users u WHERE p.conversation_id = :conversationId -AND p.user_id = u.user_id + AND p.user_id = u.user_id ORDER BY p.created_at DESC; userIdByIdentityNumber: diff --git a/lib/ui/home/chat/chat_bar.dart b/lib/ui/home/chat/chat_bar.dart index 2c3157d91c..dfda41a607 100644 --- a/lib/ui/home/chat/chat_bar.dart +++ b/lib/ui/home/chat/chat_bar.dart @@ -11,7 +11,7 @@ import '../../../utils/web_view/web_view_interface.dart'; import '../../../widgets/action_button.dart'; import '../../../widgets/avatar_view/avatar_view.dart'; import '../../../widgets/buttons.dart'; -import '../../../widgets/conversation/verified_or_bot_widget.dart'; +import '../../../widgets/conversation/badges_widget.dart'; import '../../../widgets/high_light_text.dart'; import '../../../widgets/interactive_decorated_box.dart'; import '../../../widgets/window/move_window.dart'; @@ -268,9 +268,10 @@ class ConversationName extends StatelessWidget { ), ), ), - VerifiedOrBotWidget( + BadgesWidget( verified: conversationState.isVerified, isBot: conversationState.isBot ?? false, + membership: conversationState.membership, ), ], ); diff --git a/lib/ui/home/chat_slide_page/group_participants_page.dart b/lib/ui/home/chat_slide_page/group_participants_page.dart index 7166e4297e..8238f0aadf 100644 --- a/lib/ui/home/chat_slide_page/group_participants_page.dart +++ b/lib/ui/home/chat_slide_page/group_participants_page.dart @@ -14,7 +14,7 @@ import '../../../utils/extension/extension.dart'; import '../../../utils/hook.dart'; import '../../../widgets/app_bar.dart'; import '../../../widgets/avatar_view/avatar_view.dart'; -import '../../../widgets/conversation/verified_or_bot_widget.dart'; +import '../../../widgets/conversation/badges_widget.dart'; import '../../../widgets/high_light_text.dart'; import '../../../widgets/menu.dart'; import '../../../widgets/search_text_field.dart'; @@ -180,9 +180,10 @@ class _ParticipantTile extends HookWidget { ], ), ), - VerifiedOrBotWidget( + BadgesWidget( isBot: participant.appId != null, verified: participant.isVerified, + membership: participant.membership, ), ], ), diff --git a/lib/ui/home/conversation/conversation_list.dart b/lib/ui/home/conversation/conversation_list.dart index 3e5b3391b7..b18df5f9d3 100644 --- a/lib/ui/home/conversation/conversation_list.dart +++ b/lib/ui/home/conversation/conversation_list.dart @@ -14,7 +14,7 @@ import '../../../utils/extension/extension.dart'; import '../../../utils/hook.dart'; import '../../../utils/message_optimize.dart'; import '../../../widgets/avatar_view/avatar_view.dart'; -import '../../../widgets/conversation/verified_or_bot_widget.dart'; +import '../../../widgets/conversation/badges_widget.dart'; import '../../../widgets/high_light_text.dart'; import '../../../widgets/interactive_decorated_box.dart'; import '../../../widgets/message/item/pin_message.dart'; @@ -199,9 +199,10 @@ class ConversationItemWidget extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - VerifiedOrBotWidget( + BadgesWidget( verified: conversation.ownerVerified, isBot: conversation.isBotConversation, + membership: conversation.membership, ), ], ), diff --git a/lib/ui/home/conversation/search_list.dart b/lib/ui/home/conversation/search_list.dart index 12ba9c9a54..c0b3cd5769 100644 --- a/lib/ui/home/conversation/search_list.dart +++ b/lib/ui/home/conversation/search_list.dart @@ -22,7 +22,7 @@ import '../../../utils/message_optimize.dart'; import '../../../utils/reg_exp_utils.dart'; import '../../../utils/uri_utils.dart'; import '../../../widgets/avatar_view/avatar_view.dart'; -import '../../../widgets/conversation/verified_or_bot_widget.dart'; +import '../../../widgets/conversation/badges_widget.dart'; import '../../../widgets/high_light_text.dart'; import '../../../widgets/interactive_decorated_box.dart'; import '../../../widgets/message/item/pin_message.dart'; @@ -222,9 +222,10 @@ class SearchList extends HookConsumerWidget { ), name: user.fullName ?? '?', description: context.l10n.contactMixinId(user.identityNumber), - trailing: VerifiedOrBotWidget( + trailing: BadgesWidget( verified: user.isVerified, isBot: user.appId != null, + membership: user.membership, ), keyword: keyword, onTap: () async { @@ -334,9 +335,10 @@ class SearchList extends HookConsumerWidget { ), name: conversation.validName, description: description, - trailing: VerifiedOrBotWidget( + trailing: BadgesWidget( verified: conversation.isVerified, isBot: conversation.appId != null, + membership: conversation.membership, ), keyword: keyword, onTap: () async { @@ -759,9 +761,10 @@ class SearchMessageItem extends HookConsumerWidget { message.groupName, message.ownerFullName, ), - trailing: VerifiedOrBotWidget( + trailing: BadgesWidget( verified: message.verified, isBot: message.appId != null, + membership: message.membership, ), nameHighlight: false, keyword: keyword, diff --git a/lib/ui/provider/conversation_provider.dart b/lib/ui/provider/conversation_provider.dart index 1b51f104b3..71bcdf5ae6 100644 --- a/lib/ui/provider/conversation_provider.dart +++ b/lib/ui/provider/conversation_provider.dart @@ -60,6 +60,8 @@ class ConversationState extends Equatable { bool get isVerified => conversation?.ownerVerified ?? user?.isVerified ?? false; + Membership? get membership => user?.membership ?? conversation?.membership; + // note: check user information first. // because in bot stranger conversation. it might be conversation.isStrangerConversation == false bool? get isStranger => diff --git a/lib/utils/device_transfer/transfer_data_user.g.dart b/lib/utils/device_transfer/transfer_data_user.g.dart index d844c5ef96..4b858f3738 100644 --- a/lib/utils/device_transfer/transfer_data_user.g.dart +++ b/lib/utils/device_transfer/transfer_data_user.g.dart @@ -28,6 +28,9 @@ TransferDataUser _$TransferDataUserFromJson(Map json) => isScam: json['is_scam'] as bool?, codeUrl: json['code_url'] as String?, codeId: json['code_id'] as String?, + membership: json['membership'] == null + ? null + : Membership.fromJson(json['membership'] as Map), ); Map _$TransferDataUserToJson(TransferDataUser instance) => @@ -48,4 +51,5 @@ Map _$TransferDataUserToJson(TransferDataUser instance) => 'is_scam': instance.isScam, 'code_url': instance.codeUrl, 'code_id': instance.codeId, + 'membership': instance.membership?.toJson(), }; diff --git a/lib/widgets/actions/command_palette_action.dart b/lib/widgets/actions/command_palette_action.dart index b6476fa844..33f8145309 100644 --- a/lib/widgets/actions/command_palette_action.dart +++ b/lib/widgets/actions/command_palette_action.dart @@ -21,7 +21,7 @@ import '../../utils/hook.dart'; import '../../utils/platform.dart'; import '../avatar_view/avatar_view.dart'; import '../buttons.dart'; -import '../conversation/verified_or_bot_widget.dart'; +import '../conversation/badges_widget.dart'; import '../dialog.dart'; import '../search_text_field.dart'; import 'actions.dart'; @@ -293,9 +293,10 @@ class CommandPalettePage extends HookConsumerWidget { avatarUrl: user.avatarUrl, ), name: user.fullName ?? '?', - trailing: VerifiedOrBotWidget( + trailing: BadgesWidget( verified: user.isVerified, isBot: user.appId != null, + membership: user.membership, ), keyword: keyword, onTap: () => select(index), @@ -328,9 +329,10 @@ class CommandPalettePage extends HookConsumerWidget { userId: conversation.ownerId, ), name: conversation.validName, - trailing: VerifiedOrBotWidget( + trailing: BadgesWidget( verified: conversation.isVerified, isBot: conversation.appId != null, + membership: conversation.membership, ), keyword: keyword, onTap: () => select(users.length + index), diff --git a/lib/widgets/conversation/badges_widget.dart b/lib/widgets/conversation/badges_widget.dart new file mode 100644 index 0000000000..a4e0ed88a8 --- /dev/null +++ b/lib/widgets/conversation/badges_widget.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; + +import '../../../constants/resources.dart'; +import '../../utils/extension/extension.dart'; + +class BadgesWidget extends StatelessWidget { + const BadgesWidget({ + required this.verified, + required this.isBot, + required this.membership, + super.key, + }); + final bool? verified; + final bool isBot; + final Membership? membership; + + @override + Widget build(BuildContext context) { + var children = []; + + switch ((verified, isBot)) { + case (true, _): + children.add( + SvgPicture.asset( + Resources.assetsImagesVerifiedSvg, + width: 12, + height: 12, + ), + ); + case (_, true): + children.add( + SvgPicture.asset( + Resources.assetsImagesBotFillSvg, + width: 12, + height: 12, + ), + ); + default: + } + + switch ((membership?.isValid, membership?.plan)) { + case (true, final plan) when plan != Plan.none: + children.add( + SvgPicture.asset( + { + Plan.basic: Resources.assetsImagesPlanBasicSvg, + Plan.standard: Resources.assetsImagesPlanStandardSvg, + Plan.premium: Resources.assetsImagesPlanPremiumSvg, + }[plan]!, + width: 12, + height: 12, + ), + ); + default: + } + + children = children.joinList(const SizedBox(width: 4)); + + if (children.isNotEmpty) { + children.insert(0, const SizedBox(width: 4)); + } + + return Row( + mainAxisSize: MainAxisSize.min, + children: children, + ); + } +} diff --git a/lib/widgets/conversation/verified_or_bot_widget.dart b/lib/widgets/conversation/verified_or_bot_widget.dart deleted file mode 100644 index 305f520243..0000000000 --- a/lib/widgets/conversation/verified_or_bot_widget.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; - -import '../../../constants/resources.dart'; - -class VerifiedOrBotWidget extends StatelessWidget { - const VerifiedOrBotWidget({ - required this.verified, - required this.isBot, - super.key, - }); - final bool? verified; - final bool isBot; - - @override - Widget build(BuildContext context) { - final _verified = verified ?? false; - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (_verified || isBot) const SizedBox(width: 4), - if (_verified) - SvgPicture.asset( - Resources.assetsImagesVerifiedSvg, - width: 12, - height: 12, - ) - else if (isBot) - SvgPicture.asset( - Resources.assetsImagesBotFillSvg, - width: 12, - height: 12, - ), - if (_verified || isBot) const SizedBox(width: 4), - ], - ); - } -} diff --git a/lib/widgets/message/item/contact_message_widget.dart b/lib/widgets/message/item/contact_message_widget.dart index 9f7f05af49..536e040d09 100644 --- a/lib/widgets/message/item/contact_message_widget.dart +++ b/lib/widgets/message/item/contact_message_widget.dart @@ -1,10 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; import '../../../utils/extension/extension.dart'; import '../../avatar_view/avatar_view.dart'; -import '../../conversation/verified_or_bot_widget.dart'; +import '../../conversation/badges_widget.dart'; import '../../interactive_decorated_box.dart'; import '../../user/user_dialog.dart'; import '../message.dart'; @@ -29,6 +30,8 @@ class ContactMessageWidget extends HookConsumerWidget { useMessageConverter(converter: (state) => state.sharedUserAppId); final sharedUserIdentityNumber = useMessageConverter( converter: (state) => state.sharedUserIdentityNumber ?? ''); + final shareUserMembership = + useMessageConverter(converter: (state) => state.sharedUserMembership); return MessageBubble( outerTimeAndStatusWidget: const MessageDatetimeAndStatus(), @@ -38,12 +41,14 @@ class ContactMessageWidget extends HookConsumerWidget { sharedUserId, ), child: ContactItem( - avatarUrl: sharedUserAvatarUrl, - userId: sharedUserId, - fullName: sharedUserFullName, - isVerified: sharedUserIsVerified, - appId: sharedUserAppId, - identityNumber: sharedUserIdentityNumber), + avatarUrl: sharedUserAvatarUrl, + userId: sharedUserId, + fullName: sharedUserFullName, + isVerified: sharedUserIsVerified, + appId: sharedUserAppId, + identityNumber: sharedUserIdentityNumber, + membership: shareUserMembership, + ), ), ); } @@ -57,6 +62,7 @@ class ContactItem extends StatelessWidget { required this.isVerified, required this.appId, required this.identityNumber, + required this.membership, super.key, }); @@ -66,6 +72,7 @@ class ContactItem extends StatelessWidget { final bool? isVerified; final String? appId; final String identityNumber; + final Membership? membership; @override Widget build(BuildContext context) => Row( @@ -97,9 +104,10 @@ class ContactItem extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - VerifiedOrBotWidget( + BadgesWidget( verified: isVerified, isBot: appId != null, + membership: membership, ), ], ), diff --git a/lib/widgets/message/send_message_dialog/send_message_dialog.dart b/lib/widgets/message/send_message_dialog/send_message_dialog.dart index dd99720aca..06643ccfc1 100644 --- a/lib/widgets/message/send_message_dialog/send_message_dialog.dart +++ b/lib/widgets/message/send_message_dialog/send_message_dialog.dart @@ -457,6 +457,7 @@ class _Contact extends HookConsumerWidget { isVerified: user.isVerified, appId: user.appId, identityNumber: user.identityNumber, + membership: user.membership, ), ); } diff --git a/lib/widgets/user/user_dialog.dart b/lib/widgets/user/user_dialog.dart index 5695812be9..b51b870f48 100644 --- a/lib/widgets/user/user_dialog.dart +++ b/lib/widgets/user/user_dialog.dart @@ -14,7 +14,7 @@ import '../../utils/logger.dart'; import '../action_button.dart'; import '../avatar_view/avatar_view.dart'; import '../buttons.dart'; -import '../conversation/verified_or_bot_widget.dart'; +import '../conversation/badges_widget.dart'; import '../dialog.dart'; import '../high_light_text.dart'; import '../menu.dart'; @@ -195,9 +195,10 @@ class _UserProfileBody extends StatelessWidget { ), ), ), - VerifiedOrBotWidget( + BadgesWidget( verified: user.isVerified, isBot: !anonymous && user.appId != null, + membership: user.membership, ) ], ), diff --git a/lib/widgets/user_selector/conversation_selector.dart b/lib/widgets/user_selector/conversation_selector.dart index 35e0fb19df..4d14f1dd75 100644 --- a/lib/widgets/user_selector/conversation_selector.dart +++ b/lib/widgets/user_selector/conversation_selector.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_svg/svg.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart' as sdk; import 'package:mixin_logger/mixin_logger.dart'; import 'package:sliver_tools/sliver_tools.dart'; @@ -19,7 +20,7 @@ import '../../utils/extension/extension.dart'; import '../../utils/hook.dart'; import '../action_button.dart'; import '../avatar_view/avatar_view.dart'; -import '../conversation/verified_or_bot_widget.dart'; +import '../conversation/badges_widget.dart'; import '../dialog.dart'; import '../high_light_text.dart'; import '../interactive_decorated_box.dart'; @@ -392,6 +393,7 @@ class _ConversationSelector extends HookConsumerWidget { title: item.validName, verified: item.ownerVerified, isBot: item.isBotConversation, + membership: item.membership, selected: selected.any((element) => _getConversationId(element, context) == _getConversationId(item, context)), @@ -416,6 +418,7 @@ class _ConversationSelector extends HookConsumerWidget { title: item.fullName ?? '', verified: item.isVerified, isBot: item.appId != null, + membership: item.membership, showSelector: !singleSelect, selected: selected.any((element) => _getConversationId(element, context) == @@ -440,6 +443,7 @@ class _ConversationSelector extends HookConsumerWidget { title: item.fullName!, verified: item.isVerified, isBot: item.appId != null, + membership: item.membership, showSelector: !singleSelect, selected: selected.any((element) => _getConversationId(element, context) == @@ -636,6 +640,7 @@ class _BaseItem extends StatelessWidget { required this.avatar, required this.verified, required this.isBot, + required this.membership, this.showSelector = false, this.selected = false, }); @@ -648,6 +653,7 @@ class _BaseItem extends StatelessWidget { final bool? verified; final bool isBot; + final sdk.Membership? membership; @override Widget build(BuildContext context) => Container( @@ -699,9 +705,10 @@ class _BaseItem extends StatelessWidget { ), ), ), - VerifiedOrBotWidget( + BadgesWidget( verified: verified, isBot: isBot, + membership: membership, ), ], ), diff --git a/pubspec.lock b/pubspec.lock index ad7d90a8a1..85bc6deed7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -264,7 +264,7 @@ packages: source: hosted version: "4.10.0" collection: - dependency: "direct overridden" + dependency: transitive description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a diff --git a/pubspec.yaml b/pubspec.yaml index a0703476fd..dc91651517 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -187,7 +187,6 @@ dev_dependencies: dependency_overrides: very_good_analysis: ^6.0.0 - collection: ^1.18.0 # pixel_snap 0.1.3 not compat with latest flutter master channel. # pixel_snap: 0.1.2 # intl: ^0.19.0 From ad175c4bb6aacb6b8a67b8bf420efd0db4a7dcf6 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 14:26:30 +0900 Subject: [PATCH 03/15] fix sql --- lib/db/converter/membership_converter.dart | 2 + lib/db/dao/conversation_dao.g.dart | 10 +- lib/db/moor/dao/conversation.drift | 157 +++++++++++++------- lib/widgets/conversation/badges_widget.dart | 4 +- pubspec.lock | 2 +- pubspec.yaml | 1 + 6 files changed, 113 insertions(+), 63 deletions(-) diff --git a/lib/db/converter/membership_converter.dart b/lib/db/converter/membership_converter.dart index 77e6a917be..60152c4fca 100644 --- a/lib/db/converter/membership_converter.dart +++ b/lib/db/converter/membership_converter.dart @@ -5,6 +5,8 @@ import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; import 'package:mixin_logger/mixin_logger.dart'; class MembershipConverter extends TypeConverter { + const MembershipConverter(); + @override Membership? fromSql(String? fromDb) { if (fromDb == null) { diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index 44be1ecca7..84826d09d8 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -226,7 +226,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -370,7 +370,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \' CONTACT \' AND(owner.full_name LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \' OR owner.identity_number LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \' GROUP \' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \' CONTACT \' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), ...generatedwhere.introducedVariables, @@ -435,7 +435,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedorder.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', variables: [ for (var $ in ids) Variable($), ...generatedorder.introducedVariables @@ -510,7 +510,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), Variable(circleId), diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 71a139faee..7a082e731e 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -8,72 +8,110 @@ FROM conversations conversation WHERE $where; _baseConversationItems AS ConversationItem: -SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, - conversation.category AS category, conversation.draft AS draft, - conversation.name AS groupName, conversation.status AS status, +SELECT conversation.conversation_id AS conversationId, + conversation.icon_url AS groupIconUrl, + conversation.category AS category, + conversation.draft AS draft, + conversation.name AS groupName, + conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, - conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, - conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, + conversation.unseen_message_count AS unseenMessageCount, + conversation.owner_id AS ownerId, + conversation.pin_time AS pinTime, + conversation.mute_until AS muteUntil, conversation.expire_in as expireIn, - owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, - owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, - owner.app_id AS appId, owner.membership AS membership, - lastMessage.content AS content, lastMessage.category AS contentType, - conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, + owner.avatar_url AS avatarUrl, + owner.full_name AS name, + owner.is_verified AS ownerVerified, + owner.identity_number AS ownerIdentityNumber, + owner.mute_until AS ownerMuteUntil, + owner.app_id AS appId, + CASE + WHEN conversation.category = 'CONTACT' THEN owner.membership + ELSE NULL + END AS membership, + lastMessage.content AS content, + lastMessage.category AS contentType, + conversation.created_at AS createdAt, + lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, - lastMessage.user_id AS senderId, lastMessage.action AS actionName, + lastMessage.user_id AS senderId, + lastMessage.action AS actionName, lastMessage.status AS messageStatus, - lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, - participant.full_name AS participantFullName, participant.user_id AS participantUserId, + lastMessageSender.full_name AS senderFullName, + snapshot.type AS SnapshotType, + participant.full_name AS participantFullName, + participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, - (SELECT COUNT(1) - FROM message_mentions messageMention - WHERE messageMention.conversation_id = conversation.conversation_id AND - messageMention.has_read = 0) AS mentionCount, + ( + SELECT COUNT(1) + FROM message_mentions messageMention + WHERE messageMention.conversation_id = conversation.conversation_id + AND messageMention.has_read = 0 + ) AS mentionCount, owner.relationship AS relationship FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id - LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id - LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id - LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id - LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id + INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id + LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id + LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id + LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id + LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id WHERE $where ORDER BY $order LIMIT $limit; _baseConversationItemsByCircleId AS ConversationItem: -SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, - conversation.category AS category, conversation.draft AS draft, - conversation.name AS groupName, conversation.status AS status, +SELECT conversation.conversation_id AS conversationId, + conversation.icon_url AS groupIconUrl, + conversation.category AS category, + conversation.draft AS draft, + conversation.name AS groupName, + conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, - conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, - conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, + conversation.unseen_message_count AS unseenMessageCount, + conversation.owner_id AS ownerId, + conversation.pin_time AS pinTime, + conversation.mute_until AS muteUntil, conversation.expire_in as expireIn, - owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, - owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, - owner.app_id AS appId, owner.membership AS membership, - lastMessage.content AS content, lastMessage.category AS contentType, - conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, + owner.avatar_url AS avatarUrl, + owner.full_name AS name, + owner.is_verified AS ownerVerified, + owner.identity_number AS ownerIdentityNumber, + owner.mute_until AS ownerMuteUntil, + owner.app_id AS appId, + CASE + WHEN conversation.category = 'CONTACT' THEN owner.membership + ELSE NULL + END AS membership, + lastMessage.content AS content, + lastMessage.category AS contentType, + conversation.created_at AS createdAt, + lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, - lastMessage.user_id AS senderId, lastMessage.action AS actionName, + lastMessage.user_id AS senderId, + lastMessage.action AS actionName, lastMessage.status AS messageStatus, - lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, - participant.full_name AS participantFullName, participant.user_id AS participantUserId, + lastMessageSender.full_name AS senderFullName, + snapshot.type AS SnapshotType, + participant.full_name AS participantFullName, + participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, - (SELECT COUNT(1) - FROM message_mentions messageMention - WHERE messageMention.conversation_id = conversation.conversation_id AND - messageMention.has_read = 0) AS mentionCount, + ( + SELECT COUNT(1) + FROM message_mentions messageMention + WHERE messageMention.conversation_id = conversation.conversation_id + AND messageMention.has_read = 0 + ) AS mentionCount, owner.relationship AS relationship FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id - LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id - LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id - LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id - LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id - LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id + INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id + LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id + LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id + LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id + LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id + LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id WHERE $where ORDER BY $order LIMIT $limit; @@ -123,7 +161,10 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - owner.membership AS membership, + CASE + WHEN conversation.category = 'CONTACT' THEN owner.membership + ELSE NULL + END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -141,12 +182,12 @@ WHERE ( ( conversation.category = 'GROUP' AND conversation.name LIKE '%' || :query || '%' ESCAPE '\') OR - (conversation.category = 'CONTACT' AND - (owner.full_name LIKE '%' || :query || '%' ESCAPE '\' OR - owner.identity_number LIKE '%' || :query || '%' ESCAPE '\')) + (conversation.category = ' CONTACT ' AND + (owner.full_name LIKE ' %' || :query || ' %' ESCAPE ' \ ' OR + owner.identity_number LIKE ' %' || :query || ' %' ESCAPE ' \ ')) ) AND $where -ORDER BY (conversation.category = 'GROUP' AND conversation.name = :query COLLATE NOCASE) - OR (conversation.category = 'CONTACT' +ORDER BY (conversation.category = ' GROUP ' AND conversation.name = :query COLLATE NOCASE) + OR (conversation.category = ' CONTACT ' AND (owner.full_name = :query COLLATE NOCASE OR owner.identity_number = :query COLLATE NOCASE)) DESC, conversation.pin_time DESC, @@ -167,7 +208,10 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - owner.membership AS membership, + CASE + WHEN conversation.category = 'CONTACT' THEN owner.membership + ELSE NULL + END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -198,7 +242,10 @@ SELECT conversation.conversation_id AS conversationId, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - owner.membership AS membership, + CASE + WHEN conversation.category = 'CONTACT' THEN owner.membership + ELSE NULL + END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, diff --git a/lib/widgets/conversation/badges_widget.dart b/lib/widgets/conversation/badges_widget.dart index a4e0ed88a8..3adc777800 100644 --- a/lib/widgets/conversation/badges_widget.dart +++ b/lib/widgets/conversation/badges_widget.dart @@ -49,8 +49,8 @@ class BadgesWidget extends StatelessWidget { Plan.standard: Resources.assetsImagesPlanStandardSvg, Plan.premium: Resources.assetsImagesPlanPremiumSvg, }[plan]!, - width: 12, - height: 12, + width: 16, + height: 16, ), ); default: diff --git a/pubspec.lock b/pubspec.lock index 85bc6deed7..ad7d90a8a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -264,7 +264,7 @@ packages: source: hosted version: "4.10.0" collection: - dependency: transitive + dependency: "direct overridden" description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a diff --git a/pubspec.yaml b/pubspec.yaml index dc91651517..a0703476fd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -187,6 +187,7 @@ dev_dependencies: dependency_overrides: very_good_analysis: ^6.0.0 + collection: ^1.18.0 # pixel_snap 0.1.3 not compat with latest flutter master channel. # pixel_snap: 0.1.2 # intl: ^0.19.0 From e4ca66914d560ee557df72e686f703b3dd09a13d Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 15:17:41 +0900 Subject: [PATCH 04/15] chore: update mixin_bot_sdk_dart to version 1.2.5 --- pubspec.lock | 9 +++++---- pubspec.yaml | 3 +-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index ad7d90a8a1..5b513c184b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1291,10 +1291,11 @@ packages: mixin_bot_sdk_dart: dependency: "direct main" description: - path: "../mixin_bot_sdk_dart" - relative: true - source: path - version: "1.2.4" + name: mixin_bot_sdk_dart + sha256: cc5a0af3a989ae8511132482253f78ac3e028e57802f60ad6a395e63fe6d4434 + url: "https://pub.dev" + source: hosted + version: "1.2.5" mixin_logger: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index a0703476fd..1fb54a78d5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -93,8 +93,7 @@ dependencies: map: ^2.0.2 markdown_widget: ^2.3.2+2 mime: ^1.0.2 - mixin_bot_sdk_dart: - path: ../mixin_bot_sdk_dart + mixin_bot_sdk_dart: ^1.2.5 mixin_logger: ^0.1.2 native_dio_adapter: ^1.3.0 network_info_plus: ^6.0.0 From c1789b2d4cf72f0dfe4abc4de50313b5ef9819aa Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 16:27:01 +0900 Subject: [PATCH 05/15] improve: sql --- lib/account/notification_service.dart | 13 +- lib/db/dao/conversation_dao.g.dart | 265 +++++++----------- lib/db/dao/message_dao.g.dart | 95 +++---- lib/db/extension/conversation.dart | 18 +- lib/db/mixin_database.g.dart | 11 +- lib/db/moor/dao/common.drift | 2 - lib/db/moor/dao/conversation.drift | 101 +++---- lib/db/moor/dao/message.drift | 74 +++-- .../home/chat_slide_page/chat_info_page.dart | 5 +- .../group_invite/group_invite_dialog.dart | 1 - .../groups_in_common_page.dart | 1 - .../home/conversation/audio_player_bar.dart | 2 +- .../home/conversation/conversation_list.dart | 4 +- lib/ui/home/conversation/menu_wrapper.dart | 5 +- lib/ui/home/conversation/search_list.dart | 20 +- lib/ui/provider/conversation_provider.dart | 2 +- lib/ui/setting/storage_usage_list_page.dart | 8 +- .../actions/command_palette_action.dart | 6 +- lib/widgets/avatar_view/avatar_view.dart | 5 +- .../bloc/conversation_filter_cubit.dart | 16 +- .../user_selector/conversation_selector.dart | 4 +- 21 files changed, 234 insertions(+), 424 deletions(-) diff --git a/lib/account/notification_service.dart b/lib/account/notification_service.dart index 0d80acf7c9..156800abf5 100644 --- a/lib/account/notification_service.dart +++ b/lib/account/notification_service.dart @@ -6,7 +6,6 @@ import 'package:stream_transform/stream_transform.dart'; import '../blaze/vo/pin_message_minimal.dart'; import '../db/database_event_bus.dart'; -import '../db/extension/conversation.dart'; import '../enum/message_category.dart'; import '../generated/l10n.dart'; @@ -85,17 +84,9 @@ class NotificationService { // quote current user if (await quotedCurrentUser()) return true; - final muteUntil = event.category == ConversationCategory.group - ? event.muteUntil - : event.ownerMuteUntil; - return muteUntil?.isAfter(DateTime.now()) != true; + return event.muteUntil?.isAfter(DateTime.now()) != true; }) .asyncMap((event) async { - final name = conversationValidName( - event.groupName, - event.ownerFullName, - ); - String? body; if (context.settingChangeNotifier.messagePreview) { final mentionCache = @@ -153,7 +144,7 @@ class NotificationService { } await showNotification( - title: name, + title: event.name ?? '', body: body, uri: Uri( scheme: enumConvertToString(NotificationScheme.conversation), diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index 84826d09d8..e7bd5ef8cd 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -129,11 +129,13 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ...generatedlimit.watchedTables, }).map((QueryRow row) => ConversationItem( conversationId: row.read('conversationId'), - groupIconUrl: row.readNullable('groupIconUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), + muteUntil: NullAwareTypeConverter.wrapFromSql( + Users.$convertermuteUntil, row.readNullable('muteUntil')), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), draft: row.readNullable('draft'), - groupName: row.readNullable('groupName'), status: Conversations.$converterstatus.fromSql(row.read('status')), lastReadMessageId: row.readNullable('lastReadMessageId'), @@ -142,17 +144,9 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { pinTime: NullAwareTypeConverter.wrapFromSql( Conversations.$converterpinTime, row.readNullable('pinTime')), - muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), expireIn: row.readNullable('expireIn'), - avatarUrl: row.readNullable('avatarUrl'), - name: row.readNullable('name'), ownerVerified: row.readNullable('ownerVerified'), - ownerIdentityNumber: row.read('ownerIdentityNumber'), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), + ownerIdentityNumber: row.readNullable('ownerIdentityNumber'), appId: row.readNullable('appId'), membership: Users.$convertermembership .fromSql(row.readNullable('membership')), @@ -226,7 +220,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -245,11 +239,13 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ...generatedlimit.watchedTables, }).map((QueryRow row) => ConversationItem( conversationId: row.read('conversationId'), - groupIconUrl: row.readNullable('groupIconUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), + muteUntil: NullAwareTypeConverter.wrapFromSql( + Users.$convertermuteUntil, row.readNullable('muteUntil')), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), draft: row.readNullable('draft'), - groupName: row.readNullable('groupName'), status: Conversations.$converterstatus.fromSql(row.read('status')), lastReadMessageId: row.readNullable('lastReadMessageId'), @@ -258,17 +254,9 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { pinTime: NullAwareTypeConverter.wrapFromSql( Conversations.$converterpinTime, row.readNullable('pinTime')), - muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), expireIn: row.readNullable('expireIn'), - avatarUrl: row.readNullable('avatarUrl'), - name: row.readNullable('name'), ownerVerified: row.readNullable('ownerVerified'), - ownerIdentityNumber: row.read('ownerIdentityNumber'), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), + ownerIdentityNumber: row.readNullable('ownerIdentityNumber'), appId: row.readNullable('appId'), membership: Users.$convertermembership .fromSql(row.readNullable('membership')), @@ -370,7 +358,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \' CONTACT \' AND(owner.full_name LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \' OR owner.identity_number LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \' GROUP \' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \' CONTACT \' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \' CONTACT \' AND(owner.full_name LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \' OR owner.identity_number LIKE \' %\' || ?1 || \' %\' ESCAPE \' \\ \')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \' GROUP \' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \' CONTACT \' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), ...generatedwhere.introducedVariables, @@ -384,23 +372,17 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ...generatedlimit.watchedTables, }).map((QueryRow row) => SearchConversationItem( conversationId: row.read('conversationId'), - groupIconUrl: row.readNullable('groupIconUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), + muteUntil: NullAwareTypeConverter.wrapFromSql( + Users.$convertermuteUntil, row.readNullable('muteUntil')), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - groupName: row.readNullable('groupName'), pinTime: NullAwareTypeConverter.wrapFromSql( Conversations.$converterpinTime, row.readNullable('pinTime')), - muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), ownerId: row.readNullable('ownerId'), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), - ownerIdentityNumber: row.read('ownerIdentityNumber'), - fullName: row.readNullable('fullName'), - avatarUrl: row.readNullable('avatarUrl'), + ownerIdentityNumber: row.readNullable('ownerIdentityNumber'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), membership: Users.$convertermembership @@ -435,7 +417,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedorder.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', variables: [ for (var $ in ids) Variable($), ...generatedorder.introducedVariables @@ -447,23 +429,17 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ...generatedorder.watchedTables, }).map((QueryRow row) => SearchConversationItem( conversationId: row.read('conversationId'), - groupIconUrl: row.readNullable('groupIconUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), + muteUntil: NullAwareTypeConverter.wrapFromSql( + Users.$convertermuteUntil, row.readNullable('muteUntil')), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - groupName: row.readNullable('groupName'), pinTime: NullAwareTypeConverter.wrapFromSql( Conversations.$converterpinTime, row.readNullable('pinTime')), - muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), ownerId: row.readNullable('ownerId'), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), - ownerIdentityNumber: row.read('ownerIdentityNumber'), - fullName: row.readNullable('fullName'), - avatarUrl: row.readNullable('avatarUrl'), + ownerIdentityNumber: row.readNullable('ownerIdentityNumber'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), membership: Users.$convertermembership @@ -510,7 +486,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, CASE WHEN conversation.category = \'CONTACT\' THEN owner.membership ELSE NULL END AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), Variable(circleId), @@ -526,23 +502,17 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ...generatedlimit.watchedTables, }).map((QueryRow row) => SearchConversationItem( conversationId: row.read('conversationId'), - groupIconUrl: row.readNullable('groupIconUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), + muteUntil: NullAwareTypeConverter.wrapFromSql( + Users.$convertermuteUntil, row.readNullable('muteUntil')), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - groupName: row.readNullable('groupName'), pinTime: NullAwareTypeConverter.wrapFromSql( Conversations.$converterpinTime, row.readNullable('pinTime')), - muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), ownerId: row.readNullable('ownerId'), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), - ownerIdentityNumber: row.read('ownerIdentityNumber'), - fullName: row.readNullable('fullName'), - avatarUrl: row.readNullable('avatarUrl'), + ownerIdentityNumber: row.readNullable('ownerIdentityNumber'), isVerified: row.readNullable('isVerified'), appId: row.readNullable('appId'), membership: Users.$convertermembership @@ -562,7 +532,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { Selectable conversationStorageUsage() { return customSelect( - 'SELECT c.conversation_id, c.owner_id, c.category, c.icon_url, c.name, u.identity_number, u.full_name, u.avatar_url, u.is_verified FROM conversations AS c INNER JOIN users AS u ON u.user_id = c.owner_id WHERE c.category IS NOT NULL', + 'SELECT c.conversation_id, c.owner_id, c.category, u.identity_number, u.is_verified, COALESCE(u.full_name, c.name) AS name, COALESCE(u.avatar_url, c.icon_url) AS avatarUrl FROM conversations AS c LEFT JOIN users AS u ON c.category = \'CONTACT\' AND u.user_id = c.owner_id WHERE c.category IS NOT NULL', variables: [], readsFrom: { conversations, @@ -572,12 +542,10 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { ownerId: row.readNullable('owner_id'), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - iconUrl: row.readNullable('icon_url'), - name: row.readNullable('name'), - identityNumber: row.read('identity_number'), - fullName: row.readNullable('full_name'), - avatarUrl: row.readNullable('avatar_url'), + identityNumber: row.readNullable('identity_number'), isVerified: row.readNullable('is_verified'), + name: row.readNullable('name'), + avatarUrl: row.readNullable('avatarUrl'), )); } @@ -643,22 +611,19 @@ typedef BaseConversationItemCount$where = Expression Function( class ConversationItem { final String conversationId; - final String? groupIconUrl; + final String? avatarUrl; + final String? name; + final DateTime? muteUntil; final ConversationCategory? category; final String? draft; - final String? groupName; final ConversationStatus status; final String? lastReadMessageId; final int? unseenMessageCount; final String? ownerId; final DateTime? pinTime; - final DateTime? muteUntil; final int? expireIn; - final String? avatarUrl; - final String? name; final bool? ownerVerified; - final String ownerIdentityNumber; - final DateTime? ownerMuteUntil; + final String? ownerIdentityNumber; final String? appId; final Membership? membership; final String? content; @@ -678,22 +643,19 @@ class ConversationItem { final UserRelationship? relationship; ConversationItem({ required this.conversationId, - this.groupIconUrl, + this.avatarUrl, + this.name, + this.muteUntil, this.category, this.draft, - this.groupName, required this.status, this.lastReadMessageId, this.unseenMessageCount, this.ownerId, this.pinTime, - this.muteUntil, this.expireIn, - this.avatarUrl, - this.name, this.ownerVerified, - required this.ownerIdentityNumber, - this.ownerMuteUntil, + this.ownerIdentityNumber, this.appId, this.membership, this.content, @@ -715,22 +677,19 @@ class ConversationItem { @override int get hashCode => Object.hashAll([ conversationId, - groupIconUrl, + avatarUrl, + name, + muteUntil, category, draft, - groupName, status, lastReadMessageId, unseenMessageCount, ownerId, pinTime, - muteUntil, expireIn, - avatarUrl, - name, ownerVerified, ownerIdentityNumber, - ownerMuteUntil, appId, membership, content, @@ -754,22 +713,19 @@ class ConversationItem { identical(this, other) || (other is ConversationItem && other.conversationId == this.conversationId && - other.groupIconUrl == this.groupIconUrl && + other.avatarUrl == this.avatarUrl && + other.name == this.name && + other.muteUntil == this.muteUntil && other.category == this.category && other.draft == this.draft && - other.groupName == this.groupName && other.status == this.status && other.lastReadMessageId == this.lastReadMessageId && other.unseenMessageCount == this.unseenMessageCount && other.ownerId == this.ownerId && other.pinTime == this.pinTime && - other.muteUntil == this.muteUntil && other.expireIn == this.expireIn && - other.avatarUrl == this.avatarUrl && - other.name == this.name && other.ownerVerified == this.ownerVerified && other.ownerIdentityNumber == this.ownerIdentityNumber && - other.ownerMuteUntil == this.ownerMuteUntil && other.appId == this.appId && other.membership == this.membership && other.content == this.content && @@ -791,22 +747,19 @@ class ConversationItem { String toString() { return (StringBuffer('ConversationItem(') ..write('conversationId: $conversationId, ') - ..write('groupIconUrl: $groupIconUrl, ') + ..write('avatarUrl: $avatarUrl, ') + ..write('name: $name, ') + ..write('muteUntil: $muteUntil, ') ..write('category: $category, ') ..write('draft: $draft, ') - ..write('groupName: $groupName, ') ..write('status: $status, ') ..write('lastReadMessageId: $lastReadMessageId, ') ..write('unseenMessageCount: $unseenMessageCount, ') ..write('ownerId: $ownerId, ') ..write('pinTime: $pinTime, ') - ..write('muteUntil: $muteUntil, ') ..write('expireIn: $expireIn, ') - ..write('avatarUrl: $avatarUrl, ') - ..write('name: $name, ') ..write('ownerVerified: $ownerVerified, ') ..write('ownerIdentityNumber: $ownerIdentityNumber, ') - ..write('ownerMuteUntil: $ownerMuteUntil, ') ..write('appId: $appId, ') ..write('membership: $membership, ') ..write('content: $content, ') @@ -917,16 +870,13 @@ typedef BaseUnseenConversationCount$where = Expression Function( class SearchConversationItem { final String conversationId; - final String? groupIconUrl; + final String? avatarUrl; + final String? name; + final DateTime? muteUntil; final ConversationCategory? category; - final String? groupName; final DateTime? pinTime; - final DateTime? muteUntil; final String? ownerId; - final DateTime? ownerMuteUntil; - final String ownerIdentityNumber; - final String? fullName; - final String? avatarUrl; + final String? ownerIdentityNumber; final bool? isVerified; final String? appId; final Membership? membership; @@ -940,16 +890,13 @@ class SearchConversationItem { final String? participantFullName; SearchConversationItem({ required this.conversationId, - this.groupIconUrl, + this.avatarUrl, + this.name, + this.muteUntil, this.category, - this.groupName, this.pinTime, - this.muteUntil, this.ownerId, - this.ownerMuteUntil, - required this.ownerIdentityNumber, - this.fullName, - this.avatarUrl, + this.ownerIdentityNumber, this.isVerified, this.appId, this.membership, @@ -963,45 +910,38 @@ class SearchConversationItem { this.participantFullName, }); @override - int get hashCode => Object.hashAll([ - conversationId, - groupIconUrl, - category, - groupName, - pinTime, - muteUntil, - ownerId, - ownerMuteUntil, - ownerIdentityNumber, - fullName, - avatarUrl, - isVerified, - appId, - membership, - messageStatus, - content, - contentType, - senderId, - actionName, - senderFullName, - participantUserId, - participantFullName - ]); + int get hashCode => Object.hash( + conversationId, + avatarUrl, + name, + muteUntil, + category, + pinTime, + ownerId, + ownerIdentityNumber, + isVerified, + appId, + membership, + messageStatus, + content, + contentType, + senderId, + actionName, + senderFullName, + participantUserId, + participantFullName); @override bool operator ==(Object other) => identical(this, other) || (other is SearchConversationItem && other.conversationId == this.conversationId && - other.groupIconUrl == this.groupIconUrl && + other.avatarUrl == this.avatarUrl && + other.name == this.name && + other.muteUntil == this.muteUntil && other.category == this.category && - other.groupName == this.groupName && other.pinTime == this.pinTime && - other.muteUntil == this.muteUntil && other.ownerId == this.ownerId && - other.ownerMuteUntil == this.ownerMuteUntil && other.ownerIdentityNumber == this.ownerIdentityNumber && - other.fullName == this.fullName && - other.avatarUrl == this.avatarUrl && other.isVerified == this.isVerified && other.appId == this.appId && other.membership == this.membership && @@ -1017,16 +957,13 @@ class SearchConversationItem { String toString() { return (StringBuffer('SearchConversationItem(') ..write('conversationId: $conversationId, ') - ..write('groupIconUrl: $groupIconUrl, ') + ..write('avatarUrl: $avatarUrl, ') + ..write('name: $name, ') + ..write('muteUntil: $muteUntil, ') ..write('category: $category, ') - ..write('groupName: $groupName, ') ..write('pinTime: $pinTime, ') - ..write('muteUntil: $muteUntil, ') ..write('ownerId: $ownerId, ') - ..write('ownerMuteUntil: $ownerMuteUntil, ') ..write('ownerIdentityNumber: $ownerIdentityNumber, ') - ..write('fullName: $fullName, ') - ..write('avatarUrl: $avatarUrl, ') ..write('isVerified: $isVerified, ') ..write('appId: $appId, ') ..write('membership: $membership, ') @@ -1080,26 +1017,22 @@ class ConversationStorageUsage { final String conversationId; final String? ownerId; final ConversationCategory? category; - final String? iconUrl; + final String? identityNumber; + final bool? isVerified; final String? name; - final String identityNumber; - final String? fullName; final String? avatarUrl; - final bool? isVerified; ConversationStorageUsage({ required this.conversationId, this.ownerId, this.category, - this.iconUrl, + this.identityNumber, + this.isVerified, this.name, - required this.identityNumber, - this.fullName, this.avatarUrl, - this.isVerified, }); @override - int get hashCode => Object.hash(conversationId, ownerId, category, iconUrl, - name, identityNumber, fullName, avatarUrl, isVerified); + int get hashCode => Object.hash(conversationId, ownerId, category, + identityNumber, isVerified, name, avatarUrl); @override bool operator ==(Object other) => identical(this, other) || @@ -1107,24 +1040,20 @@ class ConversationStorageUsage { other.conversationId == this.conversationId && other.ownerId == this.ownerId && other.category == this.category && - other.iconUrl == this.iconUrl && - other.name == this.name && other.identityNumber == this.identityNumber && - other.fullName == this.fullName && - other.avatarUrl == this.avatarUrl && - other.isVerified == this.isVerified); + other.isVerified == this.isVerified && + other.name == this.name && + other.avatarUrl == this.avatarUrl); @override String toString() { return (StringBuffer('ConversationStorageUsage(') ..write('conversationId: $conversationId, ') ..write('ownerId: $ownerId, ') ..write('category: $category, ') - ..write('iconUrl: $iconUrl, ') - ..write('name: $name, ') ..write('identityNumber: $identityNumber, ') - ..write('fullName: $fullName, ') - ..write('avatarUrl: $avatarUrl, ') - ..write('isVerified: $isVerified') + ..write('isVerified: $isVerified, ') + ..write('name: $name, ') + ..write('avatarUrl: $avatarUrl') ..write(')')) .toString(); } diff --git a/lib/db/dao/message_dao.g.dart b/lib/db/dao/message_dao.g.dart index d9cd592b67..375fd78d4e 100644 --- a/lib/db/dao/message_dao.g.dart +++ b/lib/db/dao/message_dao.g.dart @@ -200,7 +200,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { final expandedmessageId = $expandVar($arrayStartIndex, messageId.length); $arrayStartIndex += messageId.length; return customSelect( - 'SELECT m.message_id AS messageId, m.conversation_id AS conversationId, sender.user_id AS senderId, sender.full_name AS senderFullName, m.category AS type, m.content AS content, m.quote_content AS quoteContent, m.status AS status, c.name AS groupName, c.mute_until AS muteUntil, conversationOwner.mute_until AS ownerMuteUntil, conversationOwner.user_id AS ownerUserId, conversationOwner.full_name AS ownerFullName, m.created_at AS createdAt, c.category AS category, m."action" AS actionName, conversationOwner.relationship AS relationship, pu.full_name AS participantFullName, pu.user_id AS participantUserId FROM messages AS m INNER JOIN users AS sender ON m.user_id = sender.user_id LEFT JOIN conversations AS c ON m.conversation_id = c.conversation_id LEFT JOIN users AS conversationOwner ON c.owner_id = conversationOwner.user_id LEFT JOIN message_mentions AS mm ON m.message_id = mm.message_id LEFT JOIN users AS pu ON pu.user_id = m.participant_id WHERE m.message_id IN ($expandedmessageId) ORDER BY m.created_at DESC', + 'SELECT m.message_id AS messageId, m.conversation_id AS conversationId, sender.user_id AS senderId, sender.full_name AS senderFullName, m.category AS type, m.content AS content, m.quote_content AS quoteContent, m.status AS status, COALESCE(conversationOwner.full_name, c.name) AS name, COALESCE(conversationOwner.mute_until, c.mute_until) AS muteUntil, m.created_at AS createdAt, c.category AS category, m."action" AS actionName, conversationOwner.relationship AS relationship, pu.full_name AS participantFullName, pu.user_id AS participantUserId, c.owner_id AS ownerUserId FROM messages AS m INNER JOIN users AS sender ON m.user_id = sender.user_id LEFT JOIN conversations AS c ON m.conversation_id = c.conversation_id LEFT JOIN users AS conversationOwner ON c.category = \'CONTACT\' AND c.owner_id = conversationOwner.user_id LEFT JOIN message_mentions AS mm ON m.message_id = mm.message_id LEFT JOIN users AS pu ON pu.user_id = m.participant_id WHERE m.message_id IN ($expandedmessageId) ORDER BY m.created_at DESC', variables: [ for (var $ in messageId) Variable($) ], @@ -218,15 +218,9 @@ mixin _$MessageDaoMixin on DatabaseAccessor { content: row.readNullable('content'), quoteContent: row.readNullable('quoteContent'), status: Messages.$converterstatus.fromSql(row.read('status')), - groupName: row.readNullable('groupName'), + name: row.readNullable('name'), muteUntil: NullAwareTypeConverter.wrapFromSql( - Conversations.$convertermuteUntil, - row.readNullable('muteUntil')), - ownerMuteUntil: NullAwareTypeConverter.wrapFromSql( - Users.$convertermuteUntil, - row.readNullable('ownerMuteUntil')), - ownerUserId: row.readNullable('ownerUserId'), - ownerFullName: row.readNullable('ownerFullName'), + Users.$convertermuteUntil, row.readNullable('muteUntil')), createdAt: Messages.$convertercreatedAt.fromSql(row.read('createdAt')), category: Conversations.$convertercategory @@ -236,6 +230,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { .fromSql(row.readNullable('relationship')), participantFullName: row.readNullable('participantFullName'), participantUserId: row.readNullable('participantUserId'), + ownerUserId: row.readNullable('ownerUserId'), )); } @@ -245,7 +240,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { final expandedmessageIds = $expandVar($arrayStartIndex, messageIds.length); $arrayStartIndex += messageIds.length; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.category AS category, c.conversation_id AS conversationId, COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, COALESCE(owner.full_name, c.name) AS name FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.category = \'CONTACT\' AND c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', variables: [ for (var $ in messageIds) Variable($) ], @@ -269,13 +264,11 @@ mixin _$MessageDaoMixin on DatabaseAccessor { membership: Users.$convertermembership .fromSql(row.readNullable('membership')), ownerId: row.readNullable('ownerId'), - groupIconUrl: row.readNullable('groupIconUrl'), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - groupName: row.readNullable('groupName'), conversationId: row.read('conversationId'), - ownerFullName: row.readNullable('ownerFullName'), - ownerAvatarUrl: row.readNullable('ownerAvatarUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), )); } @@ -312,7 +305,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.category AS category, c.conversation_id AS conversationId, COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, COALESCE(owner.full_name, c.name) AS name FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.category = \'CONTACT\' AND c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedlimit.introducedVariables @@ -339,13 +332,11 @@ mixin _$MessageDaoMixin on DatabaseAccessor { membership: Users.$convertermembership .fromSql(row.readNullable('membership')), ownerId: row.readNullable('ownerId'), - groupIconUrl: row.readNullable('groupIconUrl'), category: Conversations.$convertercategory .fromSql(row.readNullable('category')), - groupName: row.readNullable('groupName'), conversationId: row.read('conversationId'), - ownerFullName: row.readNullable('ownerFullName'), - ownerAvatarUrl: row.readNullable('ownerAvatarUrl'), + avatarUrl: row.readNullable('avatarUrl'), + name: row.readNullable('name'), )); } @@ -777,17 +768,15 @@ class NotificationMessage { final String? content; final String? quoteContent; final MessageStatus status; - final String? groupName; + final String? name; final DateTime? muteUntil; - final DateTime? ownerMuteUntil; - final String? ownerUserId; - final String? ownerFullName; final DateTime createdAt; final ConversationCategory? category; final String? actionName; final UserRelationship? relationship; final String? participantFullName; final String? participantUserId; + final String? ownerUserId; NotificationMessage({ required this.messageId, required this.conversationId, @@ -797,17 +786,15 @@ class NotificationMessage { this.content, this.quoteContent, required this.status, - this.groupName, + this.name, this.muteUntil, - this.ownerMuteUntil, - this.ownerUserId, - this.ownerFullName, required this.createdAt, this.category, this.actionName, this.relationship, this.participantFullName, this.participantUserId, + this.ownerUserId, }); @override int get hashCode => Object.hash( @@ -819,17 +806,15 @@ class NotificationMessage { content, quoteContent, status, - groupName, + name, muteUntil, - ownerMuteUntil, - ownerUserId, - ownerFullName, createdAt, category, actionName, relationship, participantFullName, - participantUserId); + participantUserId, + ownerUserId); @override bool operator ==(Object other) => identical(this, other) || @@ -842,17 +827,15 @@ class NotificationMessage { other.content == this.content && other.quoteContent == this.quoteContent && other.status == this.status && - other.groupName == this.groupName && + other.name == this.name && other.muteUntil == this.muteUntil && - other.ownerMuteUntil == this.ownerMuteUntil && - other.ownerUserId == this.ownerUserId && - other.ownerFullName == this.ownerFullName && other.createdAt == this.createdAt && other.category == this.category && other.actionName == this.actionName && other.relationship == this.relationship && other.participantFullName == this.participantFullName && - other.participantUserId == this.participantUserId); + other.participantUserId == this.participantUserId && + other.ownerUserId == this.ownerUserId); @override String toString() { return (StringBuffer('NotificationMessage(') @@ -864,17 +847,15 @@ class NotificationMessage { ..write('content: $content, ') ..write('quoteContent: $quoteContent, ') ..write('status: $status, ') - ..write('groupName: $groupName, ') + ..write('name: $name, ') ..write('muteUntil: $muteUntil, ') - ..write('ownerMuteUntil: $ownerMuteUntil, ') - ..write('ownerUserId: $ownerUserId, ') - ..write('ownerFullName: $ownerFullName, ') ..write('createdAt: $createdAt, ') ..write('category: $category, ') ..write('actionName: $actionName, ') ..write('relationship: $relationship, ') ..write('participantFullName: $participantFullName, ') - ..write('participantUserId: $participantUserId') + ..write('participantUserId: $participantUserId, ') + ..write('ownerUserId: $ownerUserId') ..write(')')) .toString(); } @@ -894,12 +875,10 @@ class SearchMessageDetailItem { final bool? verified; final Membership? membership; final String? ownerId; - final String? groupIconUrl; final ConversationCategory? category; - final String? groupName; final String conversationId; - final String? ownerFullName; - final String? ownerAvatarUrl; + final String? avatarUrl; + final String? name; SearchMessageDetailItem({ required this.messageId, required this.senderId, @@ -914,12 +893,10 @@ class SearchMessageDetailItem { this.verified, this.membership, this.ownerId, - this.groupIconUrl, this.category, - this.groupName, required this.conversationId, - this.ownerFullName, - this.ownerAvatarUrl, + this.avatarUrl, + this.name, }); @override int get hashCode => Object.hash( @@ -936,12 +913,10 @@ class SearchMessageDetailItem { verified, membership, ownerId, - groupIconUrl, category, - groupName, conversationId, - ownerFullName, - ownerAvatarUrl); + avatarUrl, + name); @override bool operator ==(Object other) => identical(this, other) || @@ -959,12 +934,10 @@ class SearchMessageDetailItem { other.verified == this.verified && other.membership == this.membership && other.ownerId == this.ownerId && - other.groupIconUrl == this.groupIconUrl && other.category == this.category && - other.groupName == this.groupName && other.conversationId == this.conversationId && - other.ownerFullName == this.ownerFullName && - other.ownerAvatarUrl == this.ownerAvatarUrl); + other.avatarUrl == this.avatarUrl && + other.name == this.name); @override String toString() { return (StringBuffer('SearchMessageDetailItem(') @@ -981,12 +954,10 @@ class SearchMessageDetailItem { ..write('verified: $verified, ') ..write('membership: $membership, ') ..write('ownerId: $ownerId, ') - ..write('groupIconUrl: $groupIconUrl, ') ..write('category: $category, ') - ..write('groupName: $groupName, ') ..write('conversationId: $conversationId, ') - ..write('ownerFullName: $ownerFullName, ') - ..write('ownerAvatarUrl: $ownerAvatarUrl') + ..write('avatarUrl: $avatarUrl, ') + ..write('name: $name') ..write(')')) .toString(); } diff --git a/lib/db/extension/conversation.dart b/lib/db/extension/conversation.dart index 0a14b74114..d716c33803 100644 --- a/lib/db/extension/conversation.dart +++ b/lib/db/extension/conversation.dart @@ -5,11 +5,7 @@ import '../dao/conversation_dao.dart'; extension SearchConversationItemExtension on SearchConversationItem { bool get isGroupConversation => category == ConversationCategory.group; - bool get isMute => - (isGroupConversation && muteUntil?.isAfter(DateTime.now()) == true) || - (!isGroupConversation && ownerMuteUntil?.isAfter(DateTime.now()) == true); - - String get validName => conversationValidName(groupName, fullName); + bool get isMute => muteUntil?.isAfter(DateTime.now()) == true; } extension ConversationItemExtension on ConversationItem { @@ -28,20 +24,10 @@ extension ConversationItemExtension on ConversationItem { relationship == UserRelationship.stranger && appId == null; - String get validName => conversationValidName(groupName, name); - - bool get isMute => - (isGroupConversation && muteUntil?.isAfter(DateTime.now()) == true) || - (!isGroupConversation && ownerMuteUntil?.isAfter(DateTime.now()) == true); - - DateTime? get validMuteUntil => - isGroupConversation ? muteUntil : ownerMuteUntil; + bool get isMute => muteUntil?.isAfter(DateTime.now()) == true; Duration get expireDuration { final expireIn = this.expireIn ?? 0; return expireIn == 0 ? Duration.zero : Duration(seconds: expireIn); } } - -String conversationValidName(String? groupName, String? fullName) => - groupName?.trim().isNotEmpty == true ? groupName! : fullName ?? ''; diff --git a/lib/db/mixin_database.g.dart b/lib/db/mixin_database.g.dart index e9782c2c9e..a417d00bbb 100644 --- a/lib/db/mixin_database.g.dart +++ b/lib/db/mixin_database.g.dart @@ -16403,7 +16403,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -16470,7 +16470,6 @@ abstract class _$MixinDatabase extends GeneratedDatabase { conversationOwnerId: row.readNullable('conversationOwnerId'), conversionCategory: Conversations.$convertercategory .fromSql(row.readNullable('conversionCategory')), - groupName: row.readNullable('groupName'), assetUrl: row.readNullable('assetUrl'), assetWidth: row.readNullable('assetWidth'), assetHeight: row.readNullable('assetHeight'), @@ -16541,7 +16540,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', variables: [ Variable(conversationId), ...generatedorder.introducedVariables, @@ -16607,7 +16606,6 @@ abstract class _$MixinDatabase extends GeneratedDatabase { conversationOwnerId: row.readNullable('conversationOwnerId'), conversionCategory: Conversations.$convertercategory .fromSql(row.readNullable('conversionCategory')), - groupName: row.readNullable('groupName'), assetUrl: row.readNullable('assetUrl'), assetWidth: row.readNullable('assetWidth'), assetHeight: row.readNullable('assetHeight'), @@ -23028,7 +23026,6 @@ class MessageItem { final Membership? sharedUserMembership; final String? conversationOwnerId; final ConversationCategory? conversionCategory; - final String? groupName; final String? assetUrl; final int? assetWidth; final int? assetHeight; @@ -23089,7 +23086,6 @@ class MessageItem { this.sharedUserMembership, this.conversationOwnerId, this.conversionCategory, - this.groupName, this.assetUrl, this.assetWidth, this.assetHeight, @@ -23152,7 +23148,6 @@ class MessageItem { sharedUserMembership, conversationOwnerId, conversionCategory, - groupName, assetUrl, assetWidth, assetHeight, @@ -23217,7 +23212,6 @@ class MessageItem { other.sharedUserMembership == this.sharedUserMembership && other.conversationOwnerId == this.conversationOwnerId && other.conversionCategory == this.conversionCategory && - other.groupName == this.groupName && other.assetUrl == this.assetUrl && other.assetWidth == this.assetWidth && other.assetHeight == this.assetHeight && @@ -23280,7 +23274,6 @@ class MessageItem { ..write('sharedUserMembership: $sharedUserMembership, ') ..write('conversationOwnerId: $conversationOwnerId, ') ..write('conversionCategory: $conversionCategory, ') - ..write('groupName: $groupName, ') ..write('assetUrl: $assetUrl, ') ..write('assetWidth: $assetWidth, ') ..write('assetHeight: $assetHeight, ') diff --git a/lib/db/moor/dao/common.drift b/lib/db/moor/dao/common.drift index 8bd3f2e41d..a479810759 100644 --- a/lib/db/moor/dao/common.drift +++ b/lib/db/moor/dao/common.drift @@ -37,7 +37,6 @@ SELECT message.message_id AS messageId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, - conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, @@ -116,7 +115,6 @@ SELECT message.message_id AS messageId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, - conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 7a082e731e..81147134f6 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -9,27 +9,21 @@ WHERE $where; _baseConversationItems AS ConversationItem: SELECT conversation.conversation_id AS conversationId, - conversation.icon_url AS groupIconUrl, + COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, + COALESCE(owner.full_name, conversation.name) AS name, + COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, - conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, - conversation.mute_until AS muteUntil, conversation.expire_in as expireIn, - owner.avatar_url AS avatarUrl, - owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, - owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, - CASE - WHEN conversation.category = 'CONTACT' THEN owner.membership - ELSE NULL - END AS membership, + owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, @@ -51,11 +45,11 @@ SELECT conversation.conversation_id AS conversationId, ) AS mentionCount, owner.relationship AS relationship FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id WHERE $where ORDER BY $order @@ -63,27 +57,21 @@ LIMIT $limit; _baseConversationItemsByCircleId AS ConversationItem: SELECT conversation.conversation_id AS conversationId, - conversation.icon_url AS groupIconUrl, + COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, + COALESCE(owner.full_name, conversation.name) AS name, + COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, - conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, - conversation.mute_until AS muteUntil, conversation.expire_in as expireIn, - owner.avatar_url AS avatarUrl, - owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, - owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, - CASE - WHEN conversation.category = 'CONTACT' THEN owner.membership - ELSE NULL - END AS membership, + owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, @@ -105,12 +93,12 @@ SELECT conversation.conversation_id AS conversationId, ) AS mentionCount, owner.relationship AS relationship FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id WHERE $where ORDER BY $order @@ -149,22 +137,16 @@ LIMIT 1; _fuzzySearchConversation AS SearchConversationItem: SELECT conversation.conversation_id AS conversationId, - conversation.icon_url AS groupIconUrl, + COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, + COALESCE(owner.full_name, conversation.name) AS name, + COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, - conversation.name AS groupName, conversation.pin_time AS pinTime, - conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, - owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, - owner.full_name AS fullName, - owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - CASE - WHEN conversation.category = 'CONTACT' THEN owner.membership - ELSE NULL - END AS membership, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -174,10 +156,10 @@ SELECT conversation.conversation_id AS conversationId, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id - LEFT JOIN users participant ON participant.user_id = message.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id WHERE ( ( conversation.category = 'GROUP' @@ -196,22 +178,16 @@ ORDER BY (conversation.category = ' GROUP ' AND conversation.name = :query COLLA _searchConversationItemByIn AS SearchConversationItem: SELECT conversation.conversation_id AS conversationId, - conversation.icon_url AS groupIconUrl, + COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, + COALESCE(owner.full_name, conversation.name) AS name, + COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, - conversation.name AS groupName, conversation.pin_time AS pinTime, - conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, - owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, - owner.full_name AS fullName, - owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - CASE - WHEN conversation.category = 'CONTACT' THEN owner.membership - ELSE NULL - END AS membership, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -221,31 +197,25 @@ SELECT conversation.conversation_id AS conversationId, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id - LEFT JOIN users participant ON participant.user_id = message.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id WHERE conversation.conversation_id IN :ids ORDER BY $order; _fuzzySearchConversationInCircle AS SearchConversationItem: SELECT conversation.conversation_id AS conversationId, - conversation.icon_url AS groupIconUrl, + COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, + COALESCE(owner.full_name, conversation.name) AS name, + COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, - conversation.name AS groupName, conversation.pin_time AS pinTime, - conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, - owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, - owner.full_name AS fullName, - owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, - CASE - WHEN conversation.category = 'CONTACT' THEN owner.membership - ELSE NULL - END AS membership, + owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, @@ -255,11 +225,11 @@ SELECT conversation.conversation_id AS conversationId, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations conversation - INNER JOIN users owner ON owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id - LEFT JOIN users participant ON participant.user_id = message.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id WHERE ((conversation.category = 'GROUP' AND conversation.name LIKE '%' || :query || '%' ESCAPE '\') OR (conversation.category = 'CONTACT' AND (owner.full_name LIKE '%' || :query || '%' ESCAPE '\' OR @@ -274,10 +244,15 @@ ORDER BY (conversation.category = 'GROUP' AND conversation.name = :query COLLATE limit $limit; conversationStorageUsage AS ConversationStorageUsage: -SELECT c.conversation_id, c.owner_id, c.category, c.icon_url, c.name, u.identity_number, - u.full_name, u.avatar_url, u.is_verified +SELECT c.conversation_id, + c.owner_id, + c.category, + u.identity_number, + u.is_verified, + COALESCE(u.full_name, c.name) AS name, + COALESCE(u.avatar_url, c.icon_url) AS avatarUrl FROM conversations c - INNER JOIN users u ON u.user_id = c.owner_id + LEFT JOIN users u ON c.category = 'CONTACT' AND u.user_id = c.owner_id WHERE c.category IS NOT NULL; diff --git a/lib/db/moor/dao/message.drift b/lib/db/moor/dao/message.drift index 5f2ce30c0d..44aa8bd681 100644 --- a/lib/db/moor/dao/message.drift +++ b/lib/db/moor/dao/message.drift @@ -46,38 +46,32 @@ SELECT m.message_id, m.conversation_id, m.user_id, m.category, m.content, m.medi notificationMessage AS NotificationMessage: -SELECT m.message_id AS messageId, - m.conversation_id AS conversationId, - sender.user_id AS senderId, - sender.full_name AS senderFullName, - m.category AS type, - m.content AS content, - m.quote_content AS quoteContent, - m.status AS status, - c.name AS groupName, - c.mute_until AS muteUntil, - conversationOwner.mute_until AS ownerMuteUntil, - conversationOwner.user_id AS ownerUserId, - conversationOwner.full_name AS ownerFullName, - m.created_at AS createdAt, - c.category AS category, - m.action AS actionName, - conversationOwner.relationship AS relationship, - pu.full_name AS participantFullName, - pu.user_id AS participantUserId -FROM messages m - INNER JOIN users sender - ON m.user_id = sender.user_id - LEFT JOIN conversations c - ON m.conversation_id = c.conversation_id - LEFT JOIN users conversationOwner - ON c.owner_id = conversationOwner.user_id - LEFT JOIN message_mentions mm - ON m.message_id = mm.message_id - LEFT JOIN users pu - ON pu.user_id = m.participant_id -WHERE m.message_id in :messageId -ORDER BY m.created_at DESC; +SELECT m.message_id AS messageId, + m.conversation_id AS conversationId, + sender.user_id AS senderId, + sender.full_name AS senderFullName, + m.category AS type, + m.content AS content, + m.quote_content AS quoteContent, + m.status AS status, + COALESCE(conversationOwner.full_name, c.name) AS name, + COALESCE(conversationOwner.mute_until, c.mute_until) AS muteUntil, + m.created_at AS createdAt, + c.category AS category, + m.action AS actionName, + conversationOwner.relationship AS relationship, + pu.full_name AS participantFullName, + pu.user_id AS participantUserId, + c.owner_id AS ownerUserId +FROM messages m + INNER JOIN users sender ON m.user_id = sender.user_id + LEFT JOIN conversations c ON m.conversation_id = c.conversation_id + LEFT JOIN users conversationOwner ON c.category = 'CONTACT' + AND c.owner_id = conversationOwner.user_id + LEFT JOIN message_mentions mm ON m.message_id = mm.message_id + LEFT JOIN users pu ON pu.user_id = m.participant_id +WHERE m.message_id in :messageId +ORDER BY m.created_at DESC; searchMessageByIds AS SearchMessageDetailItem: @@ -94,16 +88,14 @@ SELECT m.message_id messageId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, - c.icon_url AS groupIconUrl, c.category AS category, - c.name AS groupName, c.conversation_id AS conversationId, - owner.full_name AS ownerFullName, - owner.avatar_url AS ownerAvatarUrl + COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, + COALESCE(owner.full_name, c.name) AS name FROM messages m INNER JOIN conversations c ON c.conversation_id = m.conversation_id INNER JOIN users u ON m.user_id = u.user_id - INNER JOIN users owner ON c.owner_id = owner.user_id + INNER JOIN users owner ON c.category = 'CONTACT' AND c.owner_id = owner.user_id WHERE m.message_id IN :messageIds ORDER BY m.created_at DESC, m.rowid DESC; @@ -125,16 +117,14 @@ SELECT m.message_id messageId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, - c.icon_url AS groupIconUrl, c.category AS category, - c.name AS groupName, c.conversation_id AS conversationId, - owner.full_name AS ownerFullName, - owner.avatar_url AS ownerAvatarUrl + COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, + COALESCE(owner.full_name, c.name) AS name FROM messages m INNER JOIN conversations c ON c.conversation_id = m.conversation_id INNER JOIN users u ON m.user_id = u.user_id - INNER JOIN users owner ON c.owner_id = owner.user_id + INNER JOIN users owner ON c.category = 'CONTACT' AND c.owner_id = owner.user_id WHERE $where ORDER BY m.created_at DESC, m.rowid DESC diff --git a/lib/ui/home/chat_slide_page/chat_info_page.dart b/lib/ui/home/chat_slide_page/chat_info_page.dart index 6f422d38f9..9cd6248c6b 100644 --- a/lib/ui/home/chat_slide_page/chat_info_page.dart +++ b/lib/ui/home/chat_slide_page/chat_info_page.dart @@ -305,8 +305,7 @@ class ChatInfoPage extends HookConsumerWidget { description: muting ? Text( DateFormat('yyyy/MM/dd, hh:mm a').format( - conversationState - .conversation!.validMuteUntil! + conversationState.conversation!.muteUntil! .toLocal()), style: TextStyle( color: context.theme.secondaryText, @@ -639,7 +638,7 @@ class _AddToContactsButton extends StatelessWidget { ), onPressed: () { final username = conversation.user?.fullName ?? - conversation.conversation?.validName; + conversation.conversation?.name; assert(username != null, 'ContactsAdd: username should not be null.'); assert(conversation.isGroup != true, diff --git a/lib/ui/home/chat_slide_page/group_invite/group_invite_dialog.dart b/lib/ui/home/chat_slide_page/group_invite/group_invite_dialog.dart index de49a9f7a5..2448f37bdb 100644 --- a/lib/ui/home/chat_slide_page/group_invite/group_invite_dialog.dart +++ b/lib/ui/home/chat_slide_page/group_invite/group_invite_dialog.dart @@ -96,7 +96,6 @@ class _GroupInviteBody extends StatelessWidget { size: 90, conversationId: conversation.conversationId, fullName: conversation.name, - groupIconUrl: conversation.iconUrl, category: conversation.category, userId: conversation.ownerId, ), diff --git a/lib/ui/home/chat_slide_page/groups_in_common_page.dart b/lib/ui/home/chat_slide_page/groups_in_common_page.dart index 56ab0d1a5e..0d392e6f87 100644 --- a/lib/ui/home/chat_slide_page/groups_in_common_page.dart +++ b/lib/ui/home/chat_slide_page/groups_in_common_page.dart @@ -117,7 +117,6 @@ class _GroupConversationItemWidget extends StatelessWidget { size: ConversationPage.conversationItemAvatarSize, conversationId: group.conversationId, category: ConversationCategory.group, - groupIconUrl: group.groupIconUrl, ), const SizedBox(width: 12), Expanded( diff --git a/lib/ui/home/conversation/audio_player_bar.dart b/lib/ui/home/conversation/audio_player_bar.dart index e95ab75e58..b1b1388715 100644 --- a/lib/ui/home/conversation/audio_player_bar.dart +++ b/lib/ui/home/conversation/audio_player_bar.dart @@ -91,7 +91,7 @@ class AudioPlayerBar extends HookConsumerWidget { const SizedBox(width: 8), Flexible( child: Text( - conversationItem?.validName ?? '', + conversationItem?.name ?? '', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( diff --git a/lib/ui/home/conversation/conversation_list.dart b/lib/ui/home/conversation/conversation_list.dart index b18df5f9d3..3a02946cfa 100644 --- a/lib/ui/home/conversation/conversation_list.dart +++ b/lib/ui/home/conversation/conversation_list.dart @@ -190,7 +190,7 @@ class ConversationItemWidget extends StatelessWidget { children: [ Flexible( child: CustomText( - conversation.validName, + conversation.name ?? '', style: TextStyle( color: context.theme.text, fontSize: 16, @@ -378,7 +378,7 @@ class _MessageContent extends HookConsumerWidget { conversation.relationship, conversation.participantFullName, conversation.senderFullName, - conversation.groupName, + conversation.name, conversation.draft, hasDraft, ], diff --git a/lib/ui/home/conversation/menu_wrapper.dart b/lib/ui/home/conversation/menu_wrapper.dart index 345ee5ca0e..8ec9c79d85 100644 --- a/lib/ui/home/conversation/menu_wrapper.dart +++ b/lib/ui/home/conversation/menu_wrapper.dart @@ -138,11 +138,10 @@ class ConversationMenuWrapper extends HookConsumerWidget { image: MenuImage.icon(IconFonts.delete), title: context.l10n.deleteChat, callback: () async { - final name = - conversation?.validName ?? searchConversation!.validName; + final name = conversation?.name ?? searchConversation!.name; final ret = await showConfirmMixinDialog( context, - context.l10n.conversationDeleteTitle(name), + context.l10n.conversationDeleteTitle(name ?? ''), description: context.l10n.deleteChatDescription, ); if (ret == null) return; diff --git a/lib/ui/home/conversation/search_list.dart b/lib/ui/home/conversation/search_list.dart index c0b3cd5769..0721ee4442 100644 --- a/lib/ui/home/conversation/search_list.dart +++ b/lib/ui/home/conversation/search_list.dart @@ -326,14 +326,13 @@ class SearchList extends HookConsumerWidget { child: SearchItem( avatar: ConversationAvatarWidget( conversationId: conversation.conversationId, - fullName: conversation.validName, - groupIconUrl: conversation.groupIconUrl, + fullName: conversation.name, avatarUrl: conversation.avatarUrl, category: conversation.category, size: ConversationPage.conversationItemAvatarSize, userId: conversation.ownerId, ), - name: conversation.validName, + name: conversation.name ?? '', description: description, trailing: BadgesWidget( verified: conversation.isVerified, @@ -743,24 +742,15 @@ class SearchMessageItem extends HookConsumerWidget { ) : ConversationAvatarWidget( conversationId: message.conversationId, - fullName: conversationValidName( - message.groupName, - message.ownerFullName, - ), - groupIconUrl: message.groupIconUrl, - avatarUrl: message.ownerAvatarUrl, + fullName: message.name, + avatarUrl: message.avatarUrl, category: message.category, size: ConversationPage.conversationItemAvatarSize, userId: message.ownerId, ); return SearchItem( avatar: avatar, - name: showSender - ? message.senderFullName ?? '' - : conversationValidName( - message.groupName, - message.ownerFullName, - ), + name: showSender ? message.senderFullName ?? '' : message.name ?? '', trailing: BadgesWidget( verified: message.verified, isBot: message.appId != null, diff --git a/lib/ui/provider/conversation_provider.dart b/lib/ui/provider/conversation_provider.dart index 71bcdf5ae6..a70634714c 100644 --- a/lib/ui/provider/conversation_provider.dart +++ b/lib/ui/provider/conversation_provider.dart @@ -70,7 +70,7 @@ class ConversationState extends Equatable { bool? get isGroup => conversation?.isGroupConversation ?? (user != null ? false : null); - String? get name => conversation?.validName ?? user?.fullName; + String? get name => conversation?.name ?? user?.fullName; String? get identityNumber => conversation?.ownerIdentityNumber ?? user?.identityNumber; diff --git a/lib/ui/setting/storage_usage_list_page.dart b/lib/ui/setting/storage_usage_list_page.dart index 093c63cacf..dcd0388bbd 100644 --- a/lib/ui/setting/storage_usage_list_page.dart +++ b/lib/ui/setting/storage_usage_list_page.dart @@ -5,7 +5,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:watcher/watcher.dart'; import '../../db/dao/conversation_dao.dart'; -import '../../db/extension/conversation.dart'; import '../../utils/extension/extension.dart'; import '../../utils/hook.dart'; import '../../widgets/app_bar.dart'; @@ -98,8 +97,7 @@ class _Item extends HookConsumerWidget { child: CellItem( leading: ConversationAvatarWidget( conversationId: item.conversationId, - fullName: item.fullName, - groupIconUrl: item.iconUrl, + fullName: item.name, avatarUrl: item.avatarUrl, category: item.category, size: 50, @@ -109,7 +107,7 @@ class _Item extends HookConsumerWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(conversationValidName(item.name, item.fullName)), + Text(item.name ?? ''), Text( sizeString, style: TextStyle( @@ -122,7 +120,7 @@ class _Item extends HookConsumerWidget { onTap: () => ref.read(responsiveNavigatorProvider.notifier).pushPage( ResponsiveNavigatorStateNotifier.storageUsageDetail, arguments: ( - conversationValidName(item.name, item.fullName), + item.name, item.conversationId, ), ), diff --git a/lib/widgets/actions/command_palette_action.dart b/lib/widgets/actions/command_palette_action.dart index 33f8145309..0f8b1a7941 100644 --- a/lib/widgets/actions/command_palette_action.dart +++ b/lib/widgets/actions/command_palette_action.dart @@ -9,7 +9,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../constants/resources.dart'; import '../../db/dao/conversation_dao.dart'; import '../../db/database_event_bus.dart'; -import '../../db/extension/conversation.dart'; import '../../db/mixin_database.dart'; import '../../ui/home/conversation/search_list.dart'; import '../../ui/home/intent.dart'; @@ -321,14 +320,13 @@ class CommandPalettePage extends HookConsumerWidget { padding: const EdgeInsets.all(14), avatar: ConversationAvatarWidget( conversationId: conversation.conversationId, - fullName: conversation.validName, - groupIconUrl: conversation.groupIconUrl, + fullName: conversation.name, avatarUrl: conversation.avatarUrl, category: conversation.category, size: 40, userId: conversation.ownerId, ), - name: conversation.validName, + name: conversation.name ?? '', trailing: BadgesWidget( verified: conversation.isVerified, isBot: conversation.appId != null, diff --git a/lib/widgets/avatar_view/avatar_view.dart b/lib/widgets/avatar_view/avatar_view.dart index ee8b4cb1ec..ce1359b38d 100644 --- a/lib/widgets/avatar_view/avatar_view.dart +++ b/lib/widgets/avatar_view/avatar_view.dart @@ -20,7 +20,6 @@ class ConversationAvatarWidget extends HookConsumerWidget { this.conversationId, this.userId, this.fullName, - this.groupIconUrl, this.avatarUrl, this.category, }); @@ -29,7 +28,6 @@ class ConversationAvatarWidget extends HookConsumerWidget { final String? userId; final String? conversationId; final String? fullName; - final String? groupIconUrl; final String? avatarUrl; final ConversationCategory? category; final double size; @@ -39,7 +37,6 @@ class ConversationAvatarWidget extends HookConsumerWidget { final _conversationId = conversation?.conversationId ?? conversationId; assert(_conversationId != null); final _name = conversation?.name ?? fullName; - final _groupIconUrl = conversation?.groupIconUrl ?? groupIconUrl; final _avatarUrl = conversation?.avatarUrl ?? avatarUrl; final _category = conversation?.category ?? category; assert(_category != null); @@ -73,7 +70,7 @@ class ConversationAvatarWidget extends HookConsumerWidget { ? AvatarWidget( userId: _userId, name: _name, - avatarUrl: _avatarUrl ?? _groupIconUrl ?? '', + avatarUrl: _avatarUrl ?? '', size: size) : AvatarPuzzlesWidget(list, size), ), diff --git a/lib/widgets/user_selector/bloc/conversation_filter_cubit.dart b/lib/widgets/user_selector/bloc/conversation_filter_cubit.dart index 394e725718..dddc275d28 100644 --- a/lib/widgets/user_selector/bloc/conversation_filter_cubit.dart +++ b/lib/widgets/user_selector/bloc/conversation_filter_cubit.dart @@ -89,19 +89,17 @@ class ConversationFilterCubit extends Cubit { final keyword = state.keyword!.toLowerCase(); final recentConversations = conversations - .where((element) => element.isGroupConversation - ? element.groupName != null && - element.groupName!.toLowerCase().contains(keyword) - : element.name!.toLowerCase().contains(keyword) || - element.ownerIdentityNumber.toLowerCase().startsWith(keyword)) + .where((element) => + (element.name ?? element.ownerIdentityNumber) + ?.toLowerCase() + .contains(keyword) ?? + false) .toList() ..sort(compareValuesBy((e) { - if (e.isGroupConversation) { - return e.groupName!.toLowerCase().indexOf(keyword); - } final indexOf = e.name?.toLowerCase().indexOf(keyword) ?? -1; if (indexOf != -1) return indexOf; - return e.ownerIdentityNumber.indexOf(keyword); + + return e.ownerIdentityNumber?.indexOf(keyword) ?? -1; })); bool where(User element) => diff --git a/lib/widgets/user_selector/conversation_selector.dart b/lib/widgets/user_selector/conversation_selector.dart index 4d14f1dd75..a7287500ef 100644 --- a/lib/widgets/user_selector/conversation_selector.dart +++ b/lib/widgets/user_selector/conversation_selector.dart @@ -27,7 +27,7 @@ import '../interactive_decorated_box.dart'; import 'bloc/conversation_filter_cubit.dart'; String _getConversationName(dynamic item) { - if (item is ConversationItem) return item.validName; + if (item is ConversationItem) return item.name ?? '?'; if (item is User) return item.fullName ?? '?'; throw ArgumentError('must be ConversationItem or User'); } @@ -390,7 +390,7 @@ class _ConversationSelector extends HookConsumerWidget { child: _BaseItem( keyword: conversationFilterState.keyword, avatar: item.avatarWidget, - title: item.validName, + title: item.name ?? '', verified: item.ownerVerified, isBot: item.isBotConversation, membership: item.membership, From da12f2a3a6444f5bf24205f1ef21381daecb5d09 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 17:03:34 +0900 Subject: [PATCH 06/15] improve: optimize SQL query for conversation data retrieval --- lib/db/dao/conversation_dao.g.dart | 6 +++--- lib/db/moor/dao/conversation.drift | 34 ++++++++++++++++++------------ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index e7bd5ef8cd..ba51019ca4 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -220,7 +220,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -232,8 +232,8 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { messages, snapshots, expiredMessages, - messageMentions, circleConversations, + messageMentions, ...generatedwhere.watchedTables, ...generatedorder.watchedTables, ...generatedlimit.watchedTables, diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 81147134f6..c816f27239 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -37,12 +37,7 @@ SELECT conversation.conversation_id AS conversationId, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, - ( - SELECT COUNT(1) - FROM message_mentions messageMention - WHERE messageMention.conversation_id = conversation.conversation_id - AND messageMention.has_read = 0 - ) AS mentionCount, + COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations conversation LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id @@ -51,6 +46,13 @@ FROM conversations conversation LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id + LEFT JOIN ( + SELECT conversation_id, + COUNT(1) AS count + FROM message_mentions + WHERE has_read = 0 + GROUP BY conversation_id + ) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE $where ORDER BY $order LIMIT $limit; @@ -85,21 +87,25 @@ SELECT conversation.conversation_id AS conversationId, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, - ( - SELECT COUNT(1) - FROM message_mentions messageMention - WHERE messageMention.conversation_id = conversation.conversation_id - AND messageMention.has_read = 0 - ) AS mentionCount, + COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations conversation - LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id + LEFT JOIN users owner ON conversation.category = 'CONTACT' + AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = lastMessage.participant_id + LEFT JOIN users participant ON conversation.category = 'CONTACT' + AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id + LEFT JOIN ( + SELECT conversation_id, + COUNT(1) AS count + FROM message_mentions + WHERE has_read = 0 + GROUP BY conversation_id + ) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE $where ORDER BY $order LIMIT $limit; From 6234b012aeb7a9df0b057dcdfcade9fffca26f81 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 18:15:41 +0900 Subject: [PATCH 07/15] quote --- assets/images/light_receiver_nip_bubble.png | Bin 871 -> 0 bytes assets/images/light_sender_nip_bubble.png | Bin 1043 -> 0 bytes assets/images/plan_basic.png | Bin 0 -> 5766 bytes assets/images/plan_basic.svg | 34 ---- assets/images/plan_premium.png | Bin 0 -> 7237 bytes assets/images/plan_premium.svg | 55 ------ assets/images/plan_standard.png | Bin 0 -> 6387 bytes assets/images/plan_standard.svg | 206 -------------------- lib/constants/resources.dart | 24 +-- lib/db/mixin_database.g.dart | 13 +- lib/db/moor/dao/common.drift | 2 + lib/db/moor/dao/conversation.drift | 10 +- lib/db/moor/dao/message.drift | 40 ++-- lib/db/moor/dao/user.drift | 4 +- lib/widgets/conversation/badges_widget.dart | 8 +- lib/widgets/message/item/quote_message.dart | 129 +++++++++--- lib/widgets/message/message.dart | 19 +- lib/widgets/message/message_bubble.dart | 2 +- lib/widgets/message/message_name.dart | 66 ++++--- pubspec.yaml | 12 +- 20 files changed, 218 insertions(+), 406 deletions(-) delete mode 100644 assets/images/light_receiver_nip_bubble.png delete mode 100644 assets/images/light_sender_nip_bubble.png create mode 100644 assets/images/plan_basic.png delete mode 100644 assets/images/plan_basic.svg create mode 100644 assets/images/plan_premium.png delete mode 100644 assets/images/plan_premium.svg create mode 100644 assets/images/plan_standard.png delete mode 100644 assets/images/plan_standard.svg diff --git a/assets/images/light_receiver_nip_bubble.png b/assets/images/light_receiver_nip_bubble.png deleted file mode 100644 index 213183d5b71c47930079f23c583092b4e4b31c73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 871 zcmV-t1DO1YP) zh^;h%93l<*QLvJRd^>O6yw_Bcjyi=x!BMSN zZ#J9Fm#tRo6YT2&?PH_Scn-Uk&1UU9&Pdd1wcG7>JJvpYBC4uhaRlB9A{5@pya=B7bp@qCo9OgTde|*D;WCxqP2H6HF_g z&)?uW1~Gx!e9t|Jrc$ZA;zIi3@pz`{^}2{v-WPP2FI-Ds{C@v5`dpGb5)Fi|Bm4x{ zvoB7ka|S{a+>vNdZY1;=%*Hk8VY5nTFQfmz(6Py=QK6RA=#iaz%Q9+IsBM0Jek_Da zUa$9*6+(^H=-5oXWkPYj_%0a{y0EZd$NA9oz20y}qtWO^9GY|7k!TDH#i98zcVY&H z7SrzT?j>Y1!=0GH&>7v@+OlI2edZ3#Vkn_IJ3FT#@+}{1CIhD)ZQ%;0dxH-&8!e-_ z{8wnHRJx2d^a3J(^Fdain^CA=gg}MAY$duin$2dH@T|dKwh}#|bThNLxw(X%88PW= zn}O&FrHe_J?DP4~heDz2SoP0}#o{+rRpS`24e@pENHmDM!G&sKkCWJ*(f2-1S(fJ< z4u_irb4Q{<%#frbRD=HDC&4FRQ&Ly7T~U+|+>vN7qpzi|NL`_v&Wo8$W|cb0h4$d{6gc99X1=wmF=X zx=tOiGqAI;b3LQ$z4!YWy+dQk2Tir?_xs8B$RhVb&ZyXFib%BVa=B!;+x_>NjIMjn xJD=k8Kv>g#G6TC@l_j{ik;t$&pq4BwxC@=s3002ovPDHLkV1n|ttA_vp diff --git a/assets/images/light_sender_nip_bubble.png b/assets/images/light_sender_nip_bubble.png deleted file mode 100644 index 49923e7eb514eae1041090a5e218dfeefae5eb1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1043 zcmV+u1nm2XP)M7bd|Lj zlNGe7Ezq_DV~!EFl5%nt2tQ(D|w@E5tsnI|@mpC#k$N)paOw)ww}5I{NXVU^a|s9ED!V(Uj1)@8=YVh9yS z#tvJOekNNzvhW9ck_-|p*W2b<^~mD7cyRI&89ywQ$XkSR^NgWkbUC2$Xj|i0WEJKa zrlP6mBFV9>e)QXO`GDk%V^*XeeM)j{D~V~U5+@GX;9eOgnbb6;g3$3KOGruSsaCw0 zY;doP>6Z_=Oc@y&CrFl1ikH*VoqVQVGqT9a%r0AMYHAV{W(B~L5+Dt{gF=rE?|V>n z1fZxx(5-x6KqDEWDBeL2do8!#cb_ z{d}ivKS_cGQ_Mio_-d}OxJBhU!x<8cR7^q9__7DEogyQ1gM{N0)71OBVRVUA**tS{ z>rAP{GBsN-L++a%MXQEAUQnpB)m_%yeF2J4_*{y2 zDNK9Q_$s7+Ze3!W>?oDDgGP04NUA%$MmGe(8%J6fBtHa~`}%gYiQ1F-~#a zNjBti7QQaMim^$UP{NZF$}}AXYTNujd;}vKkCs(XCpC_x^@`@6=ahFG?g$ix7bR6_ zdy4CAb8CCivl~m}09vUtyrsNjGho7mBfQ`^_|$ua_MwcPGB^1CBtYoh7~4Qd+0eAT zys5JYV&KCEPMjS>a>6tqY~rnZ1z9EXU(af~Z6dLr>8dkK^oa+?`|7~lC%4U+JSG{O z?5))^-PPSz=?8UN(e3=l*C_8h63*})r<@f2N=ykhmIxMt&wqVX6F1*?DDez0S^(tlkVG4;`%S``2Q N002ovPDHLkV1na9=>h-% diff --git a/assets/images/plan_basic.png b/assets/images/plan_basic.png new file mode 100644 index 0000000000000000000000000000000000000000..b61e1e1f1d395a2d83e13208281db38d01dea1bf GIT binary patch literal 5766 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 - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assets/images/plan_premium.png b/assets/images/plan_premium.png new file mode 100644 index 0000000000000000000000000000000000000000..2d001e1129cfe8a5e45c8355cbbd9ffa502ef8cc GIT binary patch literal 7237 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 T13elt00000NkvXXu0mjflQH1| literal 0 HcmV?d00001 diff --git a/assets/images/plan_premium.svg b/assets/images/plan_premium.svg deleted file mode 100644 index 04a19ca1aa..0000000000 --- a/assets/images/plan_premium.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assets/images/plan_standard.png b/assets/images/plan_standard.png new file mode 100644 index 0000000000000000000000000000000000000000..2b45762ef4890087639c05f64df2ac8ae2c8089d GIT binary patch literal 6387 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 B9y - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/lib/constants/resources.dart b/lib/constants/resources.dart index 94679adbab..b4c4bdfd36 100644 --- a/lib/constants/resources.dart +++ b/lib/constants/resources.dart @@ -373,14 +373,6 @@ class Resources { static const String assetsImagesJumpCurrentArrowSvg = 'assets/images/jump_current_arrow.svg'; - /// {@macro assets_generator.assetsImagesLightReceiverNipBubblePng.preview} - static const String assetsImagesLightReceiverNipBubblePng = - 'assets/images/light_receiver_nip_bubble.png'; - - /// {@macro assets_generator.assetsImagesLightSenderNipBubblePng.preview} - static const String assetsImagesLightSenderNipBubblePng = - 'assets/images/light_sender_nip_bubble.png'; - /// {@macro assets_generator.assetsImagesLinkSendSvg.preview} static const String assetsImagesLinkSendSvg = 'assets/images/link_send.svg'; @@ -443,16 +435,16 @@ class Resources { /// {@macro assets_generator.assetsImagesPinArrowSvg.preview} static const String assetsImagesPinArrowSvg = 'assets/images/pin_arrow.svg'; - /// {@macro assets_generator.assetsImagesPlanBasicSvg.preview} - static const String assetsImagesPlanBasicSvg = 'assets/images/plan_basic.svg'; + /// {@macro assets_generator.assetsImagesPlanBasicPng.preview} + static const String assetsImagesPlanBasicPng = 'assets/images/plan_basic.png'; - /// {@macro assets_generator.assetsImagesPlanPremiumSvg.preview} - static const String assetsImagesPlanPremiumSvg = - 'assets/images/plan_premium.svg'; + /// {@macro assets_generator.assetsImagesPlanPremiumPng.preview} + static const String assetsImagesPlanPremiumPng = + 'assets/images/plan_premium.png'; - /// {@macro assets_generator.assetsImagesPlanStandardSvg.preview} - static const String assetsImagesPlanStandardSvg = - 'assets/images/plan_standard.svg'; + /// {@macro assets_generator.assetsImagesPlanStandardPng.preview} + static const String assetsImagesPlanStandardPng = + 'assets/images/plan_standard.png'; /// {@macro assets_generator.assetsImagesPlaySvg.preview} static const String assetsImagesPlaySvg = 'assets/images/play.svg'; diff --git a/lib/db/mixin_database.g.dart b/lib/db/mixin_database.g.dart index e9782c2c9e..36a2e4e174 100644 --- a/lib/db/mixin_database.g.dart +++ b/lib/db/mixin_database.g.dart @@ -16403,7 +16403,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.sticker_id AS stickerId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sender.membership AS membership, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM messages AS message INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN pin_messages AS pinMessage ON message.message_id = pinMessage.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -16459,6 +16459,8 @@ abstract class _$MixinDatabase extends GeneratedDatabase { relationship: Users.$converterrelationship .fromSql(row.readNullable('relationship')), avatarUrl: row.readNullable('avatarUrl'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), sharedUserFullName: row.readNullable('sharedUserFullName'), sharedUserIdentityNumber: row.readNullable('sharedUserIdentityNumber'), @@ -16541,7 +16543,7 @@ abstract class _$MixinDatabase extends GeneratedDatabase { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT message.message_id AS messageId, message.conversation_id AS conversationId, message.category AS type, message.content AS content, message.created_at AS createdAt, message.status AS status, message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, message.name AS mediaName, message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, message.media_width AS mediaWidth, message.media_height AS mediaHeight, message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.quote_message_id AS quoteId, message.quote_content AS quoteContent, message."action" AS actionName, message.shared_user_id AS sharedUserId, message.caption AS caption, sender.user_id AS userId, sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, sender.membership AS membership, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, sharedUser.is_verified AS sharedUserIsVerified, sharedUser.app_id AS sharedUserAppId, sharedUser.membership AS sharedUserMembership, conversation.owner_id AS conversationOwnerId, conversation.category AS conversionCategory, conversation.name AS groupName, sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, sticker.sticker_id AS stickerId, sticker.name AS assetName, sticker.asset_type AS assetType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, COALESCE(snapshot.snapshot_id, safe_snapshot.snapshot_id) AS snapshotId, COALESCE(snapshot.type, safe_snapshot.type) AS snapshotType, COALESCE(snapshot.amount, safe_snapshot.amount) AS snapshotAmount, COALESCE(snapshot.memo, safe_snapshot.memo) AS snapshotMemo, COALESCE(snapshot.asset_id, safe_snapshot.asset_id) AS assetId, COALESCE(asset.symbol, token.symbol) AS assetSymbol, COALESCE(asset.icon_url, token.icon_url) AS assetIcon, chain.icon_url AS chainIcon, hyperlink.site_name AS siteName, hyperlink.site_title AS siteTitle, hyperlink.site_description AS siteDescription, hyperlink.site_image AS siteImage, messageMention.has_read AS mentionRead, em.expire_in AS expireIn, CASE WHEN pinMessage.message_id IS NOT NULL THEN TRUE ELSE FALSE END AS pinned FROM pin_messages AS pinMessage INNER JOIN messages AS message ON message.message_id = pinMessage.message_id INNER JOIN users AS sender ON message.user_id = sender.user_id LEFT JOIN users AS participant ON message.participant_id = participant.user_id LEFT JOIN snapshots AS snapshot ON message.snapshot_id = snapshot.snapshot_id LEFT JOIN safe_snapshots AS safe_snapshot ON message.snapshot_id = safe_snapshot.snapshot_id LEFT JOIN assets AS asset ON snapshot.asset_id = asset.asset_id LEFT JOIN tokens AS token ON safe_snapshot.asset_id = token.asset_id LEFT JOIN chains AS chain ON asset.chain_id = chain.chain_id LEFT JOIN stickers AS sticker ON sticker.sticker_id = message.sticker_id LEFT JOIN hyperlinks AS hyperlink ON message.hyperlink = hyperlink.hyperlink LEFT JOIN users AS sharedUser ON message.shared_user_id = sharedUser.user_id LEFT JOIN conversations AS conversation ON message.conversation_id = conversation.conversation_id LEFT JOIN message_mentions AS messageMention ON message.message_id = messageMention.message_id LEFT JOIN expired_messages AS em ON message.message_id = em.message_id WHERE pinMessage.conversation_id = ?1 ${generatedorder.sql} ${generatedlimit.sql}', variables: [ Variable(conversationId), ...generatedorder.introducedVariables, @@ -16596,6 +16598,8 @@ abstract class _$MixinDatabase extends GeneratedDatabase { relationship: Users.$converterrelationship .fromSql(row.readNullable('relationship')), avatarUrl: row.readNullable('avatarUrl'), + membership: Users.$convertermembership + .fromSql(row.readNullable('membership')), sharedUserFullName: row.readNullable('sharedUserFullName'), sharedUserIdentityNumber: row.readNullable('sharedUserIdentityNumber'), @@ -23020,6 +23024,7 @@ class MessageItem { final String? appId; final UserRelationship? relationship; final String? avatarUrl; + final Membership? membership; final String? sharedUserFullName; final String? sharedUserIdentityNumber; final String? sharedUserAvatarUrl; @@ -23081,6 +23086,7 @@ class MessageItem { this.appId, this.relationship, this.avatarUrl, + this.membership, this.sharedUserFullName, this.sharedUserIdentityNumber, this.sharedUserAvatarUrl, @@ -23144,6 +23150,7 @@ class MessageItem { appId, relationship, avatarUrl, + membership, sharedUserFullName, sharedUserIdentityNumber, sharedUserAvatarUrl, @@ -23209,6 +23216,7 @@ class MessageItem { other.appId == this.appId && other.relationship == this.relationship && other.avatarUrl == this.avatarUrl && + other.membership == this.membership && other.sharedUserFullName == this.sharedUserFullName && other.sharedUserIdentityNumber == this.sharedUserIdentityNumber && other.sharedUserAvatarUrl == this.sharedUserAvatarUrl && @@ -23272,6 +23280,7 @@ class MessageItem { ..write('appId: $appId, ') ..write('relationship: $relationship, ') ..write('avatarUrl: $avatarUrl, ') + ..write('membership: $membership, ') ..write('sharedUserFullName: $sharedUserFullName, ') ..write('sharedUserIdentityNumber: $sharedUserIdentityNumber, ') ..write('sharedUserAvatarUrl: $sharedUserAvatarUrl, ') diff --git a/lib/db/moor/dao/common.drift b/lib/db/moor/dao/common.drift index 8bd3f2e41d..6541f29b44 100644 --- a/lib/db/moor/dao/common.drift +++ b/lib/db/moor/dao/common.drift @@ -29,6 +29,7 @@ SELECT message.message_id AS messageId, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, + sender.membership as membership, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, @@ -108,6 +109,7 @@ SELECT message.message_id AS messageId, sender.app_id AS appId, sender.relationship AS relationship, sender.avatar_url AS avatarUrl, + sender.membership as membership, sharedUser.full_name AS sharedUserFullName, sharedUser.identity_number AS sharedUserIdentityNumber, sharedUser.avatar_url AS sharedUserAvatarUrl, diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 7a082e731e..a4ee3674de 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -182,12 +182,12 @@ WHERE ( ( conversation.category = 'GROUP' AND conversation.name LIKE '%' || :query || '%' ESCAPE '\') OR - (conversation.category = ' CONTACT ' AND - (owner.full_name LIKE ' %' || :query || ' %' ESCAPE ' \ ' OR - owner.identity_number LIKE ' %' || :query || ' %' ESCAPE ' \ ')) + (conversation.category = 'CONTACT' AND + (owner.full_name LIKE '%' || :query || '%' ESCAPE '\' OR + owner.identity_number LIKE '%' || :query || '%' ESCAPE '\')) ) AND $where -ORDER BY (conversation.category = ' GROUP ' AND conversation.name = :query COLLATE NOCASE) - OR (conversation.category = ' CONTACT ' +ORDER BY (conversation.category = 'GROUP' AND conversation.name = :query COLLATE NOCASE) + OR (conversation.category = 'CONTACT' AND (owner.full_name = :query COLLATE NOCASE OR owner.identity_number = :query COLLATE NOCASE)) DESC, conversation.pin_time DESC, diff --git a/lib/db/moor/dao/message.drift b/lib/db/moor/dao/message.drift index 5f2ce30c0d..c2c1940815 100644 --- a/lib/db/moor/dao/message.drift +++ b/lib/db/moor/dao/message.drift @@ -1,32 +1,44 @@ import '../mixin.drift'; _baseQuoteMessageItem AS QuoteMessageItem: -SELECT message.message_id AS messageId, message.conversation_id AS conversationId, +SELECT message.message_id AS messageId, + message.conversation_id AS conversationId, sender.user_id AS userId, - sender.full_name AS userFullName, sender.identity_number AS userIdentityNumber, + sender.full_name AS userFullName, + sender.identity_number AS userIdentityNumber, sender.app_id AS appId, message.category AS type, - message.content AS content, message.created_at AS createdAt, message.status AS status, - message.media_status AS mediaStatus, message.media_waveform AS mediaWaveform, - message.name AS mediaName, message.media_mime_type AS mediaMimeType, + message.content AS content, + message.created_at AS createdAt, + message.status AS status, + message.media_status AS mediaStatus, + message.media_waveform AS mediaWaveform, + message.name AS mediaName, + message.media_mime_type AS mediaMimeType, message.media_size AS mediaSize, - message.media_width AS mediaWidth, message.media_height AS mediaHeight, - message.thumb_image AS thumbImage, message.thumb_url AS thumbUrl, message.media_url AS mediaUrl, + message.media_width AS mediaWidth, + message.media_height AS mediaHeight, + message.thumb_image AS thumbImage, + message.thumb_url AS thumbUrl, + message.media_url AS mediaUrl, message.media_duration AS mediaDuration, message.sticker_id AS stickerId, - sticker.asset_url AS assetUrl, sticker.asset_width AS assetWidth, + sticker.asset_url AS assetUrl, + sticker.asset_width AS assetWidth, sticker.asset_height AS assetHeight, - sticker.name AS assetName, sticker.asset_type AS assetType, + sticker.name AS assetName, + sticker.asset_type AS assetType, message.shared_user_id AS sharedUserId, shareUser.full_name AS sharedUserFullName, shareUser.identity_number AS sharedUserIdentityNumber, - shareUser.avatar_url AS sharedUserAvatarUrl, shareUser.is_verified AS sharedUserIsVerified, + shareUser.avatar_url AS sharedUserAvatarUrl, + shareUser.is_verified AS sharedUserIsVerified, shareUser.app_id AS sharedUserAppId FROM messages message - INNER JOIN users sender ON message.user_id = sender.user_id - LEFT JOIN stickers sticker ON sticker.sticker_id = message.sticker_id - LEFT JOIN users shareUser ON message.shared_user_id = shareUser.user_id - LEFT JOIN message_mentions messageMention ON message.message_id = messageMention.message_id + INNER JOIN users sender ON message.user_id = sender.user_id + LEFT JOIN stickers sticker ON sticker.sticker_id = message.sticker_id + LEFT JOIN users shareUser ON message.shared_user_id = shareUser.user_id + LEFT JOIN message_mentions messageMention ON message.message_id = messageMention.message_id WHERE $where ORDER BY $order LIMIT $limit; diff --git a/lib/db/moor/dao/user.drift b/lib/db/moor/dao/user.drift index 7fe717583a..6b515a6f34 100644 --- a/lib/db/moor/dao/user.drift +++ b/lib/db/moor/dao/user.drift @@ -38,7 +38,7 @@ WHERE $firstFilter AND relationship = 'FRIEND' AND ( full_name LIKE '%' || :username || '%' ESCAPE '\' - OR identity_number LIKE ' %' || :identityNumber || ' %' ESCAPE '\') AND $lastFilter + OR identity_number LIKE '%' || :identityNumber || '%' ESCAPE '\') AND $lastFilter GROUP BY user_id ORDER BY full_name = :username COLLATE nocase OR identity_number = :identityNumber COLLATE nocase DESC; @@ -53,7 +53,7 @@ WHERE $filter AND relationship = 'FRIEND' AND ( full_name LIKE '%' || :username || '%' ESCAPE '\' - OR identity_number LIKE ' %' || :identityNumber || ' %' ESCAPE '\') AND circleConversation.circle_id = :circleId + OR identity_number LIKE '%' || :identityNumber || '%' ESCAPE '\') AND circleConversation.circle_id = :circleId GROUP BY users.user_id ORDER BY full_name = :username COLLATE nocase OR identity_number = :identityNumber COLLATE nocase DESC; diff --git a/lib/widgets/conversation/badges_widget.dart b/lib/widgets/conversation/badges_widget.dart index 3adc777800..812e5f7270 100644 --- a/lib/widgets/conversation/badges_widget.dart +++ b/lib/widgets/conversation/badges_widget.dart @@ -43,11 +43,11 @@ class BadgesWidget extends StatelessWidget { switch ((membership?.isValid, membership?.plan)) { case (true, final plan) when plan != Plan.none: children.add( - SvgPicture.asset( + Image.asset( { - Plan.basic: Resources.assetsImagesPlanBasicSvg, - Plan.standard: Resources.assetsImagesPlanStandardSvg, - Plan.premium: Resources.assetsImagesPlanPremiumSvg, + Plan.basic: Resources.assetsImagesPlanBasicPng, + Plan.standard: Resources.assetsImagesPlanStandardPng, + Plan.premium: Resources.assetsImagesPlanPremiumPng, }[plan]!, width: 16, height: 16, diff --git a/lib/widgets/message/item/quote_message.dart b/lib/widgets/message/item/quote_message.dart index b2dbdef36e..5d1a4ad5c6 100644 --- a/lib/widgets/message/item/quote_message.dart +++ b/lib/widgets/message/item/quote_message.dart @@ -8,12 +8,14 @@ import 'package:flutter_svg/svg.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../../../constants/resources.dart'; +import '../../../db/dao/message_dao.dart'; import '../../../db/extension/message.dart'; import '../../../db/mixin_database.dart'; import '../../../enum/message_category.dart'; import '../../../ui/home/bloc/blink_cubit.dart'; import '../../../ui/home/bloc/message_bloc.dart'; import '../../../ui/provider/conversation_provider.dart'; +import '../../../ui/provider/database_provider.dart'; import '../../../ui/provider/mention_cache_provider.dart'; import '../../../ui/provider/pending_jump_message_provider.dart'; import '../../../utils/color_utils.dart'; @@ -22,6 +24,7 @@ import '../../../utils/hook.dart'; import '../../../utils/logger.dart'; import '../../avatar_view/avatar_view.dart'; import '../../cache_image.dart'; +import '../../conversation/badges_widget.dart'; import '../../high_light_text.dart'; import '../../image.dart'; import '../../sticker_page/sticker_item.dart'; @@ -34,14 +37,14 @@ import 'action_card/action_card_data.dart'; class QuoteMessage extends HookConsumerWidget { const QuoteMessage({ super.key, - this.content, + this.quoteContent, this.quoteMessageId, this.messageId, this.message, this.isTranscriptPage = false, }); - final String? content; + final String? quoteContent; final String? quoteMessageId; final String? messageId; final MessageItem? message; @@ -50,9 +53,9 @@ class QuoteMessage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final decodeMap = useMemoized(() { - if (content == null) return null; - return jsonDecode(content!); - }, [content]); + if (quoteContent == null) return null; + return jsonDecode(quoteContent!); + }, [quoteContent]); if (quoteMessageId?.isEmpty ?? true) return const SizedBox(); var inputMode = false; @@ -67,8 +70,50 @@ class QuoteMessage extends HookConsumerWidget { } else if (decodeMap != null) { quote = mapToQuoteMessage(decodeMap as Map); } - final type = quote?.type as String?; - if (content != null && (type == null || type.isIllegalMessageCategory)) { + + String? type; + String? userId; + String? userFullName; + String? content; + String? thumbUrl; + String? mediaName; + String? assetUrl; + String? assetType; + String? sharedUserId; + String? sharedUserFullName; + String? sharedUserAvatarUrl; + String? sharedUserIdentityNumber; + switch (quote) { + case final quote when quote is QuoteMessageItem: + type = quote.type; + userId = quote.userId; + userFullName = quote.userFullName; + content = quote.content; + thumbUrl = quote.thumbUrl; + mediaName = quote.mediaName; + assetUrl = quote.assetUrl; + assetType = quote.assetType; + sharedUserId = quote.sharedUserId; + sharedUserFullName = quote.sharedUserFullName; + sharedUserAvatarUrl = quote.sharedUserAvatarUrl; + sharedUserIdentityNumber = quote.sharedUserIdentityNumber; + case final quote when quote is MessageItem: + type = quote.type; + userId = quote.userId; + userFullName = quote.userFullName; + content = quote.content; + thumbUrl = quote.thumbUrl; + mediaName = quote.mediaName; + assetUrl = quote.assetUrl; + assetType = quote.assetType; + sharedUserId = quote.sharedUserId; + sharedUserFullName = quote.sharedUserFullName; + sharedUserAvatarUrl = quote.sharedUserAvatarUrl; + sharedUserIdentityNumber = quote.sharedUserIdentityNumber; + } + + if (quoteContent != null && + (type == null || type.isIllegalMessageCategory)) { return _QuoteMessageBase( messageId: messageId, quoteMessageId: quoteMessageId!, @@ -82,15 +127,13 @@ class QuoteMessage extends HookConsumerWidget { onTap: () {}, ); } - final userId = quote?.userId as String?; - final userFullName = quote?.userFullName as String?; if (type.isText) { return HookConsumer( builder: (context, ref, _) { - final rawContent = quote.content as String; + final rawContent = content ?? ''; final mentionCache = ref.read(mentionCacheProvider); - final content = useMemoizedFuture( + final description = useMemoizedFuture( () async => mentionCache.replaceMention( rawContent, await mentionCache.checkMentionCache({rawContent}), @@ -104,7 +147,7 @@ class QuoteMessage extends HookConsumerWidget { quoteMessageId: quoteMessageId!, userId: userId, name: userFullName, - description: content!, + description: description!, inputMode: inputMode, ); }, @@ -158,7 +201,7 @@ class QuoteMessage extends HookConsumerWidget { userId: userId, name: userFullName, image: CacheImage( - quote.thumbUrl as String, + thumbUrl ?? '', placeholder: () => placeholder, errorWidget: () => placeholder, ), @@ -180,7 +223,7 @@ class QuoteMessage extends HookConsumerWidget { Resources.assetsImagesFileSvg, colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), ), - description: quote.mediaName as String? ?? context.l10n.file, + description: mediaName ?? context.l10n.file, inputMode: inputMode, ); } @@ -208,7 +251,7 @@ class QuoteMessage extends HookConsumerWidget { Resources.assetsImagesFileSvg, colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), ), - description: (quote.content! as String).postOptimizeMarkdown, + description: (content ?? '').postOptimizeMarkdown, inputMode: inputMode, ); } @@ -247,8 +290,8 @@ class QuoteMessage extends HookConsumerWidget { userId: userId, name: userFullName, image: StickerItem( - assetUrl: quote.assetUrl as String, - assetType: quote.assetType as String?, + assetUrl: assetUrl ?? '', + assetType: assetType, ), icon: SvgPicture.asset( Resources.assetsImagesStickerSvg, @@ -267,24 +310,24 @@ class QuoteMessage extends HookConsumerWidget { image: Padding( padding: const EdgeInsets.all(6), child: AvatarWidget( - name: quote.sharedUserFullName as String?, - userId: quote.sharedUserId as String?, + name: sharedUserFullName, + userId: sharedUserId, size: 48, - avatarUrl: quote.sharedUserAvatarUrl as String?, + avatarUrl: sharedUserAvatarUrl, ), ), icon: SvgPicture.asset( Resources.assetsImagesContactSvg, colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), ), - description: quote.sharedUserIdentityNumber as String, + description: sharedUserIdentityNumber ?? '', inputMode: inputMode, ); } if (type == MessageCategory.appCard || type == MessageCategory.appButtonGroup) { String? description; - final json = jsonDecode(quote.content as String); + final json = jsonDecode(content ?? ''); switch (type) { case MessageCategory.appButtonGroup: description = (json as List?) @@ -388,7 +431,7 @@ class _QuoteImage extends HookWidget { } } -class _QuoteMessageBase extends StatelessWidget { +class _QuoteMessageBase extends HookWidget { const _QuoteMessageBase({ required this.messageId, required this.quoteMessageId, @@ -419,6 +462,18 @@ class _QuoteMessageBase extends StatelessWidget { final color = userId?.isNotEmpty == true ? getNameColorById(userId!) : context.theme.accent; + + final user = useMemoizedFuture(() async { + if (userId == null) return null; + return context.providerContainer + .read(databaseProvider) + .value + ?.userDao + .userById(userId!) + .getSingleOrNull(); + }, null) + .data; + return ClipRRect( borderRadius: inputMode ? BorderRadius.zero @@ -478,15 +533,25 @@ class _QuoteMessageBase extends StatelessWidget { if (name != null) Padding( padding: const EdgeInsets.only(bottom: 4), - child: CustomText( - name!, - style: TextStyle( - fontSize: - context.messageStyle.secondaryFontSize, - color: color, - height: 1, - ), - maxLines: 1, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + CustomText( + name!, + style: TextStyle( + fontSize: context + .messageStyle.secondaryFontSize, + color: color, + height: 1, + ), + maxLines: 1, + ), + BadgesWidget( + verified: false, + isBot: false, + membership: user?.membership, + ) + ], ), ), Row( diff --git a/lib/widgets/message/message.dart b/lib/widgets/message/message.dart index 08788f3136..1d3d9d086b 100644 --- a/lib/widgets/message/message.dart +++ b/lib/widgets/message/message.dart @@ -852,16 +852,27 @@ class _MessageBubbleMargin extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final userIdentityNumber = useMessageConverter(converter: (m) => m.userIdentityNumber); + final membership = useMessageConverter(converter: (m) => m.membership); final messageColumn = Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ if (userName != null && userId != null) - MessageName( - userName: userName!, - userId: userId!, - userIdentityNumber: userIdentityNumber, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: MessageName( + userName: userName!, + userId: userId!, + userIdentityNumber: userIdentityNumber, + membership: membership, + isBot: false, + verified: false, + ), + ), + ], ), CustomContextMenuWidget( hitTestBehavior: HitTestBehavior.translucent, diff --git a/lib/widgets/message/message_bubble.dart b/lib/widgets/message/message_bubble.dart index 17f2fa1c9b..5f9fb69c5e 100644 --- a/lib/widgets/message/message_bubble.dart +++ b/lib/widgets/message/message_bubble.dart @@ -103,7 +103,7 @@ class MessageBubble extends HookConsumerWidget { return QuoteMessage( messageId: messageId, quoteMessageId: quoteId, - content: quoteContent, + quoteContent: quoteContent, isTranscriptPage: isTranscriptPage, ); }), diff --git a/lib/widgets/message/message_name.dart b/lib/widgets/message/message_name.dart index 53de108129..9a47df8ba9 100644 --- a/lib/widgets/message/message_name.dart +++ b/lib/widgets/message/message_name.dart @@ -1,9 +1,11 @@ import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; import '../../ui/provider/setting_provider.dart'; import '../../utils/color_utils.dart'; import '../../utils/extension/extension.dart'; +import '../conversation/badges_widget.dart'; import '../high_light_text.dart'; import '../interactive_decorated_box.dart'; import '../user/user_dialog.dart'; @@ -14,45 +16,55 @@ class MessageName extends ConsumerWidget { required this.userName, required this.userId, required this.userIdentityNumber, + required this.verified, + required this.isBot, + required this.membership, super.key, }); final String userName; final String userId; final String userIdentityNumber; + final bool? verified; + final bool isBot; + final Membership? membership; @override Widget build(BuildContext context, WidgetRef ref) { final showIdentityNumber = ref.watch( settingProvider.select((value) => value.messageShowIdentityNumber), ); - Widget widget = CustomText( - userName, - style: TextStyle( - fontSize: context.messageStyle.secondaryFontSize, - color: getNameColorById(userId), - ), - ); + final children = [ + CustomText( + userName, + style: TextStyle( + fontSize: context.messageStyle.secondaryFontSize, + color: getNameColorById(userId), + ), + ) + ]; + if (showIdentityNumber && userIdentityNumber != '0') { - widget = Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: [ - widget, - const SizedBox(width: 2), - Padding( - padding: const EdgeInsets.only(bottom: 2), - child: Text( - '@$userIdentityNumber', - style: TextStyle( - fontSize: context.messageStyle.statusFontSize, - color: context.theme.text.withOpacity(0.5), - ), + children + ..add(const SizedBox(width: 2)) + ..add(Padding( + padding: const EdgeInsets.only(bottom: 2), + child: Text( + '@$userIdentityNumber', + style: TextStyle( + fontSize: context.messageStyle.statusFontSize, + color: context.theme.text.withOpacity(0.5), ), - ) - ], - ); + ), + )); } + + children.add(BadgesWidget( + verified: verified, + isBot: isBot, + membership: membership, + )); + return Align( alignment: Alignment.centerLeft, child: InteractiveDecoratedBox( @@ -63,7 +75,11 @@ class MessageName extends ConsumerWidget { left: 10, bottom: 2, ), - child: widget, + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: children, + ), ), ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 1fb54a78d5..cfa68fc32d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -201,12 +201,12 @@ flutter: # the material Icons class. uses-material-design: true assets: - # assets start + # assets start - # GENERATED CODE - DO NOT MODIFY MANUALLY - # ************************************************************************** - # Auto generated by https://github.com/fluttercandies/assets_generator - # ************************************************************************** + # GENERATED CODE - DO NOT MODIFY MANUALLY + # ************************************************************************** + # Auto generated by https://github.com/fluttercandies/assets_generator + # ************************************************************************** - assets/ - assets/fonts/ @@ -250,4 +250,4 @@ msix_config: toast_activator: clsid: "94B64592-528D-48B4-B37B-C82D634F1BE7" arguments: "-ToastActivated" - display_name: "Mixin Messenger" + display_name: "Mixin Messenger" \ No newline at end of file From 71766d873024f0b89bee7f8d1963b70d7e270382 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 18:27:23 +0900 Subject: [PATCH 08/15] Update user_cache_provider to use userCacheProvider in quote_message.dart --- lib/ui/provider/user_cache_provider.dart | 27 +++++++++++++++++++++ lib/widgets/message/item/quote_message.dart | 17 +++---------- 2 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 lib/ui/provider/user_cache_provider.dart diff --git a/lib/ui/provider/user_cache_provider.dart b/lib/ui/provider/user_cache_provider.dart new file mode 100644 index 0000000000..bb03001dbd --- /dev/null +++ b/lib/ui/provider/user_cache_provider.dart @@ -0,0 +1,27 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +import '../../db/dao/user_dao.dart'; +import '../../db/mixin_database.dart'; +import '../../utils/rivepod.dart'; +import 'database_provider.dart'; + +class _UserCacheState extends DistinctStateNotifier { + _UserCacheState(String userId, UserDao? userDao) : super(null) { + if (userDao == null) return; + + userDao.userById(userId).getSingle().then((value) => state = value); + } +} + +// !!! Only query once in 10 minutes !!! +final userCacheProvider = StateNotifierProvider.autoDispose + .family<_UserCacheState, User?, String>((ref, userId) { + // Minimize frequent calls to isBotGroup by keeping it alive for 10 minutes + final keepAlive = ref.keepAlive(); + ref.onDispose( + () => Future.delayed(const Duration(minutes: 10), keepAlive.close), + ); + + return _UserCacheState(userId, + ref.watch(databaseProvider.select((value) => value.value?.userDao))); +}); diff --git a/lib/widgets/message/item/quote_message.dart b/lib/widgets/message/item/quote_message.dart index 5d1a4ad5c6..b506883f5e 100644 --- a/lib/widgets/message/item/quote_message.dart +++ b/lib/widgets/message/item/quote_message.dart @@ -15,9 +15,9 @@ import '../../../enum/message_category.dart'; import '../../../ui/home/bloc/blink_cubit.dart'; import '../../../ui/home/bloc/message_bloc.dart'; import '../../../ui/provider/conversation_provider.dart'; -import '../../../ui/provider/database_provider.dart'; import '../../../ui/provider/mention_cache_provider.dart'; import '../../../ui/provider/pending_jump_message_provider.dart'; +import '../../../ui/provider/user_cache_provider.dart'; import '../../../utils/color_utils.dart'; import '../../../utils/extension/extension.dart'; import '../../../utils/hook.dart'; @@ -431,7 +431,7 @@ class _QuoteImage extends HookWidget { } } -class _QuoteMessageBase extends HookWidget { +class _QuoteMessageBase extends HookConsumerWidget { const _QuoteMessageBase({ required this.messageId, required this.quoteMessageId, @@ -455,7 +455,7 @@ class _QuoteMessageBase extends HookWidget { final VoidCallback? onTap; @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { final iterator = LineSplitter.split(description).iterator; final _description = '${iterator.moveNext() ? iterator.current : ''}${iterator.moveNext() ? '...' : ''}'; @@ -463,16 +463,7 @@ class _QuoteMessageBase extends HookWidget { ? getNameColorById(userId!) : context.theme.accent; - final user = useMemoizedFuture(() async { - if (userId == null) return null; - return context.providerContainer - .read(databaseProvider) - .value - ?.userDao - .userById(userId!) - .getSingleOrNull(); - }, null) - .data; + final user = userId != null ? ref.watch(userCacheProvider(userId!)) : null; return ClipRRect( borderRadius: inputMode From c6b6f97c443dee03c78f7dbde767fc37d7bdd83e Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 18:34:22 +0900 Subject: [PATCH 09/15] chore: update plan badges to use SVG assets --- assets/images/plan_basic.png | Bin 5766 -> 0 bytes assets/images/plan_basic.svg | 21 +++++ assets/images/plan_premium.png | Bin 7237 -> 0 bytes assets/images/plan_premium.svg | 88 ++++++++++++++++++++ assets/images/plan_standard.png | Bin 6387 -> 0 bytes assets/images/plan_standard.svg | 40 +++++++++ lib/constants/resources.dart | 16 ++-- lib/widgets/conversation/badges_widget.dart | 12 +-- 8 files changed, 163 insertions(+), 14 deletions(-) delete mode 100644 assets/images/plan_basic.png create mode 100644 assets/images/plan_basic.svg delete mode 100644 assets/images/plan_premium.png create mode 100644 assets/images/plan_premium.svg delete mode 100644 assets/images/plan_standard.png create mode 100644 assets/images/plan_standard.svg diff --git a/assets/images/plan_basic.png b/assets/images/plan_basic.png deleted file mode 100644 index b61e1e1f1d395a2d83e13208281db38d01dea1bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5766 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 + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/plan_premium.png b/assets/images/plan_premium.png deleted file mode 100644 index 2d001e1129cfe8a5e45c8355cbbd9ffa502ef8cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7237 zcmV-L9J=F)P)a$jY$9pTWE?ABqo9#SE}MloRZ5_m7U64%6`a0D#J@&V(1U# zJ*-sXJmkSbUK~rQild4lTaGN3Ac~|g1KkbuaJ&1?=briO!QZ|RX_BT)QiFZTg9dKj zVXwW``o3>{`%v<8c_@10##iZ`J6GuT_JnPwO?rpiB`=UGME~@>p4!}O$`@|lRX51* zDnh6tKjQ}_KeNXTwzbtWY&$lcnPYfW!ODR{oj@=yY|3RuP3A5FFbz-TaU|y~S9QN3 zif~(8Z1==u^PBSK&6|S!3?4siVD$R+KQ_qju31}?)_5;Bt8LfJOTmm1|2vY&*q{|# zvUlH*;qs}aglR}wDq&Erl%o*6!;K>2POHiX&fW6Xt=|< zHc1N8F?`E4N;BuVp_pY-K@DVy8K#9xF;eO`+IR;cf|n8zN!zf6C`)OZO61buRFvHE ztEDM&&X0?tze>v6w||@eBmsWvz+Qj-YsU7sCr;BNmQ}axJkD*~cP&*2lM!Ysfm~3_ zQcRj$62oHDKspS9WAmsY>+I1V*o1`I^-fbH`HLVMIEnYuYBYts>7HTbYhBl_LqYm1GE#TT)SjDrAci z!!X$5yM&NRM`kcXC`klWl1qb>lBj}knk&k4d}=`omg5D5qj(XS&8$lh+}*F}ynmwX zeZs(Qur5smE;xb2ggc}Yql!G#Lq*NB64Ea$emVweFiyl)- zB2uP=LQfGY36Y#oG#NDtg}@A4NMlAR$*>b?$w{Ut%Vk>RwYr&4rzE?z`?SD%$e7h=(<~+{E7{tDxMfSZPg`_(^G1QCY(`2Iz6ccwS|-xz6Y0KNpzuUlm=2tT*X+SN@CiCT{Z*qTmSwQ zaqHGC^;2Z*2Ky&lSKTz8cuFR&Wm=vgfz^}*ii!YlM-URhGLM?lGYr%71IrJ5$M<~G zw=K(dUCS{|hJF(=&x9y)F5;xfleoz9yv#FP2(my1bBRo0L77xC#b%^Rkp$020vA3z zH42iMjAlH@(pUazKf7_`$7hcIO_{oL>WZ^ZLa)(seaSP|AVx(JSz*Wq0NqE!1OUBC z;M>*ia;3G}YjoR7mG-5V+iUXyw%=v$%dd4$J^YKw0NEg%Dz(t0l?%TA{cjA9lZ0o}Niy&Er{mq-@zLJy=p>w{Aum--DFgT@ zlcE99i$ER}E4qcQm+=JmCdHC&!QO_4jsmhDTY!LnT$DvxR=0qx|PYst{ljg482k znrYy%#43UWXjy!0V49~6-=6!9C4I9bKC?)bOIg!_S*F=oU#qXY^x3tG8|OL~uU=ny z>Fqx~=^q?~$^vMF-??+Ra~}cDqj)ShnKJ~VgVTWlOhaan86{?%Ml!D0EOB10 zCLiWG^TQ>WZodJZB91EzH#fLv2*)?5(4|y6cfPZB_3HXd>u1{Mg%tKT{>P(xj~^YU z`+Ji-3iBiI4z!|SxsGkto1W_dHXH<^5F9UsOp;Q>amEk!#^u4@qgPY-{TcGn+tBSO8XVm7xp|VxR)t4K7_;S%3BO8(ZC_>Y3>{Dc^Z#fAsj#pa`eB z&y@uv^m@HUu)I>Mb~{y1mz?dQ)lr8iH!Kc_kQOqEv-0F5$_B?_IvPgV58m91_xGn6 z`YikG)Af!^U9;P%w_bc1LQFCG=9}9hoFz)XAKxPcJ_!_wZ4w2gMVUuXDjwt4uit{c zB>W=+Q?y6kumoh15CYs{IaF|;QOoFE2npU$4{j5Tx{m8$El zuGOm>8%xbo>&<$r9e9poS$@qhKl576M~|rc-=1fAELEk=jLC6XZk#Q|EX<0d{w&$q z9)x>)qZpetjl+V!{PKGH)JDD9BGvk5F89txcb!z%)+XHiW&#UcA<6%A6Uxua?facC%+22I#g#YtN2Bu_=lLaA(`5 zS*>_hs~LFBR^U<;+ISR|gTX8Z5(BXZ45G3Q&FrYj| zX?Uizq!6bk|BmmH|1Lie*ys4KIceZ}(t<>i)Q2ppVmGRP?+fQIU%0sR;>q#6`0oGT z9v<#b4J^)GJ=Lsly|UT6^1|xM@^Za`nzNEnkRp*J%ek5iGSOLw=mXu}{^oHS%}ZI9 zx-~$(AS(?l(2s28Y{hX*&qi+=gHcqRphO)E2d!4c`GsF@G$GZDJd)*L7)E&lGDlDh z;u&k;LhDS_qrzNJP$6>fnb;5i4}UK(O~!BamRw74T!vRr8Gzxdjb_mP;%gT^clDRM zpZ&w%zjOcT?ntNEL&-I+Zf&eyywqE&S3M73VgT+*6c%D|5|uko2Kn7PhuQ!8gPr(K zzVS3g+494KsTd9-5l6*hM@^6#)jF(c8!D&F4_q6YPEelNJT8hx-M3DiuLVpYutd@6 zEKbJbC<20Tf`Ev@N=Q5i8d{PDc5VIt{;x+5?%(g{qELRPTdjU}>+I^KiwLUed8?OPcRDDvmdtmDT`9NLiO$4`*hjp9Xco@*O<43+FKcK&MBk(ouK2%mL4$t;U0 zvj{AiLyw^xi?q!9C(~I`a9yq?kfcQJb#NvAFM!9KVjBGZdX4w{UzZE;sE(jPZHQ}E z!ws`35w;#bdMowS{^2Zo^x$Y-WFl}YrhD#Ox4Ch)+Xf1{97D#=52O6q_9(r3?;sfu zBT}h&_J#93Z)v$^R{|HSLh%6=0b>LNu7<-%92|_xhY$PMJ4H{gcT88>^x$4DDxUA2 z+gPp-2eS+%pO4NasgLMQOsgFrWwTzZMPWKc6@w9pLy1I|sYR4wGCerRhGAEZbWA0_ z6P)fRCbPkyXh$NXspqL*`p4(al$eyBJUO1u!W3Pr?3I;P<-&!PZoMA(nwuJ@EaTbs zBzgO-y=XX0Bna2v+S;uB%9k%xSC*T0rRtgg@Sm?(8!y(NI$YzW&o5i&&aK#2E}wGs zf*(IV7JK^>4s<1XDxpuP(P>xxrKP$LT0mxzpaLQj8t(F|?M}NLG{N);NRQ$OiZINv z#L|PU4Z)V!u~CgXY|+1fV|KjhItDnIlonhH5-^iiYEHF{(ZPT6_$1F$?s}eCf8m9- z-ud&ZOW>b~2F~9GKMg0?j_@my{QT&PS+E z>|djc$ptcSG@h#{%2caaWuOSwyWp`#*J6jeQQq%QQpdAdZ@J}ZVhvBqayCsOl<62` zp8|mZ^(0rOS(F$?QI#2hdUFtR@xU#h#m@WrL7iTaD?DaTlYDFzM7 zn1M>g=mg`yfOA4&dci@FrC8Vx1w0nOi4l6txPJXhjLo+WX&@Z!ykJOO z%h5P41jm4aFX^_cL9R(OvuC<~ty(ejNGUs@G|L2ms!)dq zBcNGI5EKFLkxJ7fX^6_gLeE_BS-lp(Fu->u8D!vJNd?P-vIG}E94k0k62(X^exVYW z20E586W`A?S>QdII~c%ZVHgQjP(B9TAzS8Vx=KT0QvuR;U^)~MgS<)DEKEv3vkA(< zc+0FtBS2fY&e5a11Ru%KaGnE#`O0#u(rnd$Yf!2KPHzA2Oq`s|$Y>O@YT(m)H6SQG z^7(((BwqD7ZQlR0nC!fjXd`67WvBpka4$m_P_6mY?pq1hWT!PctO8`3(0hLxrvM6U zInnM33=?cP{)JiFD7eyC!K95ca|qqL@-4=;;mU%Q;lLPhQt(A4ND0I+okl=bs20pZ zCPt1R@N8g@p@m_Zl>!UTpu8pM049~g^g2+pB#v@bw_}ew=>= z&H%Dd7MhM2MR`-LCp9we-OWUnAye8fu=Q%7C3BtY^Zm9c5}sIVU%!W zO4chC3-$s^4VgoaWQZ6xq#!@~I7{m-cy?Ox!q$Sz1T(gx-G#g4y>EorRa&G_Oc~ED zGO{qwq;^O3M1`_IwL>vb@|kM^22g=gLd{Y=Pf&9BAjjY=RhAWanUV+!AMrek$O1{{ ze>K5B`awue1~W*nQgvE&a`#VCse24at9BoR`2=OIrR;LA;l23xYp@@nn+hqC7_JE* zQI{_Ip877PDy)@qU1NrxTZp#NU(i1nr8t13sA2V57h$JhM*1Y?y5W;#ofSr{h>0Ror^jIky~*0iIHO%W7(&kH8=xFfsW zfnqP*cwObu977E}X$D~e<&5Q^CYeq-*CS#HgFQ*mIb3nQ(*T>wY%i z^5Uz3(P&pFw4pi~OiT0-*NM~FhIm!4{YHaa{(M~lUDYf9sEHazrto?9z8#Av@63wr z-NU$lG)`B#ZD+05t%QB5dsL-Kj@fNInS;&snjl-)Qo9*o`*S^f%7tfc3G|#ytvOC? z?keNfts7+X)I$^FjkVBTQfj&4GA&)SnF+u_LLAIb)um3W2?WzlFOBC(emt0FKsDBG z)I1Y}HXkUhyQwaZ@gx-UFj3$nnBbNk!^pvdLX8i(<}`J(!xv?XQcyb&r}=~X2ho0i z5Vsn2A zzA%YEFSV-gRI6YR6oeicfBoOAd601G!4FSL&;lmyQlq)TG=&T83%~_s$k{9^5BtM> z`{`jco`zYcSvUUUfBE9NW4RVKN$S3X-xzQ29`yGPjz-|ms2T+2>9vaRBkv$u^F zj?qU6PIpp=c{vb1-<|#eUyw_C`m40M<}b1ayUyfVWC{sS2h6Pq4jBNM@Z($cdX1I7 zk1@j1O#=@wJ046j4HC6l#fB%KhfwH3N}^-LB1{!086QsOP%$%(EaIATyeB_89%Tnd zgKRVoGkrj@wzA}GoL=*7!!<^Gz=A}HC{EIyr-w(|PxnufG>!1O^vrtCZ#5hC;nB&X zSriR{_Yoj20kxuH6SSDh_1Llq?03i?l1H8UVDp&?ajHi^n3eh@i{LZ`1{}5@+h;ho zG4G>jvZa<;V8WSgf?H4Dzi51#Da zmt2IvgUBLAN)0<#VV-{H@i8FkM}y`q@>SJ4f6ZvHu1QOjCkP52m!;iU=p7Ieg<~X5 zSkv??|LXD!hYxeEeR+5`1~h^g3@7mfWu--(hv+YERh`+1)Z9WYZq-bgIIP*Mo1Ip} zTyD3F9nC^a&0vhBPMcghyU}(X zhwtw9@0^T=#~528KzIy^oLVx=<|@ti!~alz!1Fl2e~n0Q*?`6ewix>82f?A|7@7rv zX}ZqgJ>UI{;TRl)&4v4ij=lD)-TJ}fG#O8488U~LNEr{&lyKfOc_VvLmnX_sODBef z89L#uB^NTrT!4z>GIHsfYxbWe*L**zww^c{XSojsy_M8Wi!H2z9seambo}xhMKl971)}-2u6my z$jyWPU=O1a6uoKItCc29YVX44nJ%8PcAg&0hNDS{>?Mu*vDaxfJ-h~ks%H(rOE{%2 zhvO8Oir~QdF$S_QoW~=K3X^F#hw#?Qn+HL_R+pA)r`J~N+B`cMj~;D5-FcA2=>%FR z0j$AS##uc+M#*ZC-oC4YdT;pouy;?dUHeb2GYSIVFaoL%B!pQ^S2Nq`oUq= z=Vit*l;(hMu5~biV4YUmS?zW!tya?q8qW?+j_&V1dv*^M(FcXjP@Xg7AuMtJ;hH2F zC2{@=z7bO95{gjb>`AU#HCJ&f|wtD=w;9B>O1&T@DyCSrv z2YJeY+nMW=Jywr0RC~WbR zh80}~*M2>yee3sU2XUMXN3-$%U^F-!;;^$wvk3(CT%VDlbRvLSh{-W_1o|uCX-LBK z!zK7}fsw`ebFb&7_0kjE@osSCgI8Tv5RAxK}U5%z;I1H0$j1!2EQ<(s*V(3($ zADN4iM`+Ph0W^xjPQ6){e!c(O>5sd)OAUG0FYK z;X0L`Hd%?j6M$*2kGaq=+BR@)8*piA6HTiXeS|B3eTzvbE6Oqj(qdlcFgiqr&j<6xtcO4gZ4^^| z0}GKkxH5xeNmWS`oN~f)vf!8H7*#Wz<9Jyutfe>i@8%zOug9mjfd#se^>CQSJ)CVj zMsC{5c3hVU5B%+xO5iw%F6?oH0`C#LhhGrw4e7gc3}Z3RsKt#rRNELDXyKCRvn~T~ z7eH6zM>nvPnIT=28Rh}XatQMbl$kfCB>TNjcmvC)yyfVIbzZDH;k&mSQGLsivcRb5 zAF9u}Yz6-k>P1fmx*WB~z!s*Nei+)7(HYaOgQ*QhnCh@H!DxsaCzLdY6_q2J+#*(C zd$N!*FQN(0=BLg4)7&uj6Wt`X|DAns7Nnnn_JJ$Qff)j8G4&88AfOk1I;I006i99U zp+1$Cg)m+4Y7CD|E$*W-^i5*=U!>HBcoM--8F5p3Wg*hi7jD7ZMd96U<~PaD?412FhNT5jD5;H%%g>ej>b1k z9B~MVhQpPCZEQy$9b1b<3ixRp6z3tB(!x+N%J?*ybLm>#*$>NGVC>*U3#fAYFQK>mi-!8=mjpC9iGu7Fl>$y{N9=`j-58-R%6A0dda2 T13elt00000NkvXXu0mjflQH1| diff --git a/assets/images/plan_premium.svg b/assets/images/plan_premium.svg new file mode 100644 index 0000000000..5fd0ec51bd --- /dev/null +++ b/assets/images/plan_premium.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/plan_standard.png b/assets/images/plan_standard.png deleted file mode 100644 index 2b45762ef4890087639c05f64df2ac8ae2c8089d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6387 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 B9y + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/constants/resources.dart b/lib/constants/resources.dart index b4c4bdfd36..f10d56c21d 100644 --- a/lib/constants/resources.dart +++ b/lib/constants/resources.dart @@ -435,16 +435,16 @@ class Resources { /// {@macro assets_generator.assetsImagesPinArrowSvg.preview} static const String assetsImagesPinArrowSvg = 'assets/images/pin_arrow.svg'; - /// {@macro assets_generator.assetsImagesPlanBasicPng.preview} - static const String assetsImagesPlanBasicPng = 'assets/images/plan_basic.png'; + /// {@macro assets_generator.assetsImagesPlanBasicSvg.preview} + static const String assetsImagesPlanBasicSvg = 'assets/images/plan_basic.svg'; - /// {@macro assets_generator.assetsImagesPlanPremiumPng.preview} - static const String assetsImagesPlanPremiumPng = - 'assets/images/plan_premium.png'; + /// {@macro assets_generator.assetsImagesPlanPremiumSvg.preview} + static const String assetsImagesPlanPremiumSvg = + 'assets/images/plan_premium.svg'; - /// {@macro assets_generator.assetsImagesPlanStandardPng.preview} - static const String assetsImagesPlanStandardPng = - 'assets/images/plan_standard.png'; + /// {@macro assets_generator.assetsImagesPlanStandardSvg.preview} + static const String assetsImagesPlanStandardSvg = + 'assets/images/plan_standard.svg'; /// {@macro assets_generator.assetsImagesPlaySvg.preview} static const String assetsImagesPlaySvg = 'assets/images/play.svg'; diff --git a/lib/widgets/conversation/badges_widget.dart b/lib/widgets/conversation/badges_widget.dart index 812e5f7270..f4c1c62bc5 100644 --- a/lib/widgets/conversation/badges_widget.dart +++ b/lib/widgets/conversation/badges_widget.dart @@ -43,14 +43,14 @@ class BadgesWidget extends StatelessWidget { switch ((membership?.isValid, membership?.plan)) { case (true, final plan) when plan != Plan.none: children.add( - Image.asset( + SvgPicture.asset( { - Plan.basic: Resources.assetsImagesPlanBasicPng, - Plan.standard: Resources.assetsImagesPlanStandardPng, - Plan.premium: Resources.assetsImagesPlanPremiumPng, + Plan.basic: Resources.assetsImagesPlanBasicSvg, + Plan.standard: Resources.assetsImagesPlanStandardSvg, + Plan.premium: Resources.assetsImagesPlanPremiumSvg, }[plan]!, - width: 16, - height: 16, + width: 14, + height: 14, ), ); default: From dd9c63d07a9d916f70008aa5134914376693c8fa Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 18:59:54 +0900 Subject: [PATCH 10/15] chore: Refactor badges_widget.dart to improve code readability and maintainability --- lib/widgets/conversation/badges_widget.dart | 69 ++++++++------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/lib/widgets/conversation/badges_widget.dart b/lib/widgets/conversation/badges_widget.dart index f4c1c62bc5..980f75e2b3 100644 --- a/lib/widgets/conversation/badges_widget.dart +++ b/lib/widgets/conversation/badges_widget.dart @@ -3,7 +3,6 @@ import 'package:flutter_svg/svg.dart'; import 'package:mixin_bot_sdk_dart/mixin_bot_sdk_dart.dart'; import '../../../constants/resources.dart'; -import '../../utils/extension/extension.dart'; class BadgesWidget extends StatelessWidget { const BadgesWidget({ @@ -18,53 +17,39 @@ class BadgesWidget extends StatelessWidget { @override Widget build(BuildContext context) { - var children = []; - - switch ((verified, isBot)) { - case (true, _): - children.add( - SvgPicture.asset( - Resources.assetsImagesVerifiedSvg, - width: 12, - height: 12, - ), + Widget child; + + switch ((verified, isBot, membership?.isValid, membership?.plan)) { + case (_, _, true, final plan) when plan != Plan.none: + child = SvgPicture.asset( + { + Plan.basic: Resources.assetsImagesPlanBasicSvg, + Plan.standard: Resources.assetsImagesPlanStandardSvg, + Plan.premium: Resources.assetsImagesPlanPremiumSvg, + }[plan]!, + width: 14, + height: 14, ); - case (_, true): - children.add( - SvgPicture.asset( - Resources.assetsImagesBotFillSvg, - width: 12, - height: 12, - ), + case (true, _, _, _): + child = SvgPicture.asset( + Resources.assetsImagesVerifiedSvg, + width: 12, + height: 12, ); - default: - } - - switch ((membership?.isValid, membership?.plan)) { - case (true, final plan) when plan != Plan.none: - children.add( - SvgPicture.asset( - { - Plan.basic: Resources.assetsImagesPlanBasicSvg, - Plan.standard: Resources.assetsImagesPlanStandardSvg, - Plan.premium: Resources.assetsImagesPlanPremiumSvg, - }[plan]!, - width: 14, - height: 14, - ), + case (_, true, _, _): + child = SvgPicture.asset( + Resources.assetsImagesBotFillSvg, + width: 12, + height: 12, ); - default: - } - children = children.joinList(const SizedBox(width: 4)); - - if (children.isNotEmpty) { - children.insert(0, const SizedBox(width: 4)); + default: + return const SizedBox(); } - return Row( - mainAxisSize: MainAxisSize.min, - children: children, + return Padding( + padding: const EdgeInsets.only(left: 4), + child: child, ); } } From 0e6e91ab958db4b4f7e696b41625d317e31a206d Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 19:07:28 +0900 Subject: [PATCH 11/15] Refactor MessageName widget to use Padding for BadgesWidget --- assets/images/plan_basic.svg | 28 +++-- assets/images/plan_premium.svg | 145 +++++++++++++------------- assets/images/plan_standard.svg | 42 ++++---- lib/widgets/message/message_name.dart | 15 ++- 4 files changed, 124 insertions(+), 106 deletions(-) diff --git a/assets/images/plan_basic.svg b/assets/images/plan_basic.svg index 4c1140e5f7..0577fb38e4 100644 --- a/assets/images/plan_basic.svg +++ b/assets/images/plan_basic.svg @@ -1,21 +1,27 @@ - - - - - + + + + - - - + + + + + + + + + + - + - - + + diff --git a/assets/images/plan_premium.svg b/assets/images/plan_premium.svg index 5fd0ec51bd..9fcc1a38d6 100644 --- a/assets/images/plan_premium.svg +++ b/assets/images/plan_premium.svg @@ -1,88 +1,89 @@ - - - - - + + + + + - - - - + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + diff --git a/assets/images/plan_standard.svg b/assets/images/plan_standard.svg index 090f190f18..bbcf2115bb 100644 --- a/assets/images/plan_standard.svg +++ b/assets/images/plan_standard.svg @@ -1,40 +1,46 @@ - - - - - + + + + - - - - - - + + + + + + + + + + + + + - + - + - + - + - + - - + + diff --git a/lib/widgets/message/message_name.dart b/lib/widgets/message/message_name.dart index 9a47df8ba9..a563f9af59 100644 --- a/lib/widgets/message/message_name.dart +++ b/lib/widgets/message/message_name.dart @@ -59,11 +59,16 @@ class MessageName extends ConsumerWidget { )); } - children.add(BadgesWidget( - verified: verified, - isBot: isBot, - membership: membership, - )); + children.add( + Padding( + padding: const EdgeInsets.only(bottom: 3), + child: BadgesWidget( + verified: verified, + isBot: isBot, + membership: membership, + ), + ), + ); return Align( alignment: Alignment.centerLeft, From 8de35eecf1b38dd4fc0fd7abaf5f518e0aeeccbd Mon Sep 17 00:00:00 2001 From: YeungKC Date: Thu, 15 Aug 2024 22:59:25 +0900 Subject: [PATCH 12/15] improve: optimize SQL query for conversation data retrieval --- lib/db/dao/conversation_dao.g.dart | 53 ++++++++++++++---------------- lib/db/dao/message_dao.g.dart | 4 +-- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index dcf286fe79..b3eb22c0bd 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -220,7 +220,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.draft AS draft, conversation.name AS groupName, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.expire_in AS expireIn, owner.avatar_url AS avatarUrl, owner.full_name AS name, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.mute_until AS ownerMuteUntil, owner.app_id AS appId, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, (SELECT COUNT(1) FROM message_mentions AS messageMention WHERE messageMention.conversation_id = conversation.conversation_id AND messageMention.has_read = 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -358,7 +358,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), ...generatedwhere.introducedVariables, @@ -417,7 +417,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedorder.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', variables: [ for (var $ in ids) Variable($), ...generatedorder.introducedVariables @@ -486,7 +486,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, conversation.icon_url AS groupIconUrl, conversation.category AS category, conversation.name AS groupName, conversation.pin_time AS pinTime, conversation.mute_until AS muteUntil, conversation.owner_id AS ownerId, owner.mute_until AS ownerMuteUntil, owner.identity_number AS ownerIdentityNumber, owner.full_name AS fullName, owner.avatar_url AS avatarUrl, owner.is_verified AS isVerified, owner.app_id AS appId, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation INNER JOIN users AS owner ON owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), Variable(circleId), @@ -910,29 +910,26 @@ class SearchConversationItem { this.participantFullName, }); @override - int get hashCode => Object.hashAll([ - conversationId, - groupIconUrl, - category, - groupName, - pinTime, - muteUntil, - ownerId, - ownerMuteUntil, - ownerIdentityNumber, - fullName, - avatarUrl, - isVerified, - appId, - messageStatus, - content, - contentType, - senderId, - actionName, - senderFullName, - participantUserId, - participantFullName - ]); + int get hashCode => Object.hash( + conversationId, + avatarUrl, + name, + muteUntil, + category, + pinTime, + ownerId, + ownerIdentityNumber, + isVerified, + appId, + membership, + messageStatus, + content, + contentType, + senderId, + actionName, + senderFullName, + participantUserId, + participantFullName); @override bool operator ==(Object other) => identical(this, other) || diff --git a/lib/db/dao/message_dao.g.dart b/lib/db/dao/message_dao.g.dart index d6645209bd..375fd78d4e 100644 --- a/lib/db/dao/message_dao.g.dart +++ b/lib/db/dao/message_dao.g.dart @@ -240,7 +240,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { final expandedmessageIds = $expandVar($arrayStartIndex, messageIds.length); $arrayStartIndex += messageIds.length; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.category AS category, c.conversation_id AS conversationId, COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, COALESCE(owner.full_name, c.name) AS name FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.category = \'CONTACT\' AND c.owner_id = owner.user_id WHERE m.message_id IN ($expandedmessageIds) ORDER BY m.created_at DESC, m."rowid" DESC', variables: [ for (var $ in messageIds) Variable($) ], @@ -305,7 +305,7 @@ mixin _$MessageDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, c.owner_id AS ownerId, c.icon_url AS groupIconUrl, c.category AS category, c.name AS groupName, c.conversation_id AS conversationId, owner.full_name AS ownerFullName, owner.avatar_url AS ownerAvatarUrl FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', + 'SELECT m.message_id AS messageId, u.user_id AS senderId, u.avatar_url AS senderAvatarUrl, u.full_name AS senderFullName, m.status AS status, m.category AS type, m.content AS content, m.created_at AS createdAt, m.name AS mediaName, u.app_id AS appId, u.is_verified AS verified, u.membership AS membership, c.owner_id AS ownerId, c.category AS category, c.conversation_id AS conversationId, COALESCE(owner.avatar_url, c.icon_url) AS avatarUrl, COALESCE(owner.full_name, c.name) AS name FROM messages AS m INNER JOIN conversations AS c ON c.conversation_id = m.conversation_id INNER JOIN users AS u ON m.user_id = u.user_id INNER JOIN users AS owner ON c.category = \'CONTACT\' AND c.owner_id = owner.user_id WHERE ${generatedwhere.sql} ORDER BY m.created_at DESC, m."rowid" DESC ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedlimit.introducedVariables From 0654327100910b13805e6975d1050507e794aa65 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Mon, 19 Aug 2024 12:23:18 +0900 Subject: [PATCH 13/15] format --- pubspec.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 84cb0ae90e..09fcc3a5ce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -201,12 +201,12 @@ flutter: # the material Icons class. uses-material-design: true assets: - # assets start + # assets start - # GENERATED CODE - DO NOT MODIFY MANUALLY - # ************************************************************************** - # Auto generated by https://github.com/fluttercandies/assets_generator - # ************************************************************************** + # GENERATED CODE - DO NOT MODIFY MANUALLY + # ************************************************************************** + # Auto generated by https://github.com/fluttercandies/assets_generator + # ************************************************************************** - assets/ - assets/fonts/ From c1160f5e60eb14b80827847638a2e2284562c7cc Mon Sep 17 00:00:00 2001 From: YeungKC Date: Mon, 19 Aug 2024 22:24:38 +0900 Subject: [PATCH 14/15] refactor: improve search --- .../chat_slide_page/search_message_page.dart | 22 +++++++++++-------- lib/ui/home/conversation/search_list.dart | 12 +++++----- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/ui/home/chat_slide_page/search_message_page.dart b/lib/ui/home/chat_slide_page/search_message_page.dart index 42c921d742..e3cc37e926 100644 --- a/lib/ui/home/chat_slide_page/search_message_page.dart +++ b/lib/ui/home/chat_slide_page/search_message_page.dart @@ -17,6 +17,7 @@ import '../../../utils/system/text_input.dart'; import '../../../widgets/action_button.dart'; import '../../../widgets/app_bar.dart'; import '../../../widgets/avatar_view/avatar_view.dart'; +import '../../../widgets/conversation/badges_widget.dart'; import '../../../widgets/high_light_text.dart'; import '../../../widgets/interactive_decorated_box.dart'; import '../../../widgets/search_text_field.dart'; @@ -420,17 +421,20 @@ class _SearchParticipantList extends HookConsumerWidget { size: 38, ), const SizedBox(width: 16), - Expanded( - child: CustomText( - user.fullName ?? '', - style: TextStyle( - fontSize: 16, - color: context.theme.text, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, + CustomText( + user.fullName ?? '', + style: TextStyle( + fontSize: 16, + color: context.theme.text, ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), + BadgesWidget( + verified: user.isVerified, + isBot: user.isBot, + membership: user.membership, + ) ], ), ), diff --git a/lib/ui/home/conversation/search_list.dart b/lib/ui/home/conversation/search_list.dart index c0b3cd5769..4209c181f8 100644 --- a/lib/ui/home/conversation/search_list.dart +++ b/lib/ui/home/conversation/search_list.dart @@ -761,11 +761,13 @@ class SearchMessageItem extends HookConsumerWidget { message.groupName, message.ownerFullName, ), - trailing: BadgesWidget( - verified: message.verified, - isBot: message.appId != null, - membership: message.membership, - ), + trailing: showSender || message.category == ConversationCategory.contact + ? BadgesWidget( + verified: message.verified, + isBot: message.appId != null, + membership: message.membership, + ) + : null, nameHighlight: false, keyword: keyword, descriptionIcon: icon, From d1feb5ef4a44ef3c602ddf7fd280194a99ac5a25 Mon Sep 17 00:00:00 2001 From: YeungKC Date: Mon, 19 Aug 2024 22:47:47 +0900 Subject: [PATCH 15/15] chore: optimize SQL queries for conversation DAO --- lib/db/dao/conversation_dao.g.dart | 10 +++++----- lib/db/moor/dao/conversation.drift | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/db/dao/conversation_dao.g.dart b/lib/db/dao/conversation_dao.g.dart index b3eb22c0bd..e2f0ae68f7 100644 --- a/lib/db/dao/conversation_dao.g.dart +++ b/lib/db/dao/conversation_dao.g.dart @@ -111,7 +111,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -220,7 +220,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.draft AS draft, conversation.status AS status, conversation.last_read_message_id AS lastReadMessageId, conversation.unseen_message_count AS unseenMessageCount, conversation.owner_id AS ownerId, conversation.pin_time AS pinTime, conversation.expire_in AS expireIn, owner.is_verified AS ownerVerified, owner.identity_number AS ownerIdentityNumber, owner.app_id AS appId, owner.membership AS membership, lastMessage.content AS content, lastMessage.category AS contentType, conversation.created_at AS createdAt, lastMessage.created_at AS lastMessageCreatedAt, lastMessage.media_url AS mediaUrl, lastMessage.user_id AS senderId, lastMessage."action" AS actionName, lastMessage.status AS messageStatus, lastMessageSender.full_name AS senderFullName, snapshot.type AS SnapshotType, participant.full_name AS participantFullName, participant.user_id AS participantUserId, em.expire_in AS messageExpireIn, COALESCE(mentionCounts.count, 0) AS mentionCount, owner.relationship AS relationship FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN messages AS lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots AS snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id LEFT JOIN users AS participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages AS em ON lastMessage.message_id = em.message_id LEFT JOIN (SELECT conversation_id, COUNT(1) AS count FROM message_mentions WHERE has_read = 0 GROUP BY conversation_id) AS mentionCounts ON conversation.conversation_id = mentionCounts.conversation_id WHERE ${generatedwhere.sql} ${generatedorder.sql} ${generatedlimit.sql}', variables: [ ...generatedwhere.introducedVariables, ...generatedorder.introducedVariables, @@ -358,7 +358,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), ...generatedwhere.introducedVariables, @@ -417,7 +417,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedorder.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN ($expandedids) ${generatedorder.sql}', variables: [ for (var $ in ids) Variable($), ...generatedorder.introducedVariables @@ -486,7 +486,7 @@ mixin _$ConversationDaoMixin on DatabaseAccessor { startIndex: $arrayStartIndex); $arrayStartIndex += generatedlimit.amountOfVariables; return customSelect( - 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON conversation.category = \'CONTACT\' AND participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', + 'SELECT conversation.conversation_id AS conversationId, COALESCE(owner.avatar_url, conversation.icon_url) AS avatarUrl, COALESCE(owner.full_name, conversation.name) AS name, COALESCE(owner.mute_until, conversation.mute_until) AS muteUntil, conversation.category AS category, conversation.pin_time AS pinTime, conversation.owner_id AS ownerId, owner.identity_number AS ownerIdentityNumber, owner.is_verified AS isVerified, owner.app_id AS appId, owner.membership AS membership, message.status AS messageStatus, message.content AS content, message.category AS contentType, message.user_id AS senderId, message."action" AS actionName, lastMessageSender.full_name AS senderFullName, participant.user_id AS participantUserId, participant.full_name AS participantFullName FROM conversations AS conversation LEFT JOIN users AS owner ON conversation.category = \'CONTACT\' AND owner.user_id = conversation.owner_id LEFT JOIN messages AS message ON conversation.last_message_id = message.message_id LEFT JOIN users AS lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations AS circleConversation ON conversation.conversation_id = circleConversation.conversation_id LEFT JOIN users AS participant ON participant.user_id = message.participant_id WHERE((conversation.category = \'GROUP\' AND conversation.name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')OR(conversation.category = \'CONTACT\' AND(owner.full_name LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\' OR owner.identity_number LIKE \'%\' || ?1 || \'%\' ESCAPE \'\\\')))AND circleConversation.circle_id = ?2 AND ${generatedwhere.sql} ORDER BY(conversation.category = \'GROUP\' AND conversation.name = ?1 COLLATE NOCASE)OR(conversation.category = \'CONTACT\' AND(owner.full_name = ?1 COLLATE NOCASE OR owner.identity_number = ?1 COLLATE NOCASE))DESC, conversation.pin_time DESC, message.created_at DESC ${generatedlimit.sql}', variables: [ Variable(query), Variable(circleId), diff --git a/lib/db/moor/dao/conversation.drift b/lib/db/moor/dao/conversation.drift index 90ffa8efb4..2600cedb44 100644 --- a/lib/db/moor/dao/conversation.drift +++ b/lib/db/moor/dao/conversation.drift @@ -44,7 +44,7 @@ FROM conversations conversation LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = lastMessage.participant_id + LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id LEFT JOIN ( SELECT conversation_id, @@ -96,8 +96,7 @@ FROM conversations conversation LEFT JOIN messages lastMessage ON conversation.last_message_id = lastMessage.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = lastMessage.user_id LEFT JOIN snapshots snapshot ON snapshot.snapshot_id = lastMessage.snapshot_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' - AND participant.user_id = lastMessage.participant_id + LEFT JOIN users participant ON participant.user_id = lastMessage.participant_id LEFT JOIN expired_messages em ON lastMessage.message_id = em.message_id LEFT JOIN ( SELECT conversation_id, @@ -165,7 +164,7 @@ FROM conversations conversation LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id + LEFT JOIN users participant ON participant.user_id = message.participant_id WHERE ( ( conversation.category = 'GROUP' @@ -206,7 +205,7 @@ FROM conversations conversation LEFT JOIN users owner ON conversation.category = 'CONTACT' AND owner.user_id = conversation.owner_id LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id + LEFT JOIN users participant ON participant.user_id = message.participant_id WHERE conversation.conversation_id IN :ids ORDER BY $order; @@ -235,7 +234,7 @@ FROM conversations conversation LEFT JOIN messages message ON conversation.last_message_id = message.message_id LEFT JOIN users lastMessageSender ON lastMessageSender.user_id = message.user_id LEFT JOIN circle_conversations circleConversation ON conversation.conversation_id = circleConversation.conversation_id - LEFT JOIN users participant ON conversation.category = 'CONTACT' AND participant.user_id = message.participant_id + LEFT JOIN users participant ON participant.user_id = message.participant_id WHERE ((conversation.category = 'GROUP' AND conversation.name LIKE '%' || :query || '%' ESCAPE '\') OR (conversation.category = 'CONTACT' AND (owner.full_name LIKE '%' || :query || '%' ESCAPE '\' OR