authentication works

This commit is contained in:
otsmr 2025-03-15 01:48:27 +01:00
parent 5866d3e7e4
commit c6c625df59
19 changed files with 592 additions and 250 deletions

View file

@ -17,7 +17,7 @@ if (keystorePropertiesFile.exists()) {
android {
namespace = "com.example.connect"
// compileSdk = flutter.compileSdkVersion
compileSdk 34
compileSdk 35
//ndkVersion = flutter.ndkVersion
ndkVersion = "25.1.8937393"

View file

@ -33,6 +33,8 @@ void main() async {
}
});
await deleteLogFile();
await setupPushNotification();
await initMediaStorage();
await initFCMService();

View file

@ -1,3 +1,4 @@
import 'dart:collection';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@ -52,9 +53,9 @@ class MessageSendStateIcon extends StatefulWidget {
}
class _MessageSendStateIconState extends State<MessageSendStateIcon> {
bool containsVideo = false;
bool containsText = false;
bool containsImage = false;
Message? videoMsg;
Message? textMsg;
Message? imageMsg;
@override
void initState() {
@ -62,7 +63,7 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
for (Message msg in widget.messages) {
if (msg.kind == MessageKind.textMessage) {
containsText = true;
textMsg = msg;
}
if (msg.kind == MessageKind.media) {
MessageJson message =
@ -70,21 +71,17 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
final content = message.content;
if (content is MediaMessageContent) {
if (content.isVideo) {
containsVideo = true;
videoMsg = msg;
} else {
containsImage = true;
imageMsg = msg;
}
}
}
}
}
@override
Widget build(BuildContext context) {
Widget icon = Placeholder();
String text = "";
Widget loaderIcon = Row(
Widget getLoaderIcon(color) {
return Row(
children: [
SizedBox(
width: 10,
@ -94,39 +91,70 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
SizedBox(width: 2),
],
);
}
MessageSendState state = messageSendStateFromMessage(message);
@override
Widget build(BuildContext context) {
List<Widget> icons = [];
String text = "";
switch (state) {
case MessageSendState.receivedOpened:
icon = Icon(Icons.crop_square, size: 14, color: color);
text = context.lang.messageSendState_Received;
break;
case MessageSendState.sendOpened:
icon = FaIcon(FontAwesomeIcons.paperPlane, size: 12, color: color);
text = context.lang.messageSendState_Opened;
break;
case MessageSendState.received:
icon = Icon(Icons.square_rounded, size: 14, color: color);
text = context.lang.messageSendState_Received;
break;
case MessageSendState.send:
icon = FaIcon(FontAwesomeIcons.solidPaperPlane, size: 12, color: color);
text = context.lang.messageSendState_Send;
break;
case MessageSendState.sending:
case MessageSendState.receiving:
icon = loaderIcon;
text = context.lang.messageSendState_Sending;
break;
Color twonlyColor = Theme.of(context).colorScheme.primary;
HashSet<MessageKind> kindsAlreadyShown = HashSet();
for (final message in widget.messages) {
if (icons.length == 2) break;
if (message.contentJson == null) continue;
if (kindsAlreadyShown.contains(message.kind)) continue;
kindsAlreadyShown.add(message.kind);
Widget icon = Placeholder();
MessageSendState state = messageSendStateFromMessage(message);
MessageJson msg = MessageJson.fromJson(jsonDecode(message.contentJson!));
if (msg.content == null) continue;
Color color = getMessageColorFromType(msg.content!, twonlyColor);
switch (state) {
case MessageSendState.receivedOpened:
icon = Icon(Icons.crop_square, size: 14, color: color);
text = context.lang.messageSendState_Received;
break;
case MessageSendState.sendOpened:
icon = FaIcon(FontAwesomeIcons.paperPlane, size: 12, color: color);
text = context.lang.messageSendState_Opened;
break;
case MessageSendState.received:
icon = Icon(Icons.square_rounded, size: 14, color: color);
text = context.lang.messageSendState_Received;
break;
case MessageSendState.send:
icon =
FaIcon(FontAwesomeIcons.solidPaperPlane, size: 12, color: color);
text = context.lang.messageSendState_Send;
break;
case MessageSendState.sending:
case MessageSendState.receiving:
icon = getLoaderIcon(color);
text = context.lang.messageSendState_Sending;
break;
}
if (message.downloadState == DownloadState.pending) {
text = context.lang.messageSendState_TapToLoad;
}
if (message.downloadState == DownloadState.downloaded) {
text = context.lang.messageSendState_Loading;
icon = getLoaderIcon(color);
}
icons.add(icon);
}
if (message.downloadState == DownloadState.pending) {
text = context.lang.messageSendState_TapToLoad;
}
if (message.downloadState == DownloadState.downloaded) {
text = context.lang.messageSendState_Loading;
icon = loaderIcon;
Widget icon = icons[0];
if (icons.length == 2) {
icon = Stack(
children: icons,
);
}
return Row(

View file

@ -99,8 +99,12 @@ class TwonlyDatabase extends _$TwonlyDatabase {
// ------------
Future<int> insertContact(ContactsCompanion contact) {
return into(contacts).insert(contact);
Future<int> insertContact(ContactsCompanion contact) async {
try {
return await into(contacts).insert(contact);
} catch (e) {
return 0;
}
}
Future incTotalMediaCounter(int contactId) async {
@ -140,6 +144,7 @@ class TwonlyDatabase extends _$TwonlyDatabase {
Stream<List<Contact>> watchNotAcceptedContacts() {
return (select(contacts)..where((t) => t.accepted.equals(false))).watch();
// return (select(contacts)).watch();
}
Stream<Contact> watchContact(int userid) {

View file

@ -754,7 +754,9 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> {
@override
late final GeneratedColumnWithTypeConverter<DownloadState, int>
downloadState = GeneratedColumn<int>('download_state', aliasedName, false,
type: DriftSqlType.int, requiredDuringInsert: true)
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultValue: Constant(DownloadState.pending.index))
.withConverter<DownloadState>($MessagesTable.$converterdownloadState);
static const VerificationMeta _acknowledgeByServerMeta =
const VerificationMeta('acknowledgeByServer');
@ -1230,7 +1232,7 @@ class MessagesCompanion extends UpdateCompanion<Message> {
this.responseToMessageId = const Value.absent(),
this.responseToOtherMessageId = const Value.absent(),
this.acknowledgeByUser = const Value.absent(),
required DownloadState downloadState,
this.downloadState = const Value.absent(),
this.acknowledgeByServer = const Value.absent(),
required MessageKind kind,
this.contentJson = const Value.absent(),
@ -1238,7 +1240,6 @@ class MessagesCompanion extends UpdateCompanion<Message> {
this.sendAt = const Value.absent(),
this.updatedAt = const Value.absent(),
}) : contactId = Value(contactId),
downloadState = Value(downloadState),
kind = Value(kind);
static Insertable<Message> custom({
Expression<int>? contactId,
@ -1781,7 +1782,7 @@ typedef $$MessagesTableCreateCompanionBuilder = MessagesCompanion Function({
Value<int?> responseToMessageId,
Value<int?> responseToOtherMessageId,
Value<bool> acknowledgeByUser,
required DownloadState downloadState,
Value<DownloadState> downloadState,
Value<bool> acknowledgeByServer,
required MessageKind kind,
Value<String?> contentJson,
@ -2098,7 +2099,7 @@ class $$MessagesTableTableManager extends RootTableManager<
Value<int?> responseToMessageId = const Value.absent(),
Value<int?> responseToOtherMessageId = const Value.absent(),
Value<bool> acknowledgeByUser = const Value.absent(),
required DownloadState downloadState,
Value<DownloadState> downloadState = const Value.absent(),
Value<bool> acknowledgeByServer = const Value.absent(),
required MessageKind kind,
Value<String?> contentJson = const Value.absent(),

View file

@ -10,24 +10,30 @@ enum MessageKind {
ack
}
Map<String, Color> messageKindColors = {
"video": Colors.deepPurple,
"text": Colors.lightBlue,
"image": Color.fromARGB(255, 214, 47, 47),
};
Color getMessageColorFromType(MessageContent content, Color primary) {
Color color;
if (content is TextMessageContent) {
color = Colors.lightBlue;
color = messageKindColors["text"]!;
} else {
if (content is MediaMessageContent) {
if (content.isRealTwonly) {
color = primary;
} else {
if (content.isVideo) {
color = Colors.deepPurple;
color = messageKindColors["video"]!;
} else {
color = const Color.fromARGB(255, 214, 47, 47);
color = messageKindColors["image"]!;
}
}
} else {
return Colors.black; // this should not happen
return Colors.black;
}
}
return color;

View file

@ -330,13 +330,13 @@ class Handshake_Register extends $pb.GeneratedMessage {
void clearRegistrationId() => clearField(7);
}
class Handshake_GetChallenge extends $pb.GeneratedMessage {
factory Handshake_GetChallenge() => create();
Handshake_GetChallenge._() : super();
factory Handshake_GetChallenge.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Handshake_GetChallenge.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
class Handshake_GetAuthChallenge extends $pb.GeneratedMessage {
factory Handshake_GetAuthChallenge() => create();
Handshake_GetAuthChallenge._() : super();
factory Handshake_GetAuthChallenge.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Handshake_GetAuthChallenge.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake.GetChallenge', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake.GetAuthChallenge', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..hasRequiredFields = false
;
@ -344,26 +344,26 @@ class Handshake_GetChallenge extends $pb.GeneratedMessage {
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Handshake_GetChallenge clone() => Handshake_GetChallenge()..mergeFromMessage(this);
Handshake_GetAuthChallenge clone() => Handshake_GetAuthChallenge()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Handshake_GetChallenge copyWith(void Function(Handshake_GetChallenge) updates) => super.copyWith((message) => updates(message as Handshake_GetChallenge)) as Handshake_GetChallenge;
Handshake_GetAuthChallenge copyWith(void Function(Handshake_GetAuthChallenge) updates) => super.copyWith((message) => updates(message as Handshake_GetAuthChallenge)) as Handshake_GetAuthChallenge;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Handshake_GetChallenge create() => Handshake_GetChallenge._();
Handshake_GetChallenge createEmptyInstance() => create();
static $pb.PbList<Handshake_GetChallenge> createRepeated() => $pb.PbList<Handshake_GetChallenge>();
static Handshake_GetAuthChallenge create() => Handshake_GetAuthChallenge._();
Handshake_GetAuthChallenge createEmptyInstance() => create();
static $pb.PbList<Handshake_GetAuthChallenge> createRepeated() => $pb.PbList<Handshake_GetAuthChallenge>();
@$core.pragma('dart2js:noInline')
static Handshake_GetChallenge getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Handshake_GetChallenge>(create);
static Handshake_GetChallenge? _defaultInstance;
static Handshake_GetAuthChallenge getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Handshake_GetAuthChallenge>(create);
static Handshake_GetAuthChallenge? _defaultInstance;
}
class Handshake_OpenSession extends $pb.GeneratedMessage {
factory Handshake_OpenSession({
class Handshake_GetAuthToken extends $pb.GeneratedMessage {
factory Handshake_GetAuthToken({
$fixnum.Int64? userId,
$core.List<$core.int>? response,
}) {
@ -376,11 +376,11 @@ class Handshake_OpenSession extends $pb.GeneratedMessage {
}
return $result;
}
Handshake_OpenSession._() : super();
factory Handshake_OpenSession.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Handshake_OpenSession.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
Handshake_GetAuthToken._() : super();
factory Handshake_GetAuthToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Handshake_GetAuthToken.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)
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake.GetAuthToken', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'response', $pb.PbFieldType.OY)
..hasRequiredFields = false
@ -390,22 +390,22 @@ class Handshake_OpenSession extends $pb.GeneratedMessage {
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Handshake_OpenSession clone() => Handshake_OpenSession()..mergeFromMessage(this);
Handshake_GetAuthToken clone() => Handshake_GetAuthToken()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Handshake_OpenSession copyWith(void Function(Handshake_OpenSession) updates) => super.copyWith((message) => updates(message as Handshake_OpenSession)) as Handshake_OpenSession;
Handshake_GetAuthToken copyWith(void Function(Handshake_GetAuthToken) updates) => super.copyWith((message) => updates(message as Handshake_GetAuthToken)) as Handshake_GetAuthToken;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Handshake_OpenSession create() => Handshake_OpenSession._();
Handshake_OpenSession createEmptyInstance() => create();
static $pb.PbList<Handshake_OpenSession> createRepeated() => $pb.PbList<Handshake_OpenSession>();
static Handshake_GetAuthToken create() => Handshake_GetAuthToken._();
Handshake_GetAuthToken createEmptyInstance() => create();
static $pb.PbList<Handshake_GetAuthToken> createRepeated() => $pb.PbList<Handshake_GetAuthToken>();
@$core.pragma('dart2js:noInline')
static Handshake_OpenSession getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Handshake_OpenSession>(create);
static Handshake_OpenSession? _defaultInstance;
static Handshake_GetAuthToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Handshake_GetAuthToken>(create);
static Handshake_GetAuthToken? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get userId => $_getI64(0);
@ -426,28 +426,97 @@ class Handshake_OpenSession extends $pb.GeneratedMessage {
void clearResponse() => clearField(2);
}
class Handshake_Authenticate extends $pb.GeneratedMessage {
factory Handshake_Authenticate({
$fixnum.Int64? userId,
$core.List<$core.int>? authToken,
}) {
final $result = create();
if (userId != null) {
$result.userId = userId;
}
if (authToken != null) {
$result.authToken = authToken;
}
return $result;
}
Handshake_Authenticate._() : super();
factory Handshake_Authenticate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Handshake_Authenticate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake.Authenticate', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'userId')
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'authToken', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Handshake_Authenticate clone() => Handshake_Authenticate()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Handshake_Authenticate copyWith(void Function(Handshake_Authenticate) updates) => super.copyWith((message) => updates(message as Handshake_Authenticate)) as Handshake_Authenticate;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Handshake_Authenticate create() => Handshake_Authenticate._();
Handshake_Authenticate createEmptyInstance() => create();
static $pb.PbList<Handshake_Authenticate> createRepeated() => $pb.PbList<Handshake_Authenticate>();
@$core.pragma('dart2js:noInline')
static Handshake_Authenticate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Handshake_Authenticate>(create);
static Handshake_Authenticate? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get userId => $_getI64(0);
@$pb.TagNumber(1)
set userId($fixnum.Int64 v) { $_setInt64(0, v); }
@$pb.TagNumber(1)
$core.bool hasUserId() => $_has(0);
@$pb.TagNumber(1)
void clearUserId() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get authToken => $_getN(1);
@$pb.TagNumber(2)
set authToken($core.List<$core.int> v) { $_setBytes(1, v); }
@$pb.TagNumber(2)
$core.bool hasAuthToken() => $_has(1);
@$pb.TagNumber(2)
void clearAuthToken() => clearField(2);
}
enum Handshake_Handshake {
register,
getchallenge,
opensession,
getauthchallenge,
getauthtoken,
authenticate,
notSet
}
class Handshake extends $pb.GeneratedMessage {
factory Handshake({
Handshake_Register? register,
Handshake_GetChallenge? getchallenge,
Handshake_OpenSession? opensession,
Handshake_GetAuthChallenge? getauthchallenge,
Handshake_GetAuthToken? getauthtoken,
Handshake_Authenticate? authenticate,
}) {
final $result = create();
if (register != null) {
$result.register = register;
}
if (getchallenge != null) {
$result.getchallenge = getchallenge;
if (getauthchallenge != null) {
$result.getauthchallenge = getauthchallenge;
}
if (opensession != null) {
$result.opensession = opensession;
if (getauthtoken != null) {
$result.getauthtoken = getauthtoken;
}
if (authenticate != null) {
$result.authenticate = authenticate;
}
return $result;
}
@ -457,15 +526,17 @@ class Handshake extends $pb.GeneratedMessage {
static const $core.Map<$core.int, Handshake_Handshake> _Handshake_HandshakeByTag = {
1 : Handshake_Handshake.register,
2 : Handshake_Handshake.getchallenge,
3 : Handshake_Handshake.opensession,
2 : Handshake_Handshake.getauthchallenge,
3 : Handshake_Handshake.getauthtoken,
4 : Handshake_Handshake.authenticate,
0 : Handshake_Handshake.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Handshake', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..oo(0, [1, 2, 3])
..oo(0, [1, 2, 3, 4])
..aOM<Handshake_Register>(1, _omitFieldNames ? '' : 'register', subBuilder: Handshake_Register.create)
..aOM<Handshake_GetChallenge>(2, _omitFieldNames ? '' : 'getchallenge', subBuilder: Handshake_GetChallenge.create)
..aOM<Handshake_OpenSession>(3, _omitFieldNames ? '' : 'opensession', subBuilder: Handshake_OpenSession.create)
..aOM<Handshake_GetAuthChallenge>(2, _omitFieldNames ? '' : 'getauthchallenge', subBuilder: Handshake_GetAuthChallenge.create)
..aOM<Handshake_GetAuthToken>(3, _omitFieldNames ? '' : 'getauthtoken', subBuilder: Handshake_GetAuthToken.create)
..aOM<Handshake_Authenticate>(4, _omitFieldNames ? '' : 'authenticate', subBuilder: Handshake_Authenticate.create)
..hasRequiredFields = false
;
@ -505,26 +576,37 @@ class Handshake extends $pb.GeneratedMessage {
Handshake_Register ensureRegister() => $_ensure(0);
@$pb.TagNumber(2)
Handshake_GetChallenge get getchallenge => $_getN(1);
Handshake_GetAuthChallenge get getauthchallenge => $_getN(1);
@$pb.TagNumber(2)
set getchallenge(Handshake_GetChallenge v) { setField(2, v); }
set getauthchallenge(Handshake_GetAuthChallenge v) { setField(2, v); }
@$pb.TagNumber(2)
$core.bool hasGetchallenge() => $_has(1);
$core.bool hasGetauthchallenge() => $_has(1);
@$pb.TagNumber(2)
void clearGetchallenge() => clearField(2);
void clearGetauthchallenge() => clearField(2);
@$pb.TagNumber(2)
Handshake_GetChallenge ensureGetchallenge() => $_ensure(1);
Handshake_GetAuthChallenge ensureGetauthchallenge() => $_ensure(1);
@$pb.TagNumber(3)
Handshake_OpenSession get opensession => $_getN(2);
Handshake_GetAuthToken get getauthtoken => $_getN(2);
@$pb.TagNumber(3)
set opensession(Handshake_OpenSession v) { setField(3, v); }
set getauthtoken(Handshake_GetAuthToken v) { setField(3, v); }
@$pb.TagNumber(3)
$core.bool hasOpensession() => $_has(2);
$core.bool hasGetauthtoken() => $_has(2);
@$pb.TagNumber(3)
void clearOpensession() => clearField(3);
void clearGetauthtoken() => clearField(3);
@$pb.TagNumber(3)
Handshake_OpenSession ensureOpensession() => $_ensure(2);
Handshake_GetAuthToken ensureGetauthtoken() => $_ensure(2);
@$pb.TagNumber(4)
Handshake_Authenticate get authenticate => $_getN(3);
@$pb.TagNumber(4)
set authenticate(Handshake_Authenticate v) { setField(4, v); }
@$pb.TagNumber(4)
$core.bool hasAuthenticate() => $_has(3);
@$pb.TagNumber(4)
void clearAuthenticate() => clearField(4);
@$pb.TagNumber(4)
Handshake_Authenticate ensureAuthenticate() => $_ensure(3);
}
class ApplicationData_TextMessage extends $pb.GeneratedMessage {
@ -792,12 +874,21 @@ class ApplicationData_GetPrekeysByUserId extends $pb.GeneratedMessage {
}
class ApplicationData_GetUploadToken extends $pb.GeneratedMessage {
factory ApplicationData_GetUploadToken() => create();
factory ApplicationData_GetUploadToken({
$core.int? recipientsCount,
}) {
final $result = create();
if (recipientsCount != null) {
$result.recipientsCount = recipientsCount;
}
return $result;
}
ApplicationData_GetUploadToken._() : super();
factory ApplicationData_GetUploadToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ApplicationData_GetUploadToken.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.GetUploadToken', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..a<$core.int>(1, _omitFieldNames ? '' : 'recipientsCount', $pb.PbFieldType.OU3)
..hasRequiredFields = false
;
@ -821,6 +912,15 @@ class ApplicationData_GetUploadToken extends $pb.GeneratedMessage {
@$core.pragma('dart2js:noInline')
static ApplicationData_GetUploadToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ApplicationData_GetUploadToken>(create);
static ApplicationData_GetUploadToken? _defaultInstance;
@$pb.TagNumber(1)
$core.int get recipientsCount => $_getIZ(0);
@$pb.TagNumber(1)
set recipientsCount($core.int v) { $_setUnsignedInt32(0, v); }
@$pb.TagNumber(1)
$core.bool hasRecipientsCount() => $_has(0);
@$pb.TagNumber(1)
void clearRecipientsCount() => clearField(1);
}
class ApplicationData_UploadData extends $pb.GeneratedMessage {
@ -828,6 +928,7 @@ class ApplicationData_UploadData extends $pb.GeneratedMessage {
$core.List<$core.int>? uploadToken,
$core.int? offset,
$core.List<$core.int>? data,
$core.List<$core.int>? checksum,
}) {
final $result = create();
if (uploadToken != null) {
@ -839,6 +940,9 @@ class ApplicationData_UploadData extends $pb.GeneratedMessage {
if (data != null) {
$result.data = data;
}
if (checksum != null) {
$result.checksum = checksum;
}
return $result;
}
ApplicationData_UploadData._() : super();
@ -849,6 +953,7 @@ class ApplicationData_UploadData extends $pb.GeneratedMessage {
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'uploadToken', $pb.PbFieldType.OY)
..a<$core.int>(2, _omitFieldNames ? '' : 'offset', $pb.PbFieldType.OU3)
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'data', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(4, _omitFieldNames ? '' : 'checksum', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@ -899,16 +1004,25 @@ class ApplicationData_UploadData extends $pb.GeneratedMessage {
$core.bool hasData() => $_has(2);
@$pb.TagNumber(3)
void clearData() => clearField(3);
@$pb.TagNumber(4)
$core.List<$core.int> get checksum => $_getN(3);
@$pb.TagNumber(4)
set checksum($core.List<$core.int> v) { $_setBytes(3, v); }
@$pb.TagNumber(4)
$core.bool hasChecksum() => $_has(3);
@$pb.TagNumber(4)
void clearChecksum() => clearField(4);
}
class ApplicationData_DownloadData extends $pb.GeneratedMessage {
factory ApplicationData_DownloadData({
$core.List<$core.int>? uploadToken,
$core.List<$core.int>? downloadToken,
$core.int? offset,
}) {
final $result = create();
if (uploadToken != null) {
$result.uploadToken = uploadToken;
if (downloadToken != null) {
$result.downloadToken = downloadToken;
}
if (offset != null) {
$result.offset = offset;
@ -920,7 +1034,7 @@ class ApplicationData_DownloadData extends $pb.GeneratedMessage {
factory ApplicationData_DownloadData.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ApplicationData.DownloadData', package: const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'uploadToken', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'downloadToken', $pb.PbFieldType.OY)
..a<$core.int>(2, _omitFieldNames ? '' : 'offset', $pb.PbFieldType.OU3)
..hasRequiredFields = false
;
@ -947,13 +1061,13 @@ class ApplicationData_DownloadData extends $pb.GeneratedMessage {
static ApplicationData_DownloadData? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get uploadToken => $_getN(0);
$core.List<$core.int> get downloadToken => $_getN(0);
@$pb.TagNumber(1)
set uploadToken($core.List<$core.int> v) { $_setBytes(0, v); }
set downloadToken($core.List<$core.int> v) { $_setBytes(0, v); }
@$pb.TagNumber(1)
$core.bool hasUploadToken() => $_has(0);
$core.bool hasDownloadToken() => $_has(0);
@$pb.TagNumber(1)
void clearUploadToken() => clearField(1);
void clearDownloadToken() => clearField(1);
@$pb.TagNumber(2)
$core.int get offset => $_getIZ(1);

View file

@ -56,10 +56,11 @@ const Handshake$json = {
'1': 'Handshake',
'2': [
{'1': 'register', '3': 1, '4': 1, '5': 11, '6': '.client_to_server.Handshake.Register', '9': 0, '10': 'register'},
{'1': 'getchallenge', '3': 2, '4': 1, '5': 11, '6': '.client_to_server.Handshake.GetChallenge', '9': 0, '10': 'getchallenge'},
{'1': 'opensession', '3': 3, '4': 1, '5': 11, '6': '.client_to_server.Handshake.OpenSession', '9': 0, '10': 'opensession'},
{'1': 'getauthchallenge', '3': 2, '4': 1, '5': 11, '6': '.client_to_server.Handshake.GetAuthChallenge', '9': 0, '10': 'getauthchallenge'},
{'1': 'getauthtoken', '3': 3, '4': 1, '5': 11, '6': '.client_to_server.Handshake.GetAuthToken', '9': 0, '10': 'getauthtoken'},
{'1': 'authenticate', '3': 4, '4': 1, '5': 11, '6': '.client_to_server.Handshake.Authenticate', '9': 0, '10': 'authenticate'},
],
'3': [Handshake_Register$json, Handshake_GetChallenge$json, Handshake_OpenSession$json],
'3': [Handshake_Register$json, Handshake_GetAuthChallenge$json, Handshake_GetAuthToken$json, Handshake_Authenticate$json],
'8': [
{'1': 'Handshake'},
],
@ -83,33 +84,45 @@ const Handshake_Register$json = {
};
@$core.Deprecated('Use handshakeDescriptor instead')
const Handshake_GetChallenge$json = {
'1': 'GetChallenge',
const Handshake_GetAuthChallenge$json = {
'1': 'GetAuthChallenge',
};
@$core.Deprecated('Use handshakeDescriptor instead')
const Handshake_OpenSession$json = {
'1': 'OpenSession',
const Handshake_GetAuthToken$json = {
'1': 'GetAuthToken',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
{'1': 'response', '3': 2, '4': 1, '5': 12, '10': 'response'},
],
};
@$core.Deprecated('Use handshakeDescriptor instead')
const Handshake_Authenticate$json = {
'1': 'Authenticate',
'2': [
{'1': 'user_id', '3': 1, '4': 1, '5': 3, '10': 'userId'},
{'1': 'auth_token', '3': 2, '4': 1, '5': 12, '10': 'authToken'},
],
};
/// Descriptor for `Handshake`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List handshakeDescriptor = $convert.base64Decode(
'CglIYW5kc2hha2USQgoIcmVnaXN0ZXIYASABKAsyJC5jbGllbnRfdG9fc2VydmVyLkhhbmRzaG'
'FrZS5SZWdpc3RlckgAUghyZWdpc3RlchJOCgxnZXRjaGFsbGVuZ2UYAiABKAsyKC5jbGllbnRf'
'dG9fc2VydmVyLkhhbmRzaGFrZS5HZXRDaGFsbGVuZ2VIAFIMZ2V0Y2hhbGxlbmdlEksKC29wZW'
'5zZXNzaW9uGAMgASgLMicuY2xpZW50X3RvX3NlcnZlci5IYW5kc2hha2UuT3BlblNlc3Npb25I'
'AFILb3BlbnNlc3Npb24avAIKCFJlZ2lzdGVyEhoKCHVzZXJuYW1lGAEgASgJUgh1c2VybmFtZR'
'IkCgtpbnZpdGVfY29kZRgCIAEoCUgAUgppbnZpdGVDb2RliAEBEi4KE3B1YmxpY19pZGVudGl0'
'eV9rZXkYAyABKAxSEXB1YmxpY0lkZW50aXR5S2V5EiMKDXNpZ25lZF9wcmVrZXkYBCABKAxSDH'
'NpZ25lZFByZWtleRI2ChdzaWduZWRfcHJla2V5X3NpZ25hdHVyZRgFIAEoDFIVc2lnbmVkUHJl'
'a2V5U2lnbmF0dXJlEigKEHNpZ25lZF9wcmVrZXlfaWQYBiABKANSDnNpZ25lZFByZWtleUlkEi'
'cKD3JlZ2lzdHJhdGlvbl9pZBgHIAEoA1IOcmVnaXN0cmF0aW9uSWRCDgoMX2ludml0ZV9jb2Rl'
'Gg4KDEdldENoYWxsZW5nZRpCCgtPcGVuU2Vzc2lvbhIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySW'
'QSGgoIcmVzcG9uc2UYAiABKAxSCHJlc3BvbnNlQgsKCUhhbmRzaGFrZQ==');
'FrZS5SZWdpc3RlckgAUghyZWdpc3RlchJaChBnZXRhdXRoY2hhbGxlbmdlGAIgASgLMiwuY2xp'
'ZW50X3RvX3NlcnZlci5IYW5kc2hha2UuR2V0QXV0aENoYWxsZW5nZUgAUhBnZXRhdXRoY2hhbG'
'xlbmdlEk4KDGdldGF1dGh0b2tlbhgDIAEoCzIoLmNsaWVudF90b19zZXJ2ZXIuSGFuZHNoYWtl'
'LkdldEF1dGhUb2tlbkgAUgxnZXRhdXRodG9rZW4STgoMYXV0aGVudGljYXRlGAQgASgLMiguY2'
'xpZW50X3RvX3NlcnZlci5IYW5kc2hha2UuQXV0aGVudGljYXRlSABSDGF1dGhlbnRpY2F0ZRq8'
'AgoIUmVnaXN0ZXISGgoIdXNlcm5hbWUYASABKAlSCHVzZXJuYW1lEiQKC2ludml0ZV9jb2RlGA'
'IgASgJSABSCmludml0ZUNvZGWIAQESLgoTcHVibGljX2lkZW50aXR5X2tleRgDIAEoDFIRcHVi'
'bGljSWRlbnRpdHlLZXkSIwoNc2lnbmVkX3ByZWtleRgEIAEoDFIMc2lnbmVkUHJla2V5EjYKF3'
'NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAUgASgMUhVzaWduZWRQcmVrZXlTaWduYXR1cmUSKAoQ'
'c2lnbmVkX3ByZWtleV9pZBgGIAEoA1IOc2lnbmVkUHJla2V5SWQSJwoPcmVnaXN0cmF0aW9uX2'
'lkGAcgASgDUg5yZWdpc3RyYXRpb25JZEIOCgxfaW52aXRlX2NvZGUaEgoQR2V0QXV0aENoYWxs'
'ZW5nZRpDCgxHZXRBdXRoVG9rZW4SFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkEhoKCHJlc3Bvbn'
'NlGAIgASgMUghyZXNwb25zZRpGCgxBdXRoZW50aWNhdGUSFwoHdXNlcl9pZBgBIAEoA1IGdXNl'
'cklkEh0KCmF1dGhfdG9rZW4YAiABKAxSCWF1dGhUb2tlbkILCglIYW5kc2hha2U=');
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData$json = {
@ -174,6 +187,9 @@ const ApplicationData_GetPrekeysByUserId$json = {
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_GetUploadToken$json = {
'1': 'GetUploadToken',
'2': [
{'1': 'recipients_count', '3': 1, '4': 1, '5': 13, '10': 'recipientsCount'},
],
};
@$core.Deprecated('Use applicationDataDescriptor instead')
@ -183,6 +199,10 @@ const ApplicationData_UploadData$json = {
{'1': 'upload_token', '3': 1, '4': 1, '5': 12, '10': 'uploadToken'},
{'1': 'offset', '3': 2, '4': 1, '5': 13, '10': 'offset'},
{'1': 'data', '3': 3, '4': 1, '5': 12, '10': 'data'},
{'1': 'checksum', '3': 4, '4': 1, '5': 12, '9': 0, '10': 'checksum', '17': true},
],
'8': [
{'1': '_checksum'},
],
};
@ -190,7 +210,7 @@ const ApplicationData_UploadData$json = {
const ApplicationData_DownloadData$json = {
'1': 'DownloadData',
'2': [
{'1': 'upload_token', '3': 1, '4': 1, '5': 12, '10': 'uploadToken'},
{'1': 'download_token', '3': 1, '4': 1, '5': 12, '10': 'downloadToken'},
{'1': 'offset', '3': 2, '4': 1, '5': 13, '10': 'offset'},
],
};
@ -215,10 +235,12 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
'JuYW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2VybmFtZRo1ChRVcGRhdGVHb29nbGVGY21Ub2tl'
'bhIdCgpnb29nbGVfZmNtGAEgASgJUglnb29nbGVGY20aJgoLR2V0VXNlckJ5SWQSFwoHdXNlcl'
'9pZBgBIAEoA1IGdXNlcklkGi0KEkdldFByZWtleXNCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgD'
'UgZ1c2VySWQaEAoOR2V0VXBsb2FkVG9rZW4aWwoKVXBsb2FkRGF0YRIhCgx1cGxvYWRfdG9rZW'
'4YASABKAxSC3VwbG9hZFRva2VuEhYKBm9mZnNldBgCIAEoDVIGb2Zmc2V0EhIKBGRhdGEYAyAB'
'KAxSBGRhdGEaSQoMRG93bmxvYWREYXRhEiEKDHVwbG9hZF90b2tlbhgBIAEoDFILdXBsb2FkVG'
'9rZW4SFgoGb2Zmc2V0GAIgASgNUgZvZmZzZXRCEQoPQXBwbGljYXRpb25EYXRh');
'UgZ1c2VySWQaOwoOR2V0VXBsb2FkVG9rZW4SKQoQcmVjaXBpZW50c19jb3VudBgBIAEoDVIPcm'
'VjaXBpZW50c0NvdW50GokBCgpVcGxvYWREYXRhEiEKDHVwbG9hZF90b2tlbhgBIAEoDFILdXBs'
'b2FkVG9rZW4SFgoGb2Zmc2V0GAIgASgNUgZvZmZzZXQSEgoEZGF0YRgDIAEoDFIEZGF0YRIfCg'
'hjaGVja3N1bRgEIAEoDEgAUghjaGVja3N1bYgBAUILCglfY2hlY2tzdW0aTQoMRG93bmxvYWRE'
'YXRhEiUKDmRvd25sb2FkX3Rva2VuGAEgASgMUg1kb3dubG9hZFRva2VuEhYKBm9mZnNldBgCIA'
'EoDVIGb2Zmc2V0QhEKD0FwcGxpY2F0aW9uRGF0YQ==');
@$core.Deprecated('Use responseDescriptor instead')
const Response$json = {

View file

@ -31,6 +31,12 @@ class ErrorCode extends $pb.ProtobufEnum {
static const ErrorCode InvalidUpdateToken = ErrorCode._(1012, _omitEnumNames ? '' : 'InvalidUpdateToken');
static const ErrorCode InvalidOffset = ErrorCode._(1013, _omitEnumNames ? '' : 'InvalidOffset');
static const ErrorCode InvalidGoogleFcmToken = ErrorCode._(1014, _omitEnumNames ? '' : 'InvalidGoogleFcmToken');
static const ErrorCode UploadTokenIsBlocked = ErrorCode._(1015, _omitEnumNames ? '' : 'UploadTokenIsBlocked');
static const ErrorCode UploadChecksumInvalid = ErrorCode._(1016, _omitEnumNames ? '' : 'UploadChecksumInvalid');
static const ErrorCode InvalidDownloadToken = ErrorCode._(1017, _omitEnumNames ? '' : 'InvalidDownloadToken');
static const ErrorCode ApiEndpointNotFound = ErrorCode._(1018, _omitEnumNames ? '' : 'ApiEndpointNotFound');
static const ErrorCode AuthTokenNotValid = ErrorCode._(1019, _omitEnumNames ? '' : 'AuthTokenNotValid');
static const ErrorCode InvalidPreKeys = ErrorCode._(1020, _omitEnumNames ? '' : 'InvalidPreKeys');
static const $core.List<ErrorCode> values = <ErrorCode> [
Unknown,
@ -50,6 +56,12 @@ class ErrorCode extends $pb.ProtobufEnum {
InvalidUpdateToken,
InvalidOffset,
InvalidGoogleFcmToken,
UploadTokenIsBlocked,
UploadChecksumInvalid,
InvalidDownloadToken,
ApiEndpointNotFound,
AuthTokenNotValid,
InvalidPreKeys,
];
static final $core.Map<$core.int, ErrorCode> _byValue = $pb.ProtobufEnum.initByValue(values);

View file

@ -34,6 +34,12 @@ const ErrorCode$json = {
{'1': 'InvalidUpdateToken', '2': 1012},
{'1': 'InvalidOffset', '2': 1013},
{'1': 'InvalidGoogleFcmToken', '2': 1014},
{'1': 'UploadTokenIsBlocked', '2': 1015},
{'1': 'UploadChecksumInvalid', '2': 1016},
{'1': 'InvalidDownloadToken', '2': 1017},
{'1': 'ApiEndpointNotFound', '2': 1018},
{'1': 'AuthTokenNotValid', '2': 1019},
{'1': 'InvalidPreKeys', '2': 1020},
],
};
@ -46,5 +52,8 @@ final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode(
'bGljS2V5EO8HEiAKG1Nlc3Npb25BbHJlYWR5QXV0aGVudGljYXRlZBDwBxIcChdTZXNzaW9uTm'
'90QXV0aGVudGljYXRlZBDxBxIaChVPbmx5T25lU2Vzc2lvbkFsbG93ZWQQ8gcSFwoSVXBsb2Fk'
'TGltaXRSZWFjaGVkEPMHEhcKEkludmFsaWRVcGRhdGVUb2tlbhD0BxISCg1JbnZhbGlkT2Zmc2'
'V0EPUHEhoKFUludmFsaWRHb29nbGVGY21Ub2tlbhD2Bw==');
'V0EPUHEhoKFUludmFsaWRHb29nbGVGY21Ub2tlbhD2BxIZChRVcGxvYWRUb2tlbklzQmxvY2tl'
'ZBD3BxIaChVVcGxvYWRDaGVja3N1bUludmFsaWQQ+AcSGQoUSW52YWxpZERvd25sb2FkVG9rZW'
'4Q+QcSGAoTQXBpRW5kcG9pbnROb3RGb3VuZBD6BxIWChFBdXRoVG9rZW5Ob3RWYWxpZBD7BxIT'
'Cg5JbnZhbGlkUHJlS2V5cxD8Bw==');

View file

@ -86,6 +86,7 @@ enum V0_Kind {
newMessage,
requestNewPreKeys,
downloaddata,
error,
notSet
}
@ -96,6 +97,7 @@ class V0 extends $pb.GeneratedMessage {
NewMessage? newMessage,
$core.bool? requestNewPreKeys,
DownloadData? downloaddata,
$0.ErrorCode? error,
}) {
final $result = create();
if (seq != null) {
@ -113,6 +115,9 @@ class V0 extends $pb.GeneratedMessage {
if (downloaddata != null) {
$result.downloaddata = downloaddata;
}
if (error != null) {
$result.error = error;
}
return $result;
}
V0._() : super();
@ -124,15 +129,17 @@ class V0 extends $pb.GeneratedMessage {
3 : V0_Kind.newMessage,
4 : V0_Kind.requestNewPreKeys,
5 : V0_Kind.downloaddata,
6 : V0_Kind.error,
0 : V0_Kind.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'V0', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..oo(0, [2, 3, 4, 5])
..oo(0, [2, 3, 4, 5, 6])
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'seq', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO)
..aOM<Response>(2, _omitFieldNames ? '' : 'response', subBuilder: Response.create)
..aOM<NewMessage>(3, _omitFieldNames ? '' : 'newMessage', protoName: 'newMessage', subBuilder: NewMessage.create)
..aOB(4, _omitFieldNames ? '' : 'RequestNewPreKeys', protoName: 'RequestNewPreKeys')
..aOM<DownloadData>(5, _omitFieldNames ? '' : 'downloaddata', subBuilder: DownloadData.create)
..e<$0.ErrorCode>(6, _omitFieldNames ? '' : 'error', $pb.PbFieldType.OE, defaultOrMaker: $0.ErrorCode.Unknown, valueOf: $0.ErrorCode.valueOf, enumValues: $0.ErrorCode.values)
..hasRequiredFields = false
;
@ -210,6 +217,15 @@ class V0 extends $pb.GeneratedMessage {
void clearDownloaddata() => clearField(5);
@$pb.TagNumber(5)
DownloadData ensureDownloaddata() => $_ensure(4);
@$pb.TagNumber(6)
$0.ErrorCode get error => $_getN(5);
@$pb.TagNumber(6)
set error($0.ErrorCode v) { setField(6, v); }
@$pb.TagNumber(6)
$core.bool hasError() => $_has(5);
@$pb.TagNumber(6)
void clearError() => clearField(6);
}
class NewMessage extends $pb.GeneratedMessage {
@ -560,12 +576,71 @@ class Response_UserData extends $pb.GeneratedMessage {
void clearUsername() => clearField(7);
}
class Response_UploadToken extends $pb.GeneratedMessage {
factory Response_UploadToken({
$core.List<$core.int>? uploadToken,
$core.Iterable<$core.List<$core.int>>? downloadTokens,
}) {
final $result = create();
if (uploadToken != null) {
$result.uploadToken = uploadToken;
}
if (downloadTokens != null) {
$result.downloadTokens.addAll(downloadTokens);
}
return $result;
}
Response_UploadToken._() : super();
factory Response_UploadToken.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory Response_UploadToken.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Response.UploadToken', package: const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'), createEmptyInstance: create)
..a<$core.List<$core.int>>(1, _omitFieldNames ? '' : 'uploadToken', $pb.PbFieldType.OY)
..p<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'downloadTokens', $pb.PbFieldType.PY)
..hasRequiredFields = false
;
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
Response_UploadToken clone() => Response_UploadToken()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
Response_UploadToken copyWith(void Function(Response_UploadToken) updates) => super.copyWith((message) => updates(message as Response_UploadToken)) as Response_UploadToken;
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_UploadToken create() => Response_UploadToken._();
Response_UploadToken createEmptyInstance() => create();
static $pb.PbList<Response_UploadToken> createRepeated() => $pb.PbList<Response_UploadToken>();
@$core.pragma('dart2js:noInline')
static Response_UploadToken getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Response_UploadToken>(create);
static Response_UploadToken? _defaultInstance;
@$pb.TagNumber(1)
$core.List<$core.int> get uploadToken => $_getN(0);
@$pb.TagNumber(1)
set uploadToken($core.List<$core.int> v) { $_setBytes(0, v); }
@$pb.TagNumber(1)
$core.bool hasUploadToken() => $_has(0);
@$pb.TagNumber(1)
void clearUploadToken() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.List<$core.int>> get downloadTokens => $_getList(1);
}
enum Response_Ok_Ok {
none,
userid,
challenge,
authchallenge,
uploadtoken,
userdata,
authtoken,
notSet
}
@ -573,9 +648,10 @@ class Response_Ok extends $pb.GeneratedMessage {
factory Response_Ok({
$core.bool? none,
$fixnum.Int64? userid,
$core.List<$core.int>? challenge,
$core.List<$core.int>? uploadtoken,
$core.List<$core.int>? authchallenge,
Response_UploadToken? uploadtoken,
Response_UserData? userdata,
$core.List<$core.int>? authtoken,
}) {
final $result = create();
if (none != null) {
@ -584,8 +660,8 @@ class Response_Ok extends $pb.GeneratedMessage {
if (userid != null) {
$result.userid = userid;
}
if (challenge != null) {
$result.challenge = challenge;
if (authchallenge != null) {
$result.authchallenge = authchallenge;
}
if (uploadtoken != null) {
$result.uploadtoken = uploadtoken;
@ -593,6 +669,9 @@ class Response_Ok extends $pb.GeneratedMessage {
if (userdata != null) {
$result.userdata = userdata;
}
if (authtoken != null) {
$result.authtoken = authtoken;
}
return $result;
}
Response_Ok._() : super();
@ -602,18 +681,20 @@ class Response_Ok extends $pb.GeneratedMessage {
static const $core.Map<$core.int, Response_Ok_Ok> _Response_Ok_OkByTag = {
1 : Response_Ok_Ok.none,
2 : Response_Ok_Ok.userid,
3 : Response_Ok_Ok.challenge,
3 : Response_Ok_Ok.authchallenge,
4 : Response_Ok_Ok.uploadtoken,
5 : Response_Ok_Ok.userdata,
6 : Response_Ok_Ok.authtoken,
0 : Response_Ok_Ok.notSet
};
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])
..oo(0, [1, 2, 3, 4, 5, 6])
..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None')
..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)
..a<$core.List<$core.int>>(3, _omitFieldNames ? '' : 'authchallenge', $pb.PbFieldType.OY)
..aOM<Response_UploadToken>(4, _omitFieldNames ? '' : 'uploadtoken', subBuilder: Response_UploadToken.create)
..aOM<Response_UserData>(5, _omitFieldNames ? '' : 'userdata', subBuilder: Response_UserData.create)
..a<$core.List<$core.int>>(6, _omitFieldNames ? '' : 'authtoken', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
@ -660,22 +741,24 @@ class Response_Ok extends $pb.GeneratedMessage {
void clearUserid() => clearField(2);
@$pb.TagNumber(3)
$core.List<$core.int> get challenge => $_getN(2);
$core.List<$core.int> get authchallenge => $_getN(2);
@$pb.TagNumber(3)
set challenge($core.List<$core.int> v) { $_setBytes(2, v); }
set authchallenge($core.List<$core.int> v) { $_setBytes(2, v); }
@$pb.TagNumber(3)
$core.bool hasChallenge() => $_has(2);
$core.bool hasAuthchallenge() => $_has(2);
@$pb.TagNumber(3)
void clearChallenge() => clearField(3);
void clearAuthchallenge() => clearField(3);
@$pb.TagNumber(4)
$core.List<$core.int> get uploadtoken => $_getN(3);
Response_UploadToken get uploadtoken => $_getN(3);
@$pb.TagNumber(4)
set uploadtoken($core.List<$core.int> v) { $_setBytes(3, v); }
set uploadtoken(Response_UploadToken v) { setField(4, v); }
@$pb.TagNumber(4)
$core.bool hasUploadtoken() => $_has(3);
@$pb.TagNumber(4)
void clearUploadtoken() => clearField(4);
@$pb.TagNumber(4)
Response_UploadToken ensureUploadtoken() => $_ensure(3);
@$pb.TagNumber(5)
Response_UserData get userdata => $_getN(4);
@ -687,6 +770,15 @@ class Response_Ok extends $pb.GeneratedMessage {
void clearUserdata() => clearField(5);
@$pb.TagNumber(5)
Response_UserData ensureUserdata() => $_ensure(4);
@$pb.TagNumber(6)
$core.List<$core.int> get authtoken => $_getN(5);
@$pb.TagNumber(6)
set authtoken($core.List<$core.int> v) { $_setBytes(5, v); }
@$pb.TagNumber(6)
$core.bool hasAuthtoken() => $_has(5);
@$pb.TagNumber(6)
void clearAuthtoken() => clearField(6);
}
enum Response_Response {

View file

@ -38,6 +38,7 @@ const V0$json = {
{'1': 'newMessage', '3': 3, '4': 1, '5': 11, '6': '.server_to_client.NewMessage', '9': 0, '10': 'newMessage'},
{'1': 'RequestNewPreKeys', '3': 4, '4': 1, '5': 8, '9': 0, '10': 'RequestNewPreKeys'},
{'1': 'downloaddata', '3': 5, '4': 1, '5': 11, '6': '.server_to_client.DownloadData', '9': 0, '10': 'downloaddata'},
{'1': 'error', '3': 6, '4': 1, '5': 14, '6': '.error.ErrorCode', '9': 0, '10': 'error'},
],
'8': [
{'1': 'Kind'},
@ -50,7 +51,8 @@ final $typed_data.Uint8List v0Descriptor = $convert.base64Decode(
'llbnQuUmVzcG9uc2VIAFIIcmVzcG9uc2USPgoKbmV3TWVzc2FnZRgDIAEoCzIcLnNlcnZlcl90'
'b19jbGllbnQuTmV3TWVzc2FnZUgAUgpuZXdNZXNzYWdlEi4KEVJlcXVlc3ROZXdQcmVLZXlzGA'
'QgASgISABSEVJlcXVlc3ROZXdQcmVLZXlzEkQKDGRvd25sb2FkZGF0YRgFIAEoCzIeLnNlcnZl'
'cl90b19jbGllbnQuRG93bmxvYWREYXRhSABSDGRvd25sb2FkZGF0YUIGCgRLaW5k');
'cl90b19jbGllbnQuRG93bmxvYWREYXRhSABSDGRvd25sb2FkZGF0YRIoCgVlcnJvchgGIAEoDj'
'IQLmVycm9yLkVycm9yQ29kZUgAUgVlcnJvckIGCgRLaW5k');
@$core.Deprecated('Use newMessageDescriptor instead')
const NewMessage$json = {
@ -89,7 +91,7 @@ const Response$json = {
{'1': 'ok', '3': 1, '4': 1, '5': 11, '6': '.server_to_client.Response.Ok', '9': 0, '10': 'ok'},
{'1': 'error', '3': 2, '4': 1, '5': 14, '6': '.error.ErrorCode', '9': 0, '10': 'error'},
],
'3': [Response_PreKey$json, Response_UserData$json, Response_Ok$json],
'3': [Response_PreKey$json, Response_UserData$json, Response_UploadToken$json, Response_Ok$json],
'8': [
{'1': 'Response'},
],
@ -125,14 +127,24 @@ const Response_UserData$json = {
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_UploadToken$json = {
'1': 'UploadToken',
'2': [
{'1': 'upload_token', '3': 1, '4': 1, '5': 12, '10': 'uploadToken'},
{'1': 'download_tokens', '3': 2, '4': 3, '5': 12, '10': 'downloadTokens'},
],
};
@$core.Deprecated('Use responseDescriptor instead')
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': 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': 'authchallenge', '3': 3, '4': 1, '5': 12, '9': 0, '10': 'authchallenge'},
{'1': 'authtoken', '3': 6, '4': 1, '5': 12, '9': 0, '10': 'authtoken'},
{'1': 'uploadtoken', '3': 4, '4': 1, '5': 11, '6': '.server_to_client.Response.UploadToken', '9': 0, '10': 'uploadtoken'},
{'1': 'userdata', '3': 5, '4': 1, '5': 11, '6': '.server_to_client.Response.UserData', '9': 0, '10': 'userdata'},
],
'8': [
@ -152,9 +164,12 @@ final $typed_data.Uint8List responseDescriptor = $convert.base64Decode(
'9wcmVrZXlfc2lnbmF0dXJlGAUgASgMSANSFXNpZ25lZFByZWtleVNpZ25hdHVyZYgBARItChBz'
'aWduZWRfcHJla2V5X2lkGAYgASgDSARSDnNpZ25lZFByZWtleUlkiAEBQgsKCV91c2VybmFtZU'
'IWChRfcHVibGljX2lkZW50aXR5X2tleUIQCg5fc2lnbmVkX3ByZWtleUIaChhfc2lnbmVkX3By'
'ZWtleV9zaWduYXR1cmVCEwoRX3NpZ25lZF9wcmVrZXlfaWQawQEKAk9rEhQKBE5vbmUYASABKA'
'hIAFIETm9uZRIYCgZ1c2VyaWQYAiABKANIAFIGdXNlcmlkEh4KCWNoYWxsZW5nZRgDIAEoDEgA'
'UgljaGFsbGVuZ2USIgoLdXBsb2FkdG9rZW4YBCABKAxIAFILdXBsb2FkdG9rZW4SQQoIdXNlcm'
'RhdGEYBSABKAsyIy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlVzZXJEYXRhSABSCHVzZXJk'
'YXRhQgQKAk9rQgoKCFJlc3BvbnNl');
'ZWtleV9zaWduYXR1cmVCEwoRX3NpZ25lZF9wcmVrZXlfaWQaWQoLVXBsb2FkVG9rZW4SIQoMdX'
'Bsb2FkX3Rva2VuGAEgASgMUgt1cGxvYWRUb2tlbhInCg9kb3dubG9hZF90b2tlbnMYAiADKAxS'
'DmRvd25sb2FkVG9rZW5zGpECCgJPaxIUCgROb25lGAEgASgISABSBE5vbmUSGAoGdXNlcmlkGA'
'IgASgDSABSBnVzZXJpZBImCg1hdXRoY2hhbGxlbmdlGAMgASgMSABSDWF1dGhjaGFsbGVuZ2US'
'HgoJYXV0aHRva2VuGAYgASgMSABSCWF1dGh0b2tlbhJKCgt1cGxvYWR0b2tlbhgEIAEoCzImLn'
'NlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuVXBsb2FkVG9rZW5IAFILdXBsb2FkdG9rZW4SQQoI'
'dXNlcmRhdGEYBSABKAsyIy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlVzZXJEYXRhSABSCH'
'VzZXJkYXRhQgQKAk9rQgoKCFJlc3BvbnNl');

View file

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:math';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/foundation.dart';
@ -62,6 +63,7 @@ class ApiProvider {
// Function is called after the user is authenticated at the server
Future onAuthenticated() async {
isAuthenticated = true;
initFCMAfterAuthenticated();
}
@ -118,7 +120,6 @@ class ApiProvider {
globalCallbackConnectionState(false);
_channel = null;
isAuthenticated = false;
// tryToReconnect();
}
void _onError(dynamic e) {
@ -126,29 +127,6 @@ class ApiProvider {
globalCallbackConnectionState(false);
_channel = null;
isAuthenticated = false;
tryToReconnect();
}
void tryToReconnect() {
return;
// if (globalIsAppInBackground) return;
// if (reconnectionTimer != null) {
// reconnectionTimer!.cancel();
// }
// final int randomDelay = Random().nextInt(20);
// final int delay = _reconnectionDelay + randomDelay;
// debugPrint("Delay reconnection $delay");
// reconnectionTimer = Timer(Duration(seconds: delay), () async {
// // increase delay but set a maximum of 60 seconds (including the random delay)
// _reconnectionDelay = _reconnectionDelay * 2;
// if (_reconnectionDelay > 40) {
// _reconnectionDelay = 40;
// }
// await connect();
// });
}
void _onData(dynamic msgBuffer) {
@ -189,7 +167,7 @@ class ApiProvider {
}
}
Future<Result> _sendRequestV0(ClientToServer request,
Future<Result> sendRequestSync(ClientToServer request,
{bool authenticated = true}) async {
if (_channel == null) {
log.shout("sending request, but api is not connected.");
@ -218,7 +196,7 @@ class ApiProvider {
await authenticate();
if (isAuthenticated) {
// this will send the request one more time.
return _sendRequestV0(request, authenticated: false);
return sendRequestSync(request, authenticated: false);
} else {
log.shout("Session is not authenticated.");
return Result.error(ErrorCode.InternalError);
@ -229,48 +207,86 @@ class ApiProvider {
return res;
}
Future<bool> tryAuthenticateWithToken(int userId) async {
final storage = getSecureStorage();
String? apiAuthToken = await storage.read(key: "api_auth_token");
if (apiAuthToken != null) {
final authenticate = Handshake_Authenticate()
..userId = Int64(userId)
..authToken = base64Decode(apiAuthToken);
final handshake = Handshake()..authenticate = authenticate;
final req = createClientToServerFromHandshake(handshake);
final result = await sendRequestSync(req, authenticated: false);
if (result.isSuccess) {
log.info("Authenticated using api_auth_token");
onAuthenticated();
return true;
}
if (result.isError) {
if (result.error != ErrorCode.AuthTokenNotValid) {
log.shout("Error while authenticating using token", result);
return false;
}
}
}
return false;
}
Future authenticate() async {
if (isAuthenticated) return;
if (await SignalHelper.getSignalIdentity() == null) {
return;
}
var handshake = Handshake()..getchallenge = Handshake_GetChallenge();
var req = createClientToServerFromHandshake(handshake);
final userData = await getUser();
if (userData == null) return;
final result = await _sendRequestV0(req, authenticated: false);
if (result.isError) {
log.shout("Error auth", result);
if (await tryAuthenticateWithToken(userData.userId)) {
return;
}
final challenge = result.value.challenge;
var handshake = Handshake()
..getauthchallenge = Handshake_GetAuthChallenge();
var req = createClientToServerFromHandshake(handshake);
final result = await sendRequestSync(req, authenticated: false);
if (result.isError) {
log.shout("Error requesting auth challenge", result);
return;
}
final challenge = result.value.authchallenge;
final privKey = await SignalHelper.getPrivateKey();
if (privKey == null) return;
final random = getRandomUint8List(32);
final signature = sign(privKey.serialize(), challenge, random);
final userData = await getUser();
if (userData == null) return;
var open = Handshake_OpenSession()
final getAuthToken = Handshake_GetAuthToken()
..response = signature
..userId = Int64(userData.userId);
var opensession = Handshake()..opensession = open;
final getauthtoken = Handshake()..getauthtoken = getAuthToken;
var req2 = createClientToServerFromHandshake(opensession);
var req2 = createClientToServerFromHandshake(getauthtoken);
final result2 = await _sendRequestV0(req2, authenticated: false);
final result2 = await sendRequestSync(req2, authenticated: false);
if (result2.isError) {
log.shout("send request failed: ${result2.error}");
log.shout("Error while sending auth challenge: ${result2.error}");
return;
}
log.info("Authenticated!");
onAuthenticated();
isAuthenticated = true;
Uint8List apiAuthToken = result2.value.authtoken;
String apiAuthTokenB64 = base64Encode(apiAuthToken);
final storage = getSecureStorage();
await storage.write(key: "api_auth_token", value: apiAuthTokenB64);
await tryAuthenticateWithToken(userData.userId);
}
Future<Result> register(String username, String? inviteCode) async {
@ -301,30 +317,30 @@ class ApiProvider {
var handshake = Handshake()..register = register;
var req = createClientToServerFromHandshake(handshake);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> getUsername(int userId) async {
var get = ApplicationData_GetUserById()..userId = Int64(userId);
var appData = ApplicationData()..getuserbyid = get;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> getUploadToken() async {
var get = ApplicationData_GetUploadToken();
var appData = ApplicationData()..getuploadtoken = get;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> triggerDownload(List<int> token, int offset) async {
var get = ApplicationData_DownloadData()
..uploadToken = token
..downloadToken = token
..offset = offset;
var appData = ApplicationData()..downloaddata = get;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> uploadData(
@ -335,7 +351,7 @@ class ApiProvider {
..offset = offset;
var appData = ApplicationData()..uploaddata = get;
var req = createClientToServerFromApplicationData(appData);
final result = await _sendRequestV0(req);
final result = await sendRequestSync(req);
return result;
}
@ -343,14 +359,14 @@ class ApiProvider {
var get = ApplicationData_GetUserByUsername()..username = username;
var appData = ApplicationData()..getuserbyusername = get;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> updateFCMToken(String googleFcm) async {
var get = ApplicationData_UpdateGoogleFcmToken()..googleFcm = googleFcm;
var appData = ApplicationData()..updategooglefcmtoken = get;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
Future<Result> sendTextMessage(int target, Uint8List msg) async {
@ -361,6 +377,6 @@ class ApiProvider {
var appData = ApplicationData()..textmessage = testMessage;
var req = createClientToServerFromApplicationData(appData);
return await _sendRequestV0(req);
return await sendRequestSync(req);
}
}

View file

@ -18,23 +18,27 @@ Future initFCMAfterAuthenticated() async {
String? storedToken = await storage.read(key: "google_fcm");
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken == null) {
Logger("init_fcm_service").shout("Error getting fcmToken");
return;
}
try {
final fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken == null) {
Logger("init_fcm_service").shout("Error getting fcmToken");
return;
}
if (storedToken == null || fcmToken != storedToken) {
await apiProvider.updateFCMToken(fcmToken);
await storage.write(key: "google_fcm", value: fcmToken);
}
if (storedToken == null || fcmToken != storedToken) {
await apiProvider.updateFCMToken(fcmToken);
await storage.write(key: "google_fcm", value: fcmToken);
}
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) async {
await apiProvider.updateFCMToken(fcmToken);
await storage.write(key: "google_fcm", value: fcmToken);
}).onError((err) {
// Logger("init_fcm_service").shout("Error getting fcmToken");
});
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) async {
await apiProvider.updateFCMToken(fcmToken);
await storage.write(key: "google_fcm", value: fcmToken);
}).onError((err) {
// Logger("init_fcm_service").shout("Error getting fcmToken");
});
} catch (e) {
Logger("fcm_service").shout("Error loading fcmToken: $e");
}
}
Future initFCMService() async {

View file

@ -1,6 +1,5 @@
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
@ -44,8 +43,20 @@ Future<void> writeLogToFile(LogRecord record) async {
await logFile.writeAsString(logMessage, mode: FileMode.append);
}
Future<bool> deleteLogFile() async {
final directory = await getApplicationDocumentsDirectory();
final logFile = File('${directory.path}/app.log');
if (await logFile.exists()) {
await logFile.delete();
return true;
}
return false;
}
// Just a helper function to get the secure storage
FlutterSecureStorage getSecureStorage() {
// ignore: no_leading_underscores_for_local_identifiers
AndroidOptions _getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
);

View file

@ -1,7 +1,6 @@
import 'dart:convert';
import 'dart:io';
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/json/message.dart';

View file

@ -12,6 +12,7 @@ import 'package:twonly/src/model/json/message.dart';
import 'package:twonly/src/providers/api/api.dart';
// ignore: library_prefixes
import 'package:twonly/src/utils/signal.dart' as SignalHelper;
import 'package:twonly/src/utils/storage.dart';
class SearchUsernameView extends StatefulWidget {
const SearchUsernameView({super.key});
@ -23,8 +24,14 @@ class SearchUsernameView extends StatefulWidget {
class _SearchUsernameView extends State<SearchUsernameView> {
final TextEditingController searchUserName = TextEditingController();
bool _isLoading = false;
bool hasRequestedUsers = false;
Future _addNewUser(BuildContext context) async {
final user = await getUser();
if (user == null || user.username == searchUserName.text) {
return;
}
setState(() {
_isLoading = true;
});
@ -44,14 +51,14 @@ class _SearchUsernameView extends State<SearchUsernameView> {
int added = await twonlyDatabase.insertContact(ContactsCompanion(
username: Value(searchUserName.text),
userId: Value(res.value.userdata.userId),
userId: Value(res.value.userdata.userId.toInt()),
requested: Value(false),
));
if (added > 0) {
if (await SignalHelper.addNewContact(res.value.userdata)) {
encryptAndSendMessage(
res.value.userdata.userId,
res.value.userdata.userId.toInt(),
MessageJson(
kind: MessageKind.contactRequest,
timestamp: DateTime.now(),
@ -120,23 +127,21 @@ class _SearchUsernameView extends State<SearchUsernameView> {
label: Text(context.lang.searchUsernameQrCodeBtn),
),
SizedBox(height: 30),
if (hasRequestedUsers)
HeadLineComponent(
context.lang.searchUsernameNewFollowerTitle,
),
StreamBuilder(
stream: contacts,
builder: (context, snapshot) {
if (!snapshot.hasData || snapshot.data != null) {
if (!snapshot.hasData ||
snapshot.data == null ||
snapshot.data!.isEmpty) {
hasRequestedUsers = false;
return Container();
}
final contacts = snapshot.data!;
if (contacts.isEmpty) {
return Container();
}
return Row(children: [
HeadLineComponent(
context.lang.searchUsernameNewFollowerTitle),
Expanded(
child: ContactsListView(contacts),
)
]);
hasRequestedUsers = true;
return Expanded(child: ContactsListView(snapshot.data!));
},
)
],

View file

@ -39,7 +39,10 @@ class _RegisterViewState extends State<RegisterView> {
if (res.isSuccess) {
Logger("create_new_user").info("Got user_id ${res.value} from server");
final userData = UserData(
userId: res.value.userid, username: username, displayName: username);
userId: res.value.userid.toInt(),
username: username,
displayName: username,
);
storage.write(key: "user_data", value: jsonEncode(userData));
}

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'package:twonly/src/utils/misc.dart';
class DiagnosticsView extends StatelessWidget {
const DiagnosticsView({super.key});
@ -45,17 +46,14 @@ class DiagnosticsView extends StatelessWidget {
),
TextButton(
onPressed: () async {
final directory =
await getApplicationDocumentsDirectory();
final logFile = File('${directory.path}/app.log');
if (await logFile.exists()) {
await logFile.delete();
if (await deleteLogFile()) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Log file deleted!')),
);
} else {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Log file does not exist.')),