change user id to i64

This commit is contained in:
otsmr 2025-01-24 12:38:12 +01:00
parent b694b9d7fc
commit a499f5c635
18 changed files with 232 additions and 154 deletions

View file

@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
class InitialsAvatar extends StatelessWidget {
final String displayName;
final double? fontSize;
const InitialsAvatar({super.key, required this.displayName});
const InitialsAvatar(
{super.key, required this.displayName, this.fontSize = 20});
@override
Widget build(BuildContext context) {
@ -25,12 +27,13 @@ class InitialsAvatar extends StatelessWidget {
return CircleAvatar(
backgroundColor: avatarColor,
radius: fontSize,
child: Text(
initials,
style: TextStyle(
color: _getTextColor(avatarColor),
fontWeight: FontWeight.normal,
fontSize: 20,
fontSize: fontSize,
),
),
);

View file

@ -8,6 +8,7 @@
"registerSubmitButton": "Register now!",
"newMessageTitle": "New message",
"chatsTitle": "Chats",
"shareImageTitle": "Share image",
"shareImagedEditorSendImage": "Send",
"shareImagedEditorSaveImage": "Save",
"shareImagedEditorSavedImage": "Saved",

View file

@ -1,11 +1,10 @@
import 'dart:typed_data';
import 'package:cv/cv.dart';
import 'package:fixnum/fixnum.dart';
import 'package:twonly/main.dart';
class Contact {
Contact({required this.userId, required this.displayName});
final Uint8List userId;
final Int64 userId;
final String displayName;
}
@ -13,7 +12,7 @@ class DbContacts extends CvModelBase {
static const tableName = "contacts";
static const columnUserId = "contact_user_id";
final userId = CvField<Uint8List>(columnUserId);
final userId = CvField<int>(columnUserId);
static const columnDisplayName = "display_name";
final displayName = CvField<String>(columnDisplayName);
@ -24,7 +23,7 @@ class DbContacts extends CvModelBase {
static String getCreateTableString() {
return """
CREATE TABLE $tableName (
$columnUserId BINARY(16) NOT NULL PRIMARY KEY,
$columnUserId INTEGER NOT NULL PRIMARY KEY,
$columnDisplayName TEXT,
$columnCreatedAt DATETIME DEFAULT CURRENT_TIMESTAMP
)
@ -39,7 +38,7 @@ class DbContacts extends CvModelBase {
List<Contact> parsedUsers = [];
for (int i = 0; i < users.length; i++) {
parsedUsers.add(Contact(
userId: users.cast()[i][columnUserId],
userId: Int64(users.cast()[i][columnUserId]),
displayName: users.cast()[i][columnDisplayName]));
}
return parsedUsers;

View file

@ -1,6 +1,8 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:fixnum/fixnum.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:twonly/src/model/user_data_json.dart';
part 'signal_identity_json.g.dart';
class Uint8ListConverter implements JsonConverter<Uint8List, String> {
@ -20,7 +22,10 @@ class Uint8ListConverter implements JsonConverter<Uint8List, String> {
class SignalIdentity {
const SignalIdentity(
{required this.identityKeyPairU8List, required this.registrationId});
final int registrationId;
@Int64Converter()
final Int64 registrationId;
@Uint8ListConverter()
final Uint8List identityKeyPairU8List;
factory SignalIdentity.fromJson(Map<String, dynamic> json) =>

View file

@ -10,12 +10,13 @@ SignalIdentity _$SignalIdentityFromJson(Map<String, dynamic> json) =>
SignalIdentity(
identityKeyPairU8List: const Uint8ListConverter()
.fromJson(json['identityKeyPairU8List'] as String),
registrationId: (json['registrationId'] as num).toInt(),
registrationId:
const Int64Converter().fromJson(json['registrationId'] as String),
);
Map<String, dynamic> _$SignalIdentityToJson(SignalIdentity instance) =>
<String, dynamic>{
'registrationId': instance.registrationId,
'registrationId': const Int64Converter().toJson(instance.registrationId),
'identityKeyPairU8List':
const Uint8ListConverter().toJson(instance.identityKeyPairU8List),
};

View file

@ -1,8 +1,21 @@
import 'dart:typed_data';
import 'package:json_annotation/json_annotation.dart';
import 'package:twonly/src/model/signal_identity_json.dart';
import 'package:fixnum/fixnum.dart';
part 'user_data_json.g.dart';
class Int64Converter implements JsonConverter<Int64, String> {
const Int64Converter();
@override
Int64 fromJson(String json) {
return Int64.parseInt(json);
}
@override
String toJson(Int64 object) {
return object.toString();
}
}
@JsonSerializable()
class UserData {
const UserData(
@ -12,8 +25,9 @@ class UserData {
final String username;
final String displayName;
@Uint8ListConverter()
final Uint8List userId;
@Int64Converter()
final Int64 userId;
factory UserData.fromJson(Map<String, dynamic> json) =>
_$UserDataFromJson(json);
Map<String, dynamic> toJson() => _$UserDataToJson(this);

View file

@ -7,7 +7,7 @@ part of 'user_data_json.dart';
// **************************************************************************
UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
userId: const Uint8ListConverter().fromJson(json['userId'] as String),
userId: const Int64Converter().fromJson(json['userId'] as String),
username: json['username'] as String,
displayName: json['displayName'] as String,
);
@ -15,5 +15,5 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'username': instance.username,
'displayName': instance.displayName,
'userId': const Uint8ListConverter().toJson(instance.userId),
'userId': const Int64Converter().toJson(instance.userId),
};

View file

@ -364,7 +364,7 @@ class Handshake_GetChallenge extends $pb.GeneratedMessage {
class Handshake_OpenSession extends $pb.GeneratedMessage {
factory Handshake_OpenSession({
$core.List<$core.int>? userId,
$fixnum.Int64? userId,
$core.List<$core.int>? response,
}) {
final $result = create();
@ -381,7 +381,7 @@ class Handshake_OpenSession extends $pb.GeneratedMessage {
factory Handshake_OpenSession.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake.OpenSession', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'userId', $pb.PbFieldType.OY)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'response', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@ -408,9 +408,9 @@ class Handshake_OpenSession extends $pb.GeneratedMessage {
static Handshake_OpenSession? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get userId => $_getN(0);
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($core.List<$core.int> v) { $_setBytes(0, v); }
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
@ -529,7 +529,7 @@ class Handshake extends $pb.GeneratedMessage {
class ApplicationData_TextMessage extends $pb.GeneratedMessage {
factory ApplicationData_TextMessage({
$core.List<$core.int>? userId,
$fixnum.Int64? userId,
$core.List<$core.int>? body,
}) {
final $result = create();
@ -546,7 +546,7 @@ class ApplicationData_TextMessage extends $pb.GeneratedMessage {
factory ApplicationData_TextMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.TextMessage', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'userId', $pb.PbFieldType.OY)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'body', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@ -573,9 +573,9 @@ class ApplicationData_TextMessage extends $pb.GeneratedMessage {
static ApplicationData_TextMessage? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get userId => $_getN(0);
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($core.List<$core.int> v) { $_setBytes(0, v); }
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
@ -643,7 +643,7 @@ class ApplicationData_GetUserByUsername extends $pb.GeneratedMessage {
class ApplicationData_GetPrekeysByUserId extends $pb.GeneratedMessage {
factory ApplicationData_GetPrekeysByUserId({
$core.List<$core.int>? userId,
$fixnum.Int64? userId,
}) {
final $result = create();
if (userId != null) {
@ -656,7 +656,7 @@ class ApplicationData_GetPrekeysByUserId extends $pb.GeneratedMessage {
factory ApplicationData_GetPrekeysByUserId.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.GetPrekeysByUserId', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'userId', $pb.PbFieldType.OY)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..hasRequiredFields = false
;
@ -682,9 +682,9 @@ class ApplicationData_GetPrekeysByUserId extends $pb.GeneratedMessage {
static ApplicationData_GetPrekeysByUserId? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get userId => $_getN(0);
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($core.List<$core.int> v) { $_setBytes(0, v); }
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)

View file

@ -91,7 +91,7 @@ const Handshake_GetChallenge$json = {
const Handshake_OpenSession$json = {
'1': 'OpenSession',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 12, '10': 'userId'},
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
{'1': 'response', '3': 2, '4': 1, '5': 12, '10': 'response'},
],
};
@ -108,7 +108,7 @@ final $typed_data.Uint8List handshakeDescriptor = $convert.base64Decode(
'NpZ25lZFByZWtleRI2ChdzaWduZWRfcHJla2V5X3NpZ25hdHVyZRgFIAEoDFIVc2lnbmVkUHJl'
'a2V5U2lnbmF0dXJlEigKEHNpZ25lZF9wcmVrZXlfaWQYBiABKANSDnNpZ25lZFByZWtleUlkEi'
'cKD3JlZ2lzdHJhdGlvbl9pZBgHIAEoA1IOcmVnaXN0cmF0aW9uSWRCDgoMX2ludml0ZV9jb2Rl'
'Gg4KDEdldENoYWxsZW5nZRpCCgtPcGVuU2Vzc2lvbhIXCgd1c2VyX2lkGAEgASgMUgZ1c2VySW'
'Gg4KDEdldENoYWxsZW5nZRpCCgtPcGVuU2Vzc2lvbhIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySW'
'QSGgoIcmVzcG9uc2UYAiABKAxSCHJlc3BvbnNlQgsKCUhhbmRzaGFrZQ==');
@$core.Deprecated('Use applicationDataDescriptor instead')
@ -131,7 +131,7 @@ const ApplicationData$json = {
const ApplicationData_TextMessage$json = {
'1': 'TextMessage',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 12, '10': 'userId'},
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
{'1': 'body', '3': 3, '4': 1, '5': 12, '10': 'body'},
],
};
@ -148,7 +148,7 @@ const ApplicationData_GetUserByUsername$json = {
const ApplicationData_GetPrekeysByUserId$json = {
'1': 'GetPrekeysByUserId',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 12, '10': 'userId'},
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
],
};
@ -181,9 +181,9 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
'bGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5HZXRVcGxvYWRUb2tlbkgAUg5nZXR1cG'
'xvYWR0b2tlbhJOCgp1cGxvYWRkYXRhGAUgASgLMiwuY2xpZW50X3RvX3NlcnZlci5BcHBsaWNh'
'dGlvbkRhdGEuVXBsb2FkRGF0YUgAUgp1cGxvYWRkYXRhGjoKC1RleHRNZXNzYWdlEhcKB3VzZX'
'JfaWQYASABKAxSBnVzZXJJZBISCgRib2R5GAMgASgMUgRib2R5Gi8KEUdldFVzZXJCeVVzZXJu'
'JfaWQYASABKANSBnVzZXJJZBISCgRib2R5GAMgASgMUgRib2R5Gi8KEUdldFVzZXJCeVVzZXJu'
'YW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2VybmFtZRotChJHZXRQcmVrZXlzQnlVc2VySWQSFw'
'oHdXNlcl9pZBgBIAEoDFIGdXNlcklkGiIKDkdldFVwbG9hZFRva2VuEhAKA2xlbhgBIAEoDVID'
'oHdXNlcl9pZBgBIAEoA1IGdXNlcklkGiIKDkdldFVwbG9hZFRva2VuEhAKA2xlbhgBIAEoDVID'
'bGVuGlsKClVwbG9hZERhdGESIQoMdXBsb2FkX3Rva2VuGAEgASgMUgt1cGxvYWRUb2tlbhIWCg'
'ZvZmZzZXQYAiABKA1SBm9mZnNldBISCgRkYXRhGAMgASgMUgRkYXRhQhEKD0FwcGxpY2F0aW9u'
'RGF0YQ==');

View file

@ -310,13 +310,12 @@ class Response_PreKey extends $pb.GeneratedMessage {
class Response_UserData extends $pb.GeneratedMessage {
factory Response_UserData({
$core.List<$core.int>? userId,
$fixnum.Int64? userId,
$core.Iterable<Response_PreKey>? prekeys,
$core.List<$core.int>? publicIdentityKey,
$core.List<$core.int>? signedPrekey,
$core.List<$core.int>? signedPrekeySignature,
$fixnum.Int64? signedPrekeyId,
$fixnum.Int64? registrationId,
}) {
final $result = create();
if (userId != null) {
@ -337,9 +336,6 @@ class Response_UserData extends $pb.GeneratedMessage {
if (signedPrekeyId != null) {
$result.signedPrekeyId = signedPrekeyId;
}
if (registrationId != null) {
$result.registrationId = registrationId;
}
return $result;
}
Response_UserData._() : super();
@ -347,13 +343,12 @@ class Response_UserData extends $pb.GeneratedMessage {
factory Response_UserData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.UserData', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'userId', $pb.PbFieldType.OY)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..pc<Response_PreKey>(2, _omitFieldNames ? '' : 'prekeys', $pb.PbFieldType.PM, subBuilder: Response_PreKey.create)
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'publicIdentityKey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(4, _omitFieldNames ? '' : 'signedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(5, _omitFieldNames ? '' : 'signedPrekeySignature', $pb.PbFieldType.OY)
..aInt64(6, _omitFieldNames ? '' : 'signedPrekeyId')
..aInt64(7, _omitFieldNames ? '' : 'registrationId')
..hasRequiredFields = false
;
@ -379,9 +374,9 @@ class Response_UserData extends $pb.GeneratedMessage {
static Response_UserData? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get userId => $_getN(0);
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($core.List<$core.int> v) { $_setBytes(0, v); }
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
@ -425,15 +420,6 @@ class Response_UserData extends $pb.GeneratedMessage {
$core.bool hasSignedPrekeyId() => $_has(5);
@$pb.TagNumber(6)
void clearSignedPrekeyId() => clearField(6);
@$pb.TagNumber(7)
$fixnum.Int64 get registrationId => $_getI64(6);
@$pb.TagNumber(7)
set registrationId($fixnum.Int64 v) { $_setInt64(6, v); }
@$pb.TagNumber(7)
$core.bool hasRegistrationId() => $_has(6);
@$pb.TagNumber(7)
void clearRegistrationId() => clearField(7);
}
enum Response_Ok_Ok {
@ -448,7 +434,7 @@ enum Response_Ok_Ok {
class Response_Ok extends $pb.GeneratedMessage {
factory Response_Ok({
$core.bool? none,
$core.List<$core.int>? userid,
$fixnum.Int64? userid,
$core.List<$core.int>? challenge,
$core.List<$core.int>? uploadtoken,
Response_UserData? userdata,
@ -486,7 +472,7 @@ class Response_Ok extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.Ok', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..oo(0, [1, 2, 3, 4, 5])
..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'userid', $pb.PbFieldType.OY)
..aInt64(2, _omitFieldNames ? '' : 'userid')
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'challenge', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(4, _omitFieldNames ? '' : 'uploadtoken', $pb.PbFieldType.OY)
..aOM<Response_UserData>(5, _omitFieldNames ? '' : 'userdata', subBuilder: Response_UserData.create)
@ -527,9 +513,9 @@ class Response_Ok extends $pb.GeneratedMessage {
void clearNone() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get userid => $_getN(1);
$fixnum.Int64 get userid => $_getI64(1);
@$pb.TagNumber(2)
set userid($core.List<$core.int> v) { $_setBytes(1, v); }
set userid($fixnum.Int64 v) { $_setInt64(1, v); }
@$pb.TagNumber(2)
$core.bool hasUserid() => $_has(1);
@$pb.TagNumber(2)

View file

@ -88,19 +88,17 @@ const Response_PreKey$json = {
const Response_UserData$json = {
'1': 'UserData',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 12, '10': 'userId'},
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
{'1': 'prekeys', '3': 2, '4': 3, '5': 11, '6': '.server_to_client.Response.PreKey', '10': 'prekeys'},
{'1': 'public_identity_key', '3': 3, '4': 1, '5': 12, '9': 0, '10': 'publicIdentityKey', '17': true},
{'1': 'signed_prekey', '3': 4, '4': 1, '5': 12, '9': 1, '10': 'signedPrekey', '17': true},
{'1': 'signed_prekey_signature', '3': 5, '4': 1, '5': 12, '9': 2, '10': 'signedPrekeySignature', '17': true},
{'1': 'registration_id', '3': 7, '4': 1, '5': 3, '9': 3, '10': 'registrationId', '17': true},
{'1': 'signed_prekey_id', '3': 6, '4': 1, '5': 3, '9': 4, '10': 'signedPrekeyId', '17': true},
{'1': 'signed_prekey_id', '3': 6, '4': 1, '5': 3, '9': 3, '10': 'signedPrekeyId', '17': true},
],
'8': [
{'1': '_public_identity_key'},
{'1': '_signed_prekey'},
{'1': '_signed_prekey_signature'},
{'1': '_registration_id'},
{'1': '_signed_prekey_id'},
],
};
@ -110,7 +108,7 @@ const Response_Ok$json = {
'1': 'Ok',
'2': [
{'1': 'None', '3': 1, '4': 1, '5': 8, '9': 0, '10': 'None'},
{'1': 'userid', '3': 2, '4': 1, '5': 12, '9': 0, '10': 'userid'},
{'1': 'userid', '3': 2, '4': 1, '5': 3, '9': 0, '10': 'userid'},
{'1': 'challenge', '3': 3, '4': 1, '5': 12, '9': 0, '10': 'challenge'},
{'1': 'uploadtoken', '3': 4, '4': 1, '5': 12, '9': 0, '10': 'uploadtoken'},
{'1': 'userdata', '3': 5, '4': 1, '5': 11, '6': '.server_to_client.Response.UserData', '9': 0, '10': 'userdata'},
@ -124,17 +122,16 @@ const Response_Ok$json = {
final $typed_data.Uint8List responseDescriptor = $convert.base64Decode(
'CghSZXNwb25zZRIvCgJvaxgBIAEoCzIdLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuT2tIAF'
'ICb2sSKAoFZXJyb3IYAiABKA4yEC5lcnJvci5FcnJvckNvZGVIAFIFZXJyb3IaMAoGUHJlS2V5'
'Eg4KAmlkGAEgASgDUgJpZBIWCgZwcmVrZXkYAiABKAxSBnByZWtleRrIAwoIVXNlckRhdGESFw'
'oHdXNlcl9pZBgBIAEoDFIGdXNlcklkEjsKB3ByZWtleXMYAiADKAsyIS5zZXJ2ZXJfdG9fY2xp'
'Eg4KAmlkGAEgASgDUgJpZBIWCgZwcmVrZXkYAiABKAxSBnByZWtleRqGAwoIVXNlckRhdGESFw'
'oHdXNlcl9pZBgBIAEoA1IGdXNlcklkEjsKB3ByZWtleXMYAiADKAsyIS5zZXJ2ZXJfdG9fY2xp'
'ZW50LlJlc3BvbnNlLlByZUtleVIHcHJla2V5cxIzChNwdWJsaWNfaWRlbnRpdHlfa2V5GAMgAS'
'gMSABSEXB1YmxpY0lkZW50aXR5S2V5iAEBEigKDXNpZ25lZF9wcmVrZXkYBCABKAxIAVIMc2ln'
'bmVkUHJla2V5iAEBEjsKF3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAUgASgMSAJSFXNpZ25lZF'
'ByZWtleVNpZ25hdHVyZYgBARIsCg9yZWdpc3RyYXRpb25faWQYByABKANIA1IOcmVnaXN0cmF0'
'aW9uSWSIAQESLQoQc2lnbmVkX3ByZWtleV9pZBgGIAEoA0gEUg5zaWduZWRQcmVrZXlJZIgBAU'
'IWChRfcHVibGljX2lkZW50aXR5X2tleUIQCg5fc2lnbmVkX3ByZWtleUIaChhfc2lnbmVkX3By'
'ZWtleV9zaWduYXR1cmVCEgoQX3JlZ2lzdHJhdGlvbl9pZEITChFfc2lnbmVkX3ByZWtleV9pZB'
'rBAQoCT2sSFAoETm9uZRgBIAEoCEgAUgROb25lEhgKBnVzZXJpZBgCIAEoDEgAUgZ1c2VyaWQS'
'HgoJY2hhbGxlbmdlGAMgASgMSABSCWNoYWxsZW5nZRIiCgt1cGxvYWR0b2tlbhgEIAEoDEgAUg'
't1cGxvYWR0b2tlbhJBCgh1c2VyZGF0YRgFIAEoCzIjLnNlcnZlcl90b19jbGllbnQuUmVzcG9u'
'c2UuVXNlckRhdGFIAFIIdXNlcmRhdGFCBAoCT2tCCgoIUmVzcG9uc2U=');
'ByZWtleVNpZ25hdHVyZYgBARItChBzaWduZWRfcHJla2V5X2lkGAYgASgDSANSDnNpZ25lZFBy'
'ZWtleUlkiAEBQhYKFF9wdWJsaWNfaWRlbnRpdHlfa2V5QhAKDl9zaWduZWRfcHJla2V5QhoKGF'
'9zaWduZWRfcHJla2V5X3NpZ25hdHVyZUITChFfc2lnbmVkX3ByZWtleV9pZBrBAQoCT2sSFAoE'
'Tm9uZRgBIAEoCEgAUgROb25lEhgKBnVzZXJpZBgCIAEoA0gAUgZ1c2VyaWQSHgoJY2hhbGxlbm'
'dlGAMgASgMSABSCWNoYWxsZW5nZRIiCgt1cGxvYWR0b2tlbhgEIAEoDEgAUgt1cGxvYWR0b2tl'
'bhJBCgh1c2VyZGF0YRgFIAEoCzIjLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuVXNlckRhdG'
'FIAFIIdXNlcmRhdGFCBAoCT2tCCgoIUmVzcG9uc2U=');

View file

@ -33,6 +33,7 @@ class ApiProvider {
final String apiUrl;
final String? backupApiUrl;
int _reconnectionDelay = 5;
bool _tryingToConnect = false;
final log = Logger("api_provider");
Function(bool)? _connectionStateCallback;
@ -103,8 +104,11 @@ class ApiProvider {
}
void tryToReconnect() {
if (_tryingToConnect) return;
_tryingToConnect = true;
Future.delayed(Duration(seconds: _reconnectionDelay)).then(
(value) async {
_tryingToConnect = false;
_reconnectionDelay = _reconnectionDelay + 2;
if (_reconnectionDelay > 20) {
_reconnectionDelay = 20;
@ -316,7 +320,7 @@ class ApiProvider {
..username = username
..publicIdentityKey =
(await signalStore.getIdentityKeyPair()).getPublicKey().serialize()
..registrationId = Int64(signalIdentity.registrationId)
..registrationId = signalIdentity.registrationId
..signedPrekey = signedPreKey.getKeyPair().publicKey.serialize()
..signedPrekeySignature = signedPreKey.signature
..signedPrekeyId = Int64(signedPreKey.id);

View file

@ -14,36 +14,45 @@ class SettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Settings'),
),
body: Padding(
padding: const EdgeInsets.all(16),
// Glue the SettingsController to the theme selection DropdownButton.
//
// When a user selects a theme from the dropdown list, the
// SettingsController is updated, which rebuilds the MaterialApp.
child: DropdownButton<ThemeMode>(
// Read the selected themeMode from the controller
value: controller.themeMode,
// Call the updateThemeMode method any time the user selects a theme.
onChanged: controller.updateThemeMode,
items: const [
DropdownMenuItem(
value: ThemeMode.system,
child: Text('System Theme'),
),
DropdownMenuItem(
value: ThemeMode.light,
child: Text('Light Theme'),
),
DropdownMenuItem(
value: ThemeMode.dark,
child: Text('Dark Theme'),
)
],
appBar: AppBar(
title: const Text('Settings'),
),
),
);
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
// Glue the SettingsController to the theme selection DropdownButton.
//
// When a user selects a theme from the dropdown list, the
// SettingsController is updated, which rebuilds the MaterialApp.
child: DropdownButton<ThemeMode>(
// Read the selected themeMode from the controller
value: controller.themeMode,
// Call the updateThemeMode method any time the user selects a theme.
onChanged: controller.updateThemeMode,
items: const [
DropdownMenuItem(
value: ThemeMode.system,
child: Text('System Theme'),
),
DropdownMenuItem(
value: ThemeMode.light,
child: Text('Light Theme'),
),
DropdownMenuItem(
value: ThemeMode.dark,
child: Text('Dark Theme'),
)
],
),
),
ElevatedButton(
onPressed: () {
showLicensePage(context: context);
},
child: Text('Show Licenses'),
),
],
));
}
}

View file

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
import 'package:fixnum/fixnum.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:logging/logging.dart';
import 'package:twonly/src/model/signal_identity_json.dart';
@ -121,10 +122,10 @@ class SignalHelper {
}
static Future<bool> addNewContact(Response_UserData userData) async {
final List<int> userId = userData.userId;
final Int64 userId = userData.userId;
SignalProtocolAddress targetAddress = SignalProtocolAddress(
uint8ListToHex(userId), SignalHelper.defaultDeviceId);
SignalProtocolAddress targetAddress =
SignalProtocolAddress(userId.toString(), SignalHelper.defaultDeviceId);
SignalProtocolStore? signalStore = await SignalHelper.getSignalStore();
if (signalStore == null) {
@ -161,7 +162,7 @@ class SignalHelper {
.serialize(),
1));
PreKeyBundle preKeyBundle = PreKeyBundle(
userData.registrationId.toInt(),
userData.userId.toInt(),
1,
tempPreKeyId,
tempPrePublicKey,
@ -200,7 +201,7 @@ class SignalHelper {
IdentityKeyPair.fromSerialized(signalIdentity.identityKeyPairU8List);
return ConnectSignalProtocolStore(
identityKeyPair, signalIdentity.registrationId);
identityKeyPair, signalIdentity.registrationId.toInt());
}
static Future<List<PreKeyRecord>> getPreKeys() async {
@ -235,7 +236,7 @@ class SignalHelper {
final storedSignalIdentity = SignalIdentity(
identityKeyPairU8List: identityKeyPair.serialize(),
registrationId: registrationId);
registrationId: Int64(registrationId));
await storage.write(
key: "signal_identity", value: jsonEncode(storedSignalIdentity));

View file

@ -102,7 +102,7 @@ Future<bool> addNewUser(String username) async {
if (await SignalHelper.addNewContact(res.value.userdata)) {
await dbProvider.db!.insert(DbContacts.tableName, {
DbContacts.columnDisplayName: username,
DbContacts.columnUserId: res.value.userdata.userId
DbContacts.columnUserId: res.value.userdata.userId.toInt()
});
}
print("Add new user: ${res}");

View file

@ -136,7 +136,7 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
if (tmp != _lastZoom) {
cameraState.sensorConfig.setZoom(tmp);
setState(() {
print(tmp);
(tmp);
_lastZoom = tmp;
});
}

View file

@ -44,21 +44,21 @@ class OnboardingView extends StatelessWidget {
),
),
),
PageViewModel(
title: "Hard work",
body:
"We try everything to give you the best experience but developing and maintaining is hard work and requires thousand of hours.",
image: Center(
child: Padding(
padding: const EdgeInsets.only(top: 100),
child: Image.asset("assets/images/onboarding/04.png"),
),
),
),
// PageViewModel(
// title: "Hard work",
// body:
// "We try everything to give you the best experience but developing and maintaining is hard work and requires thousand of hours.",
// image: Center(
// child: Padding(
// padding: const EdgeInsets.only(top: 100),
// child: Image.asset("assets/images/onboarding/04.png"),
// ),
// ),
// ),
PageViewModel(
title: "You are not the product!",
body:
"Nothing is free. Either you pay with your personal informations or with money. Twonly gives you the chance to use an sustainable social media product without exploiting you by collection you personal data.",
"Nothing is free. Either you pay with your personal informations or with money. Twonly gives you the chance to use an social media product without exploiting you by collection you personal data.",
image: Center(
child: Padding(
padding: const EdgeInsets.only(top: 100),
@ -71,7 +71,7 @@ class OnboardingView extends StatelessWidget {
bodyWidget: Column(
children: [
Text(
"You can test twonly free for 14 days and then decide it is worth for you.",
"You can test twonly free for 14 days and then decide if it is worth to you.",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
),

View file

@ -1,3 +1,6 @@
import 'dart:collection';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:twonly/src/components/initialsavatar_component.dart';
@ -13,6 +16,7 @@ class ShareImageView extends StatefulWidget {
class _ShareImageView extends State<ShareImageView> {
List<Contact> _knownUsers = [];
final HashSet<Int64> _selectedUserIds = HashSet<Int64>();
@override
void initState() {
@ -31,13 +35,34 @@ class _ShareImageView extends State<ShareImageView> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.newMessageTitle),
title: Text(AppLocalizations.of(context)!.shareImageTitle),
),
body: Padding(
padding: EdgeInsets.only(bottom: 20, left: 10, top: 20, right: 10),
child: Column(
children: [
UserCheckboxList(users: _knownUsers),
Container(
alignment:
Alignment.centerLeft, // Aligns the container to the left
padding: EdgeInsets.all(16.0), // Optional: Add some padding
child: Text(
'Best friends',
style: TextStyle(
fontSize: 20, // Set the font size to 20
),
),
),
UserCheckboxList(
users: _knownUsers,
onChanged: (userId, checkedId) {
setState(() {
if (checkedId) {
_selectedUserIds.add(userId);
} else {
_selectedUserIds.remove(userId);
}
});
}),
const SizedBox(height: 10),
// Expanded(
// child: UserList(_filteredUsers),
@ -51,8 +76,10 @@ class _ShareImageView extends State<ShareImageView> {
class UserCheckboxList extends StatelessWidget {
final List<Contact> users;
final Function(Int64, bool) onChanged;
UserCheckboxList({required this.users});
const UserCheckboxList(
{super.key, required this.users, required this.onChanged});
@override
Widget build(BuildContext context) {
@ -67,9 +94,14 @@ class UserCheckboxList extends StatelessWidget {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(limitedUsers[firstUserIndex].displayName),
Expanded(
child: UserCheckbox(
user: limitedUsers[firstUserIndex], onChanged: onChanged)),
if (secondUserIndex < limitedUsers.length)
Text(limitedUsers[secondUserIndex].displayName),
Expanded(
child: UserCheckbox(
user: limitedUsers[secondUserIndex],
onChanged: onChanged)),
],
);
}),
@ -79,11 +111,12 @@ class UserCheckboxList extends StatelessWidget {
class UserCheckbox extends StatefulWidget {
final Contact user;
final Function(Int64, bool) onChanged;
UserCheckbox({required this.user});
const UserCheckbox({super.key, required this.user, required this.onChanged});
@override
_UserCheckboxState createState() => _UserCheckboxState();
State<UserCheckbox> createState() => _UserCheckboxState();
}
class _UserCheckboxState extends State<UserCheckbox> {
@ -91,31 +124,56 @@ class _UserCheckboxState extends State<UserCheckbox> {
@override
Widget build(BuildContext context) {
return Row(
children: [
Checkbox(
value: isChecked,
onChanged: (bool? value) {
setState(() {
isChecked = value ?? false;
});
},
),
CircleAvatar(
child: InitialsAvatar(
displayName:
widget.user.displayName), // Display first letter of the name
),
SizedBox(width: 8),
Expanded(
child: Text(
widget.user.displayName.length > 10
? '${widget.user.displayName.substring(0, 10)}...' // Trim if too long
: widget.user.displayName,
overflow: TextOverflow.ellipsis,
return Container(
padding:
EdgeInsets.symmetric(horizontal: 3), // Padding inside the container
child: GestureDetector(
onTap: () {
setState(() {
isChecked = !isChecked;
widget.onChanged(widget.user.userId, isChecked);
});
},
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 0), // Padding inside the container
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.outline,
// color: Colors.blue, // Border color
width: 1.0, // Border width
),
borderRadius:
BorderRadius.circular(8.0), // Optional: Rounded corners
),
child: Row(
children: [
InitialsAvatar(
fontSize: 15,
displayName: widget
.user.displayName), // Display first letter of the name
SizedBox(width: 8),
Expanded(
child: Text(
widget.user.displayName.length > 10
? '${widget.user.displayName.substring(0, 10)}...' // Trim if too long
: widget.user.displayName,
overflow: TextOverflow.ellipsis,
),
),
Checkbox(
value: isChecked,
onChanged: (bool? value) {
setState(() {
isChecked = value ?? false;
widget.onChanged(widget.user.userId, isChecked);
});
},
),
],
),
),
],
),
);
}
}