mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 16:28:40 +00:00
custom avatar
This commit is contained in:
parent
0de6d40aa4
commit
ec095fea9c
26 changed files with 374 additions and 66 deletions
21
ios/Podfile
21
ios/Podfile
|
|
@ -46,8 +46,29 @@ end
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
|
||||||
target.build_configurations.each do |config|
|
target.build_configurations.each do |config|
|
||||||
config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
|
config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
|
||||||
|
|
||||||
|
# You can remove unused permissions here
|
||||||
|
# for more information: https://github.com/Baseflow/flutter-permission-handler/blob/main/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
|
||||||
|
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'$(inherited)',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.camera
|
||||||
|
'PERMISSION_CAMERA=1',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.microphone
|
||||||
|
'PERMISSION_MICROPHONE=1',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.notification
|
||||||
|
'PERMISSION_NOTIFICATIONS=1',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.mediaLibrary
|
||||||
|
'PERMISSION_PHOTOS=1',
|
||||||
|
]
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -339,6 +339,6 @@ SPEC CHECKSUMS:
|
||||||
sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2
|
sqlite3_flutter_libs: f6acaa2172e6bb3e2e70c771661905080e8ebcf2
|
||||||
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
|
||||||
|
|
||||||
PODFILE CHECKSUM: 84a7d8d37f41d292cbd8505494629ed779242400
|
PODFILE CHECKSUM: eda8ac661dab0c3d1e1b175d40ebbf2becd0ce86
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,13 @@
|
||||||
<true/>
|
<true/>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>To create photos that can be shared.</string>
|
<string>To create photos that can be shared.</string>
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
<string>To create videos that can be securely shared.</string>
|
<string>To create videos that can be securely shared.</string>
|
||||||
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||||
|
<string>Store photos in the gallery.</string>
|
||||||
<key>NSFaceIDUsageDescription</key>
|
<key>NSFaceIDUsageDescription</key>
|
||||||
<string>To protect others twonlies!</string>
|
<string>To protect others twonlies!</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,8 @@ class UserCheckbox extends StatelessWidget {
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
InitialsAvatar(
|
ContactAvatar(
|
||||||
displayName,
|
contact: user,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,66 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:twonly/src/database/tables/contacts_table.dart';
|
||||||
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
|
import 'package:twonly/src/json_models/userdata.dart';
|
||||||
|
|
||||||
class InitialsAvatar extends StatelessWidget {
|
class ContactAvatar extends StatelessWidget {
|
||||||
final String displayName;
|
final Contact? contact;
|
||||||
|
final UserData? userData;
|
||||||
final double? fontSize;
|
final double? fontSize;
|
||||||
|
|
||||||
const InitialsAvatar(this.displayName, {super.key, this.fontSize = 20});
|
const ContactAvatar(
|
||||||
|
{super.key, this.contact, this.userData, this.fontSize = 20});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
String displayName = "";
|
||||||
|
String? avatarSvg;
|
||||||
|
|
||||||
|
if (contact != null) {
|
||||||
|
displayName = getContactDisplayName(contact!);
|
||||||
|
avatarSvg = contact!.avatarSvg;
|
||||||
|
} else if (userData != null) {
|
||||||
|
displayName = userData!.displayName;
|
||||||
|
avatarSvg = userData!.avatarSvg;
|
||||||
|
} else {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
double proSize = (fontSize == null) ? 40 : (fontSize! * 2);
|
||||||
|
|
||||||
|
if (avatarSvg != null) {
|
||||||
|
return Container(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
minHeight: 2 * (fontSize ?? 20),
|
||||||
|
minWidth: 2 * (fontSize ?? 20),
|
||||||
|
maxWidth: 2 * (fontSize ?? 20),
|
||||||
|
maxHeight: 2 * (fontSize ?? 20),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
|
child: SizedBox(
|
||||||
|
height: proSize,
|
||||||
|
width: proSize,
|
||||||
|
child: Center(
|
||||||
|
// child: Container(
|
||||||
|
// color: Colors.green,
|
||||||
|
// ),
|
||||||
|
child: SvgPicture.string(
|
||||||
|
avatarSvg,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
print("Error: $error");
|
||||||
|
return Container();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Extract initials from the displayName
|
// Extract initials from the displayName
|
||||||
List<String> nameParts = displayName.split(' ');
|
List<String> nameParts = displayName.split(' ');
|
||||||
String initials = nameParts.map((part) => part[0]).join().toUpperCase();
|
String initials = nameParts.map((part) => part[0]).join().toUpperCase();
|
||||||
|
|
@ -35,8 +88,6 @@ class InitialsAvatar extends StatelessWidget {
|
||||||
|
|
||||||
bool isPro = initials[0] == "T";
|
bool isPro = initials[0] == "T";
|
||||||
|
|
||||||
double proSize = (fontSize == null) ? 40 : (fontSize! * 2);
|
|
||||||
|
|
||||||
return isPro
|
return isPro
|
||||||
? //or 15.0
|
? //or 15.0
|
||||||
Container(
|
Container(
|
||||||
|
|
@ -60,7 +111,10 @@ class InitialsAvatar extends StatelessWidget {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
backgroundColor: avatarColor, radius: fontSize, child: child);
|
backgroundColor: avatarColor,
|
||||||
|
radius: fontSize,
|
||||||
|
child: child,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color _getTextColor(Color color) {
|
Color _getTextColor(Color color) {
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,13 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
|
||||||
.watch();
|
.watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<Contact>> getAllNotBlockedContacts() {
|
||||||
|
return (select(contacts)
|
||||||
|
..where((t) => t.accepted.equals(true) & t.blocked.equals(false))
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||||
|
.get();
|
||||||
|
}
|
||||||
|
|
||||||
Stream<int?> watchContactsBlocked() {
|
Stream<int?> watchContactsBlocked() {
|
||||||
final count = contacts.blocked.count(distinct: true);
|
final count = contacts.blocked.count(distinct: true);
|
||||||
final query = selectOnly(contacts)..where(contacts.blocked.equals(true));
|
final query = selectOnly(contacts)..where(contacts.blocked.equals(true));
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ class Contacts extends Table {
|
||||||
TextColumn get username => text().unique()();
|
TextColumn get username => text().unique()();
|
||||||
TextColumn get displayName => text().nullable()();
|
TextColumn get displayName => text().nullable()();
|
||||||
TextColumn get nickName => text().nullable()();
|
TextColumn get nickName => text().nullable()();
|
||||||
|
TextColumn get avatarSvg => text().nullable()();
|
||||||
|
|
||||||
|
IntColumn get myAvatarCounter => integer().withDefault(Constant(0))();
|
||||||
|
|
||||||
BoolColumn get accepted => boolean().withDefault(Constant(false))();
|
BoolColumn get accepted => boolean().withDefault(Constant(false))();
|
||||||
BoolColumn get requested => boolean().withDefault(Constant(false))();
|
BoolColumn get requested => boolean().withDefault(Constant(false))();
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,20 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
late final GeneratedColumn<String> nickName = GeneratedColumn<String>(
|
late final GeneratedColumn<String> nickName = GeneratedColumn<String>(
|
||||||
'nick_name', aliasedName, true,
|
'nick_name', aliasedName, true,
|
||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
|
static const VerificationMeta _avatarSvgMeta =
|
||||||
|
const VerificationMeta('avatarSvg');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> avatarSvg = GeneratedColumn<String>(
|
||||||
|
'avatar_svg', aliasedName, true,
|
||||||
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
|
static const VerificationMeta _myAvatarCounterMeta =
|
||||||
|
const VerificationMeta('myAvatarCounter');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> myAvatarCounter = GeneratedColumn<int>(
|
||||||
|
'my_avatar_counter', aliasedName, false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: Constant(0));
|
||||||
static const VerificationMeta _acceptedMeta =
|
static const VerificationMeta _acceptedMeta =
|
||||||
const VerificationMeta('accepted');
|
const VerificationMeta('accepted');
|
||||||
@override
|
@override
|
||||||
|
|
@ -129,6 +143,8 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
username,
|
username,
|
||||||
displayName,
|
displayName,
|
||||||
nickName,
|
nickName,
|
||||||
|
avatarSvg,
|
||||||
|
myAvatarCounter,
|
||||||
accepted,
|
accepted,
|
||||||
requested,
|
requested,
|
||||||
blocked,
|
blocked,
|
||||||
|
|
@ -171,6 +187,16 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
context.handle(_nickNameMeta,
|
context.handle(_nickNameMeta,
|
||||||
nickName.isAcceptableOrUnknown(data['nick_name']!, _nickNameMeta));
|
nickName.isAcceptableOrUnknown(data['nick_name']!, _nickNameMeta));
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('avatar_svg')) {
|
||||||
|
context.handle(_avatarSvgMeta,
|
||||||
|
avatarSvg.isAcceptableOrUnknown(data['avatar_svg']!, _avatarSvgMeta));
|
||||||
|
}
|
||||||
|
if (data.containsKey('my_avatar_counter')) {
|
||||||
|
context.handle(
|
||||||
|
_myAvatarCounterMeta,
|
||||||
|
myAvatarCounter.isAcceptableOrUnknown(
|
||||||
|
data['my_avatar_counter']!, _myAvatarCounterMeta));
|
||||||
|
}
|
||||||
if (data.containsKey('accepted')) {
|
if (data.containsKey('accepted')) {
|
||||||
context.handle(_acceptedMeta,
|
context.handle(_acceptedMeta,
|
||||||
accepted.isAcceptableOrUnknown(data['accepted']!, _acceptedMeta));
|
accepted.isAcceptableOrUnknown(data['accepted']!, _acceptedMeta));
|
||||||
|
|
@ -244,6 +270,10 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}display_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}display_name']),
|
||||||
nickName: attachedDatabase.typeMapping
|
nickName: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}nick_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}nick_name']),
|
||||||
|
avatarSvg: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.string, data['${effectivePrefix}avatar_svg']),
|
||||||
|
myAvatarCounter: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.int, data['${effectivePrefix}my_avatar_counter'])!,
|
||||||
accepted: attachedDatabase.typeMapping
|
accepted: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}accepted'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}accepted'])!,
|
||||||
requested: attachedDatabase.typeMapping
|
requested: attachedDatabase.typeMapping
|
||||||
|
|
@ -283,6 +313,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
final String username;
|
final String username;
|
||||||
final String? displayName;
|
final String? displayName;
|
||||||
final String? nickName;
|
final String? nickName;
|
||||||
|
final String? avatarSvg;
|
||||||
|
final int myAvatarCounter;
|
||||||
final bool accepted;
|
final bool accepted;
|
||||||
final bool requested;
|
final bool requested;
|
||||||
final bool blocked;
|
final bool blocked;
|
||||||
|
|
@ -299,6 +331,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
required this.username,
|
required this.username,
|
||||||
this.displayName,
|
this.displayName,
|
||||||
this.nickName,
|
this.nickName,
|
||||||
|
this.avatarSvg,
|
||||||
|
required this.myAvatarCounter,
|
||||||
required this.accepted,
|
required this.accepted,
|
||||||
required this.requested,
|
required this.requested,
|
||||||
required this.blocked,
|
required this.blocked,
|
||||||
|
|
@ -321,6 +355,10 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
if (!nullToAbsent || nickName != null) {
|
if (!nullToAbsent || nickName != null) {
|
||||||
map['nick_name'] = Variable<String>(nickName);
|
map['nick_name'] = Variable<String>(nickName);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || avatarSvg != null) {
|
||||||
|
map['avatar_svg'] = Variable<String>(avatarSvg);
|
||||||
|
}
|
||||||
|
map['my_avatar_counter'] = Variable<int>(myAvatarCounter);
|
||||||
map['accepted'] = Variable<bool>(accepted);
|
map['accepted'] = Variable<bool>(accepted);
|
||||||
map['requested'] = Variable<bool>(requested);
|
map['requested'] = Variable<bool>(requested);
|
||||||
map['blocked'] = Variable<bool>(blocked);
|
map['blocked'] = Variable<bool>(blocked);
|
||||||
|
|
@ -352,6 +390,10 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
nickName: nickName == null && nullToAbsent
|
nickName: nickName == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(nickName),
|
: Value(nickName),
|
||||||
|
avatarSvg: avatarSvg == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(avatarSvg),
|
||||||
|
myAvatarCounter: Value(myAvatarCounter),
|
||||||
accepted: Value(accepted),
|
accepted: Value(accepted),
|
||||||
requested: Value(requested),
|
requested: Value(requested),
|
||||||
blocked: Value(blocked),
|
blocked: Value(blocked),
|
||||||
|
|
@ -380,6 +422,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
username: serializer.fromJson<String>(json['username']),
|
username: serializer.fromJson<String>(json['username']),
|
||||||
displayName: serializer.fromJson<String?>(json['displayName']),
|
displayName: serializer.fromJson<String?>(json['displayName']),
|
||||||
nickName: serializer.fromJson<String?>(json['nickName']),
|
nickName: serializer.fromJson<String?>(json['nickName']),
|
||||||
|
avatarSvg: serializer.fromJson<String?>(json['avatarSvg']),
|
||||||
|
myAvatarCounter: serializer.fromJson<int>(json['myAvatarCounter']),
|
||||||
accepted: serializer.fromJson<bool>(json['accepted']),
|
accepted: serializer.fromJson<bool>(json['accepted']),
|
||||||
requested: serializer.fromJson<bool>(json['requested']),
|
requested: serializer.fromJson<bool>(json['requested']),
|
||||||
blocked: serializer.fromJson<bool>(json['blocked']),
|
blocked: serializer.fromJson<bool>(json['blocked']),
|
||||||
|
|
@ -404,6 +448,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
'username': serializer.toJson<String>(username),
|
'username': serializer.toJson<String>(username),
|
||||||
'displayName': serializer.toJson<String?>(displayName),
|
'displayName': serializer.toJson<String?>(displayName),
|
||||||
'nickName': serializer.toJson<String?>(nickName),
|
'nickName': serializer.toJson<String?>(nickName),
|
||||||
|
'avatarSvg': serializer.toJson<String?>(avatarSvg),
|
||||||
|
'myAvatarCounter': serializer.toJson<int>(myAvatarCounter),
|
||||||
'accepted': serializer.toJson<bool>(accepted),
|
'accepted': serializer.toJson<bool>(accepted),
|
||||||
'requested': serializer.toJson<bool>(requested),
|
'requested': serializer.toJson<bool>(requested),
|
||||||
'blocked': serializer.toJson<bool>(blocked),
|
'blocked': serializer.toJson<bool>(blocked),
|
||||||
|
|
@ -424,6 +470,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
String? username,
|
String? username,
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
|
Value<String?> avatarSvg = const Value.absent(),
|
||||||
|
int? myAvatarCounter,
|
||||||
bool? accepted,
|
bool? accepted,
|
||||||
bool? requested,
|
bool? requested,
|
||||||
bool? blocked,
|
bool? blocked,
|
||||||
|
|
@ -440,6 +488,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
displayName: displayName.present ? displayName.value : this.displayName,
|
displayName: displayName.present ? displayName.value : this.displayName,
|
||||||
nickName: nickName.present ? nickName.value : this.nickName,
|
nickName: nickName.present ? nickName.value : this.nickName,
|
||||||
|
avatarSvg: avatarSvg.present ? avatarSvg.value : this.avatarSvg,
|
||||||
|
myAvatarCounter: myAvatarCounter ?? this.myAvatarCounter,
|
||||||
accepted: accepted ?? this.accepted,
|
accepted: accepted ?? this.accepted,
|
||||||
requested: requested ?? this.requested,
|
requested: requested ?? this.requested,
|
||||||
blocked: blocked ?? this.blocked,
|
blocked: blocked ?? this.blocked,
|
||||||
|
|
@ -465,6 +515,10 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
displayName:
|
displayName:
|
||||||
data.displayName.present ? data.displayName.value : this.displayName,
|
data.displayName.present ? data.displayName.value : this.displayName,
|
||||||
nickName: data.nickName.present ? data.nickName.value : this.nickName,
|
nickName: data.nickName.present ? data.nickName.value : this.nickName,
|
||||||
|
avatarSvg: data.avatarSvg.present ? data.avatarSvg.value : this.avatarSvg,
|
||||||
|
myAvatarCounter: data.myAvatarCounter.present
|
||||||
|
? data.myAvatarCounter.value
|
||||||
|
: this.myAvatarCounter,
|
||||||
accepted: data.accepted.present ? data.accepted.value : this.accepted,
|
accepted: data.accepted.present ? data.accepted.value : this.accepted,
|
||||||
requested: data.requested.present ? data.requested.value : this.requested,
|
requested: data.requested.present ? data.requested.value : this.requested,
|
||||||
blocked: data.blocked.present ? data.blocked.value : this.blocked,
|
blocked: data.blocked.present ? data.blocked.value : this.blocked,
|
||||||
|
|
@ -498,6 +552,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
..write('username: $username, ')
|
..write('username: $username, ')
|
||||||
..write('displayName: $displayName, ')
|
..write('displayName: $displayName, ')
|
||||||
..write('nickName: $nickName, ')
|
..write('nickName: $nickName, ')
|
||||||
|
..write('avatarSvg: $avatarSvg, ')
|
||||||
|
..write('myAvatarCounter: $myAvatarCounter, ')
|
||||||
..write('accepted: $accepted, ')
|
..write('accepted: $accepted, ')
|
||||||
..write('requested: $requested, ')
|
..write('requested: $requested, ')
|
||||||
..write('blocked: $blocked, ')
|
..write('blocked: $blocked, ')
|
||||||
|
|
@ -519,6 +575,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
username,
|
username,
|
||||||
displayName,
|
displayName,
|
||||||
nickName,
|
nickName,
|
||||||
|
avatarSvg,
|
||||||
|
myAvatarCounter,
|
||||||
accepted,
|
accepted,
|
||||||
requested,
|
requested,
|
||||||
blocked,
|
blocked,
|
||||||
|
|
@ -538,6 +596,8 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
other.username == this.username &&
|
other.username == this.username &&
|
||||||
other.displayName == this.displayName &&
|
other.displayName == this.displayName &&
|
||||||
other.nickName == this.nickName &&
|
other.nickName == this.nickName &&
|
||||||
|
other.avatarSvg == this.avatarSvg &&
|
||||||
|
other.myAvatarCounter == this.myAvatarCounter &&
|
||||||
other.accepted == this.accepted &&
|
other.accepted == this.accepted &&
|
||||||
other.requested == this.requested &&
|
other.requested == this.requested &&
|
||||||
other.blocked == this.blocked &&
|
other.blocked == this.blocked &&
|
||||||
|
|
@ -556,6 +616,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
final Value<String> username;
|
final Value<String> username;
|
||||||
final Value<String?> displayName;
|
final Value<String?> displayName;
|
||||||
final Value<String?> nickName;
|
final Value<String?> nickName;
|
||||||
|
final Value<String?> avatarSvg;
|
||||||
|
final Value<int> myAvatarCounter;
|
||||||
final Value<bool> accepted;
|
final Value<bool> accepted;
|
||||||
final Value<bool> requested;
|
final Value<bool> requested;
|
||||||
final Value<bool> blocked;
|
final Value<bool> blocked;
|
||||||
|
|
@ -572,6 +634,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
this.username = const Value.absent(),
|
this.username = const Value.absent(),
|
||||||
this.displayName = const Value.absent(),
|
this.displayName = const Value.absent(),
|
||||||
this.nickName = const Value.absent(),
|
this.nickName = const Value.absent(),
|
||||||
|
this.avatarSvg = const Value.absent(),
|
||||||
|
this.myAvatarCounter = const Value.absent(),
|
||||||
this.accepted = const Value.absent(),
|
this.accepted = const Value.absent(),
|
||||||
this.requested = const Value.absent(),
|
this.requested = const Value.absent(),
|
||||||
this.blocked = const Value.absent(),
|
this.blocked = const Value.absent(),
|
||||||
|
|
@ -589,6 +653,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
required String username,
|
required String username,
|
||||||
this.displayName = const Value.absent(),
|
this.displayName = const Value.absent(),
|
||||||
this.nickName = const Value.absent(),
|
this.nickName = const Value.absent(),
|
||||||
|
this.avatarSvg = const Value.absent(),
|
||||||
|
this.myAvatarCounter = const Value.absent(),
|
||||||
this.accepted = const Value.absent(),
|
this.accepted = const Value.absent(),
|
||||||
this.requested = const Value.absent(),
|
this.requested = const Value.absent(),
|
||||||
this.blocked = const Value.absent(),
|
this.blocked = const Value.absent(),
|
||||||
|
|
@ -606,6 +672,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Expression<String>? username,
|
Expression<String>? username,
|
||||||
Expression<String>? displayName,
|
Expression<String>? displayName,
|
||||||
Expression<String>? nickName,
|
Expression<String>? nickName,
|
||||||
|
Expression<String>? avatarSvg,
|
||||||
|
Expression<int>? myAvatarCounter,
|
||||||
Expression<bool>? accepted,
|
Expression<bool>? accepted,
|
||||||
Expression<bool>? requested,
|
Expression<bool>? requested,
|
||||||
Expression<bool>? blocked,
|
Expression<bool>? blocked,
|
||||||
|
|
@ -623,6 +691,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (username != null) 'username': username,
|
if (username != null) 'username': username,
|
||||||
if (displayName != null) 'display_name': displayName,
|
if (displayName != null) 'display_name': displayName,
|
||||||
if (nickName != null) 'nick_name': nickName,
|
if (nickName != null) 'nick_name': nickName,
|
||||||
|
if (avatarSvg != null) 'avatar_svg': avatarSvg,
|
||||||
|
if (myAvatarCounter != null) 'my_avatar_counter': myAvatarCounter,
|
||||||
if (accepted != null) 'accepted': accepted,
|
if (accepted != null) 'accepted': accepted,
|
||||||
if (requested != null) 'requested': requested,
|
if (requested != null) 'requested': requested,
|
||||||
if (blocked != null) 'blocked': blocked,
|
if (blocked != null) 'blocked': blocked,
|
||||||
|
|
@ -645,6 +715,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Value<String>? username,
|
Value<String>? username,
|
||||||
Value<String?>? displayName,
|
Value<String?>? displayName,
|
||||||
Value<String?>? nickName,
|
Value<String?>? nickName,
|
||||||
|
Value<String?>? avatarSvg,
|
||||||
|
Value<int>? myAvatarCounter,
|
||||||
Value<bool>? accepted,
|
Value<bool>? accepted,
|
||||||
Value<bool>? requested,
|
Value<bool>? requested,
|
||||||
Value<bool>? blocked,
|
Value<bool>? blocked,
|
||||||
|
|
@ -661,6 +733,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
displayName: displayName ?? this.displayName,
|
displayName: displayName ?? this.displayName,
|
||||||
nickName: nickName ?? this.nickName,
|
nickName: nickName ?? this.nickName,
|
||||||
|
avatarSvg: avatarSvg ?? this.avatarSvg,
|
||||||
|
myAvatarCounter: myAvatarCounter ?? this.myAvatarCounter,
|
||||||
accepted: accepted ?? this.accepted,
|
accepted: accepted ?? this.accepted,
|
||||||
requested: requested ?? this.requested,
|
requested: requested ?? this.requested,
|
||||||
blocked: blocked ?? this.blocked,
|
blocked: blocked ?? this.blocked,
|
||||||
|
|
@ -691,6 +765,12 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (nickName.present) {
|
if (nickName.present) {
|
||||||
map['nick_name'] = Variable<String>(nickName.value);
|
map['nick_name'] = Variable<String>(nickName.value);
|
||||||
}
|
}
|
||||||
|
if (avatarSvg.present) {
|
||||||
|
map['avatar_svg'] = Variable<String>(avatarSvg.value);
|
||||||
|
}
|
||||||
|
if (myAvatarCounter.present) {
|
||||||
|
map['my_avatar_counter'] = Variable<int>(myAvatarCounter.value);
|
||||||
|
}
|
||||||
if (accepted.present) {
|
if (accepted.present) {
|
||||||
map['accepted'] = Variable<bool>(accepted.value);
|
map['accepted'] = Variable<bool>(accepted.value);
|
||||||
}
|
}
|
||||||
|
|
@ -737,6 +817,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
..write('username: $username, ')
|
..write('username: $username, ')
|
||||||
..write('displayName: $displayName, ')
|
..write('displayName: $displayName, ')
|
||||||
..write('nickName: $nickName, ')
|
..write('nickName: $nickName, ')
|
||||||
|
..write('avatarSvg: $avatarSvg, ')
|
||||||
|
..write('myAvatarCounter: $myAvatarCounter, ')
|
||||||
..write('accepted: $accepted, ')
|
..write('accepted: $accepted, ')
|
||||||
..write('requested: $requested, ')
|
..write('requested: $requested, ')
|
||||||
..write('blocked: $blocked, ')
|
..write('blocked: $blocked, ')
|
||||||
|
|
@ -805,8 +887,6 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
'CHECK ("acknowledge_by_user" IN (0, 1))'),
|
'CHECK ("acknowledge_by_user" IN (0, 1))'),
|
||||||
defaultValue: Constant(false));
|
defaultValue: Constant(false));
|
||||||
static const VerificationMeta _downloadStateMeta =
|
|
||||||
const VerificationMeta('downloadState');
|
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<DownloadState, int>
|
late final GeneratedColumnWithTypeConverter<DownloadState, int>
|
||||||
downloadState = GeneratedColumn<int>('download_state', aliasedName, false,
|
downloadState = GeneratedColumn<int>('download_state', aliasedName, false,
|
||||||
|
|
@ -824,7 +904,6 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
'CHECK ("acknowledge_by_server" IN (0, 1))'),
|
'CHECK ("acknowledge_by_server" IN (0, 1))'),
|
||||||
defaultValue: Constant(false));
|
defaultValue: Constant(false));
|
||||||
static const VerificationMeta _kindMeta = const VerificationMeta('kind');
|
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<MessageKind, String> kind =
|
late final GeneratedColumnWithTypeConverter<MessageKind, String> kind =
|
||||||
GeneratedColumn<String>('kind', aliasedName, false,
|
GeneratedColumn<String>('kind', aliasedName, false,
|
||||||
|
|
@ -918,14 +997,12 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
|
||||||
acknowledgeByUser.isAcceptableOrUnknown(
|
acknowledgeByUser.isAcceptableOrUnknown(
|
||||||
data['acknowledge_by_user']!, _acknowledgeByUserMeta));
|
data['acknowledge_by_user']!, _acknowledgeByUserMeta));
|
||||||
}
|
}
|
||||||
context.handle(_downloadStateMeta, const VerificationResult.success());
|
|
||||||
if (data.containsKey('acknowledge_by_server')) {
|
if (data.containsKey('acknowledge_by_server')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_acknowledgeByServerMeta,
|
_acknowledgeByServerMeta,
|
||||||
acknowledgeByServer.isAcceptableOrUnknown(
|
acknowledgeByServer.isAcceptableOrUnknown(
|
||||||
data['acknowledge_by_server']!, _acknowledgeByServerMeta));
|
data['acknowledge_by_server']!, _acknowledgeByServerMeta));
|
||||||
}
|
}
|
||||||
context.handle(_kindMeta, const VerificationResult.success());
|
|
||||||
if (data.containsKey('content_json')) {
|
if (data.containsKey('content_json')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_contentJsonMeta,
|
_contentJsonMeta,
|
||||||
|
|
@ -2448,6 +2525,8 @@ typedef $$ContactsTableCreateCompanionBuilder = ContactsCompanion Function({
|
||||||
required String username,
|
required String username,
|
||||||
Value<String?> displayName,
|
Value<String?> displayName,
|
||||||
Value<String?> nickName,
|
Value<String?> nickName,
|
||||||
|
Value<String?> avatarSvg,
|
||||||
|
Value<int> myAvatarCounter,
|
||||||
Value<bool> accepted,
|
Value<bool> accepted,
|
||||||
Value<bool> requested,
|
Value<bool> requested,
|
||||||
Value<bool> blocked,
|
Value<bool> blocked,
|
||||||
|
|
@ -2465,6 +2544,8 @@ typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({
|
||||||
Value<String> username,
|
Value<String> username,
|
||||||
Value<String?> displayName,
|
Value<String?> displayName,
|
||||||
Value<String?> nickName,
|
Value<String?> nickName,
|
||||||
|
Value<String?> avatarSvg,
|
||||||
|
Value<int> myAvatarCounter,
|
||||||
Value<bool> accepted,
|
Value<bool> accepted,
|
||||||
Value<bool> requested,
|
Value<bool> requested,
|
||||||
Value<bool> blocked,
|
Value<bool> blocked,
|
||||||
|
|
@ -2519,6 +2600,13 @@ class $$ContactsTableFilterComposer
|
||||||
ColumnFilters<String> get nickName => $composableBuilder(
|
ColumnFilters<String> get nickName => $composableBuilder(
|
||||||
column: $table.nickName, builder: (column) => ColumnFilters(column));
|
column: $table.nickName, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<String> get avatarSvg => $composableBuilder(
|
||||||
|
column: $table.avatarSvg, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<int> get myAvatarCounter => $composableBuilder(
|
||||||
|
column: $table.myAvatarCounter,
|
||||||
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<bool> get accepted => $composableBuilder(
|
ColumnFilters<bool> get accepted => $composableBuilder(
|
||||||
column: $table.accepted, builder: (column) => ColumnFilters(column));
|
column: $table.accepted, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
|
@ -2600,6 +2688,13 @@ class $$ContactsTableOrderingComposer
|
||||||
ColumnOrderings<String> get nickName => $composableBuilder(
|
ColumnOrderings<String> get nickName => $composableBuilder(
|
||||||
column: $table.nickName, builder: (column) => ColumnOrderings(column));
|
column: $table.nickName, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<String> get avatarSvg => $composableBuilder(
|
||||||
|
column: $table.avatarSvg, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<int> get myAvatarCounter => $composableBuilder(
|
||||||
|
column: $table.myAvatarCounter,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<bool> get accepted => $composableBuilder(
|
ColumnOrderings<bool> get accepted => $composableBuilder(
|
||||||
column: $table.accepted, builder: (column) => ColumnOrderings(column));
|
column: $table.accepted, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
|
@ -2661,6 +2756,12 @@ class $$ContactsTableAnnotationComposer
|
||||||
GeneratedColumn<String> get nickName =>
|
GeneratedColumn<String> get nickName =>
|
||||||
$composableBuilder(column: $table.nickName, builder: (column) => column);
|
$composableBuilder(column: $table.nickName, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get avatarSvg =>
|
||||||
|
$composableBuilder(column: $table.avatarSvg, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get myAvatarCounter => $composableBuilder(
|
||||||
|
column: $table.myAvatarCounter, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<bool> get accepted =>
|
GeneratedColumn<bool> get accepted =>
|
||||||
$composableBuilder(column: $table.accepted, builder: (column) => column);
|
$composableBuilder(column: $table.accepted, builder: (column) => column);
|
||||||
|
|
||||||
|
|
@ -2743,6 +2844,8 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
Value<String> username = const Value.absent(),
|
Value<String> username = const Value.absent(),
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
|
Value<String?> avatarSvg = const Value.absent(),
|
||||||
|
Value<int> myAvatarCounter = const Value.absent(),
|
||||||
Value<bool> accepted = const Value.absent(),
|
Value<bool> accepted = const Value.absent(),
|
||||||
Value<bool> requested = const Value.absent(),
|
Value<bool> requested = const Value.absent(),
|
||||||
Value<bool> blocked = const Value.absent(),
|
Value<bool> blocked = const Value.absent(),
|
||||||
|
|
@ -2760,6 +2863,8 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
username: username,
|
username: username,
|
||||||
displayName: displayName,
|
displayName: displayName,
|
||||||
nickName: nickName,
|
nickName: nickName,
|
||||||
|
avatarSvg: avatarSvg,
|
||||||
|
myAvatarCounter: myAvatarCounter,
|
||||||
accepted: accepted,
|
accepted: accepted,
|
||||||
requested: requested,
|
requested: requested,
|
||||||
blocked: blocked,
|
blocked: blocked,
|
||||||
|
|
@ -2777,6 +2882,8 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
required String username,
|
required String username,
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
|
Value<String?> avatarSvg = const Value.absent(),
|
||||||
|
Value<int> myAvatarCounter = const Value.absent(),
|
||||||
Value<bool> accepted = const Value.absent(),
|
Value<bool> accepted = const Value.absent(),
|
||||||
Value<bool> requested = const Value.absent(),
|
Value<bool> requested = const Value.absent(),
|
||||||
Value<bool> blocked = const Value.absent(),
|
Value<bool> blocked = const Value.absent(),
|
||||||
|
|
@ -2794,6 +2901,8 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
username: username,
|
username: username,
|
||||||
displayName: displayName,
|
displayName: displayName,
|
||||||
nickName: nickName,
|
nickName: nickName,
|
||||||
|
avatarSvg: avatarSvg,
|
||||||
|
myAvatarCounter: myAvatarCounter,
|
||||||
accepted: accepted,
|
accepted: accepted,
|
||||||
requested: requested,
|
requested: requested,
|
||||||
blocked: blocked,
|
blocked: blocked,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ enum MessageKind {
|
||||||
textMessage,
|
textMessage,
|
||||||
media,
|
media,
|
||||||
contactRequest,
|
contactRequest,
|
||||||
|
avatarChange,
|
||||||
rejectRequest,
|
rejectRequest,
|
||||||
acceptRequest,
|
acceptRequest,
|
||||||
opened,
|
opened,
|
||||||
|
|
@ -93,6 +94,8 @@ class MessageContent {
|
||||||
return MediaMessageContent.fromJson(json);
|
return MediaMessageContent.fromJson(json);
|
||||||
case MessageKind.textMessage:
|
case MessageKind.textMessage:
|
||||||
return TextMessageContent.fromJson(json);
|
return TextMessageContent.fromJson(json);
|
||||||
|
case MessageKind.avatarChange:
|
||||||
|
return AvatarContent.fromJson(json);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -160,15 +163,25 @@ class TextMessageContent extends MessageContent {
|
||||||
TextMessageContent({required this.text});
|
TextMessageContent({required this.text});
|
||||||
|
|
||||||
static TextMessageContent fromJson(Map json) {
|
static TextMessageContent fromJson(Map json) {
|
||||||
return TextMessageContent(
|
return TextMessageContent(text: json['text']);
|
||||||
text: json['text'],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map toJson() {
|
Map toJson() {
|
||||||
return {
|
return {'text': text};
|
||||||
'text': text,
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
class AvatarContent extends MessageContent {
|
||||||
|
String svg;
|
||||||
|
AvatarContent({required this.svg});
|
||||||
|
|
||||||
|
static AvatarContent fromJson(Map json) {
|
||||||
|
return AvatarContent(svg: json['svg']);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map toJson() {
|
||||||
|
return {'svg': svg};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
part 'user_data.g.dart';
|
part 'userdata.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class UserData {
|
class UserData {
|
||||||
const UserData(
|
UserData({
|
||||||
{required this.userId,
|
required this.userId,
|
||||||
required this.username,
|
required this.username,
|
||||||
required this.displayName});
|
required this.displayName,
|
||||||
final String username;
|
});
|
||||||
final String displayName;
|
|
||||||
|
String username;
|
||||||
|
String displayName;
|
||||||
|
|
||||||
|
String? avatarSvg;
|
||||||
|
String? avatarJson;
|
||||||
|
int? avatarCounter;
|
||||||
|
|
||||||
final int userId;
|
final int userId;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,16 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
|
||||||
userId: (json['userId'] as num).toInt(),
|
userId: (json['userId'] as num).toInt(),
|
||||||
username: json['username'] as String,
|
username: json['username'] as String,
|
||||||
displayName: json['displayName'] as String,
|
displayName: json['displayName'] as String,
|
||||||
);
|
)
|
||||||
|
..avatarSvg = json['avatarSvg'] as String?
|
||||||
|
..avatarJson = json['avatarJson'] as String?
|
||||||
|
..avatarCounter = (json['avatarCounter'] as num?)?.toInt();
|
||||||
|
|
||||||
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
||||||
'username': instance.username,
|
'username': instance.username,
|
||||||
'displayName': instance.displayName,
|
'displayName': instance.displayName,
|
||||||
|
'avatarSvg': instance.avatarSvg,
|
||||||
|
'avatarJson': instance.avatarJson,
|
||||||
|
'avatarCounter': instance.avatarCounter,
|
||||||
'userId': instance.userId,
|
'userId': instance.userId,
|
||||||
};
|
};
|
||||||
|
|
@ -6,11 +6,13 @@ import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/database/twonly_database.dart';
|
import 'package:twonly/src/database/twonly_database.dart';
|
||||||
import 'package:twonly/src/database/tables/messages_table.dart';
|
import 'package:twonly/src/database/tables/messages_table.dart';
|
||||||
import 'package:twonly/src/json_models/message.dart';
|
import 'package:twonly/src/json_models/message.dart';
|
||||||
|
import 'package:twonly/src/json_models/userdata.dart';
|
||||||
import 'package:twonly/src/proto/api/error.pb.dart';
|
import 'package:twonly/src/proto/api/error.pb.dart';
|
||||||
import 'package:twonly/src/providers/api/api_utils.dart';
|
import 'package:twonly/src/providers/api/api_utils.dart';
|
||||||
import 'package:twonly/src/providers/hive.dart';
|
import 'package:twonly/src/providers/hive.dart';
|
||||||
// ignore: library_prefixes
|
// ignore: library_prefixes
|
||||||
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
|
||||||
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
|
||||||
Future tryTransmitMessages() async {
|
Future tryTransmitMessages() async {
|
||||||
// List<Message> retransmit =
|
// List<Message> retransmit =
|
||||||
|
|
@ -122,3 +124,27 @@ Future notifyContactAboutOpeningMessage(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future notifyContactsAboutAvatarChange() async {
|
||||||
|
List<Contact> contacts =
|
||||||
|
await twonlyDatabase.contactsDao.getAllNotBlockedContacts();
|
||||||
|
|
||||||
|
UserData? user = await getUser();
|
||||||
|
if (user == null) return;
|
||||||
|
if (user.avatarCounter == null) return;
|
||||||
|
if (user.avatarSvg == null) return;
|
||||||
|
|
||||||
|
for (Contact contact in contacts) {
|
||||||
|
if (contact.myAvatarCounter < user.avatarCounter!) {
|
||||||
|
encryptAndSendMessage(
|
||||||
|
null,
|
||||||
|
contact.userId,
|
||||||
|
MessageJson(
|
||||||
|
kind: MessageKind.avatarChange,
|
||||||
|
content: AvatarContent(svg: user.avatarSvg!),
|
||||||
|
timestamp: DateTime.now(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,14 @@ Future<client.Response> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
final update = ContactsCompanion(accepted: Value(true));
|
final update = ContactsCompanion(accepted: Value(true));
|
||||||
twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
||||||
localPushNotificationNewMessage(fromUserId.toInt(), message, 8888888);
|
localPushNotificationNewMessage(fromUserId.toInt(), message, 8888888);
|
||||||
|
notifyContactsAboutAvatarChange();
|
||||||
|
break;
|
||||||
|
case MessageKind.avatarChange:
|
||||||
|
var content = message.content;
|
||||||
|
if (content is AvatarContent) {
|
||||||
|
final update = ContactsCompanion(avatarSvg: Value(content.svg));
|
||||||
|
twonlyDatabase.contactsDao.updateContact(fromUserId, update);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MessageKind.ack:
|
case MessageKind.ack:
|
||||||
final update = MessagesCompanion(acknowledgeByUser: Value(true));
|
final update = MessagesCompanion(acknowledgeByUser: Value(true));
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ class ApiProvider {
|
||||||
if (!globalIsAppInBackground) {
|
if (!globalIsAppInBackground) {
|
||||||
tryTransmitMessages();
|
tryTransmitMessages();
|
||||||
tryDownloadAllMediaFiles();
|
tryDownloadAllMediaFiles();
|
||||||
|
notifyContactsAboutAvatarChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ Future<UserData?> getUser() async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future updateUser(UserData userData) async {
|
||||||
|
final storage = getSecureStorage();
|
||||||
|
storage.write(key: "userData", value: jsonEncode(userData));
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> deleteLocalUserData() async {
|
Future<bool> deleteLocalUserData() async {
|
||||||
final appDir = await getApplicationSupportDirectory();
|
final appDir = await getApplicationSupportDirectory();
|
||||||
if (appDir.existsSync()) {
|
if (appDir.existsSync()) {
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,14 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectCamera(int sCameraId, {bool init = false}) {
|
void selectCamera(int sCameraId, {bool init = false}) {
|
||||||
if (sCameraId > gCameras.length) return;
|
if (sCameraId >= gCameras.length) return;
|
||||||
|
if (init) {
|
||||||
|
for (; sCameraId < gCameras.length; sCameraId++) {
|
||||||
|
if (gCameras[sCameraId].lensDirection == CameraLensDirection.back) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
isZoomAble = false;
|
isZoomAble = false;
|
||||||
});
|
});
|
||||||
|
|
@ -115,12 +122,19 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
if (cameraId < gCameras.length) {
|
||||||
controller.dispose();
|
controller.dispose();
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (cameraId >= gCameras.length) {
|
||||||
|
return Center(
|
||||||
|
child: Text("No camera found."),
|
||||||
|
);
|
||||||
|
}
|
||||||
return MediaViewSizing(
|
return MediaViewSizing(
|
||||||
Stack(
|
Stack(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -303,8 +303,8 @@ class UserList extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
leading: InitialsAvatar(
|
leading: ContactAvatar(
|
||||||
getContactDisplayName(user),
|
contact: user,
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
),
|
),
|
||||||
trailing: Checkbox(
|
trailing: Checkbox(
|
||||||
|
|
|
||||||
|
|
@ -214,8 +214,8 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
? Container()
|
? Container()
|
||||||
: Row(
|
: Row(
|
||||||
children: [
|
children: [
|
||||||
InitialsAvatar(
|
ContactAvatar(
|
||||||
getContactDisplayName(user!),
|
contact: user!,
|
||||||
fontSize: 19,
|
fontSize: 19,
|
||||||
),
|
),
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ class _UserListItem extends State<UserListItem> {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
leading: InitialsAvatar(getContactDisplayName(widget.user)),
|
leading: ContactAvatar(contact: widget.user),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (currentMessage == null) {
|
if (currentMessage == null) {
|
||||||
context
|
context
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ class _ContactsListViewState extends State<ContactsListView> {
|
||||||
final displayName = getContactDisplayName(contact);
|
final displayName = getContactDisplayName(contact);
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(displayName),
|
title: Text(displayName),
|
||||||
leading: InitialsAvatar(displayName),
|
leading: ContactAvatar(contact: contact),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,7 @@ class _ContactViewState extends State<ContactView> {
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: const EdgeInsets.all(10),
|
||||||
child: InitialsAvatar(
|
child: ContactAvatar(contact: contact, fontSize: 30),
|
||||||
getContactDisplayName(contact),
|
|
||||||
fontSize: 30,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ import 'dart:math';
|
||||||
|
|
||||||
import 'package:avatar_maker/avatar_maker.dart';
|
import 'package:avatar_maker/avatar_maker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:twonly/src/json_models/userdata.dart';
|
||||||
|
import 'package:twonly/src/providers/api/api.dart';
|
||||||
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
|
|
||||||
class AvatarCreator extends StatefulWidget {
|
class AvatarCreator extends StatefulWidget {
|
||||||
const AvatarCreator({super.key});
|
const AvatarCreator({super.key});
|
||||||
|
|
@ -28,7 +31,7 @@ class _AvatarCreatorState extends State<AvatarCreator> {
|
||||||
height: 25,
|
height: 25,
|
||||||
),
|
),
|
||||||
AvatarMakerAvatar(
|
AvatarMakerAvatar(
|
||||||
backgroundColor: Colors.grey[200],
|
backgroundColor: Colors.transparent,
|
||||||
radius: 100,
|
radius: 100,
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
|
|
@ -39,13 +42,17 @@ class _AvatarCreatorState extends State<AvatarCreator> {
|
||||||
Spacer(flex: 2),
|
Spacer(flex: 2),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
icon: Icon(Icons.edit),
|
icon: Icon(Icons.edit),
|
||||||
label: Text("Customize"),
|
label: Text("Customize"),
|
||||||
onPressed: () => Navigator.push(context,
|
onPressed: () => Navigator.push(
|
||||||
new MaterialPageRoute(builder: (context) => NewPage())),
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => NewPage(),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -64,6 +71,21 @@ class _AvatarCreatorState extends State<AvatarCreator> {
|
||||||
class NewPage extends StatelessWidget {
|
class NewPage extends StatelessWidget {
|
||||||
const NewPage({super.key});
|
const NewPage({super.key});
|
||||||
|
|
||||||
|
Future updateUserAvatar(String json, String svg) async {
|
||||||
|
UserData? user = await getUser();
|
||||||
|
if (user == null) return null;
|
||||||
|
|
||||||
|
user.avatarJson = json;
|
||||||
|
user.avatarSvg = svg;
|
||||||
|
if (user.avatarCounter == null) {
|
||||||
|
user.avatarCounter = 1;
|
||||||
|
} else {
|
||||||
|
user.avatarCounter = user.avatarCounter! + 1;
|
||||||
|
}
|
||||||
|
await updateUser(user);
|
||||||
|
await notifyContactsAboutAvatarChange();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var _width = MediaQuery.of(context).size.width;
|
var _width = MediaQuery.of(context).size.width;
|
||||||
|
|
@ -75,9 +97,9 @@ class NewPage extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 30),
|
padding: const EdgeInsets.symmetric(vertical: 00),
|
||||||
child: AvatarMakerAvatar(
|
child: AvatarMakerAvatar(
|
||||||
radius: 100,
|
radius: 130,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -85,12 +107,18 @@ class NewPage extends StatelessWidget {
|
||||||
width: min(600, _width * 0.85),
|
width: min(600, _width * 0.85),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
|
||||||
"Customize:",
|
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
|
||||||
),
|
|
||||||
Spacer(),
|
Spacer(),
|
||||||
AvatarMakerSaveWidget(),
|
AvatarMakerSaveWidget(
|
||||||
|
onTap: () async {
|
||||||
|
final json =
|
||||||
|
await AvatarMakerController.getJsonOptions();
|
||||||
|
final svg = await AvatarMakerController.getAvatarSVG();
|
||||||
|
await updateUserAvatar(json, svg);
|
||||||
|
if (context.mounted) {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
AvatarMakerRandomWidget(),
|
AvatarMakerRandomWidget(),
|
||||||
AvatarMakerResetWidget(),
|
AvatarMakerResetWidget(),
|
||||||
],
|
],
|
||||||
|
|
@ -106,12 +134,20 @@ class NewPage extends StatelessWidget {
|
||||||
boxDecoration: BoxDecoration(
|
boxDecoration: BoxDecoration(
|
||||||
boxShadow: [BoxShadow()],
|
boxShadow: [BoxShadow()],
|
||||||
),
|
),
|
||||||
// primaryBgColor:
|
unselectedTileDecoration: BoxDecoration(
|
||||||
// Theme.of(context).colorScheme.surfaceContainerLowest,
|
color: const Color.fromARGB(255, 83, 83, 83),
|
||||||
// secondaryBgColor:
|
borderRadius: BorderRadius.circular(10),
|
||||||
// const Color.fromARGB(255, 203, 203, 203),
|
),
|
||||||
// labelTextStyle: TextStyle(
|
selectedTileDecoration: BoxDecoration(
|
||||||
// color: Theme.of(context).colorScheme.tertiary),
|
color: const Color.fromARGB(255, 117, 117, 117),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
selectedIconColor: Colors.white,
|
||||||
|
unselectedIconColor: Colors.grey,
|
||||||
|
primaryBgColor: Colors.transparent,
|
||||||
|
secondaryBgColor: Colors.transparent,
|
||||||
|
labelTextStyle: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.tertiary),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,7 @@ class UserList extends StatelessWidget {
|
||||||
title: Row(children: [
|
title: Row(children: [
|
||||||
Text(getContactDisplayName(user)),
|
Text(getContactDisplayName(user)),
|
||||||
]),
|
]),
|
||||||
leading: InitialsAvatar(
|
leading: ContactAvatar(contact: user, fontSize: 15),
|
||||||
getContactDisplayName(user),
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
trailing: Checkbox(
|
trailing: Checkbox(
|
||||||
value: user.blocked,
|
value: user.blocked,
|
||||||
onChanged: (bool? value) {
|
onChanged: (bool? value) {
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,15 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
Navigator.push(context,
|
await Navigator.push(context,
|
||||||
MaterialPageRoute(builder: (context) {
|
MaterialPageRoute(builder: (context) {
|
||||||
return AvatarCreator();
|
return AvatarCreator();
|
||||||
}));
|
}));
|
||||||
|
initAsync();
|
||||||
},
|
},
|
||||||
child: InitialsAvatar(
|
child: ContactAvatar(
|
||||||
userData!.username,
|
userData: userData!,
|
||||||
fontSize: 30,
|
fontSize: 30,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -636,7 +636,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_svg
|
name: flutter_svg
|
||||||
sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b
|
sha256: c200fd79c918a40c5cd50ea0877fa13f81bdaf6f0a5d3dbcc2a13e3285d6aa1b
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ dependencies:
|
||||||
web_socket_channel: ^3.0.1
|
web_socket_channel: ^3.0.1
|
||||||
camera: ^0.11.1
|
camera: ^0.11.1
|
||||||
avatar_maker: ^0.2.0
|
avatar_maker: ^0.2.0
|
||||||
|
flutter_svg: ^2.0.17
|
||||||
# avatar_maker
|
# avatar_maker
|
||||||
# avatar_maker:
|
# avatar_maker:
|
||||||
# path: ./dependencies/avatar_maker/
|
# path: ./dependencies/avatar_maker/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue