mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 12:48:41 +00:00
accept user request
This commit is contained in:
parent
0da87f1712
commit
cd27294fde
9 changed files with 88 additions and 45 deletions
|
|
@ -96,6 +96,19 @@ class DbContacts extends CvModelBase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future acceptUser(int userId) async {
|
||||||
|
Map<String, dynamic> valuesToUpdate = {
|
||||||
|
columnAccepted: 1,
|
||||||
|
columnRequested: 0,
|
||||||
|
};
|
||||||
|
await dbProvider.db!.update(
|
||||||
|
tableName,
|
||||||
|
valuesToUpdate,
|
||||||
|
where: "$columnUserId = ?",
|
||||||
|
whereArgs: [userId],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static Future deleteUser(int userId) async {
|
static Future deleteUser(int userId) async {
|
||||||
await dbProvider.db!.delete(
|
await dbProvider.db!.delete(
|
||||||
tableName,
|
tableName,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,14 @@ import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:twonly/src/utils/json.dart';
|
import 'package:twonly/src/utils/json.dart';
|
||||||
part 'message.g.dart';
|
part 'message.g.dart';
|
||||||
|
|
||||||
enum MessageKind { textMessage, image, video, contactRequest, rejectRequest }
|
enum MessageKind {
|
||||||
|
textMessage,
|
||||||
|
image,
|
||||||
|
video,
|
||||||
|
contactRequest,
|
||||||
|
rejectRequest,
|
||||||
|
acceptRequest
|
||||||
|
}
|
||||||
|
|
||||||
// so _$MessageKindEnumMap gets generated
|
// so _$MessageKindEnumMap gets generated
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const _$MessageKindEnumMap = {
|
||||||
MessageKind.video: 'video',
|
MessageKind.video: 'video',
|
||||||
MessageKind.contactRequest: 'contactRequest',
|
MessageKind.contactRequest: 'contactRequest',
|
||||||
MessageKind.rejectRequest: 'rejectRequest',
|
MessageKind.rejectRequest: 'rejectRequest',
|
||||||
|
MessageKind.acceptRequest: 'acceptRequest',
|
||||||
};
|
};
|
||||||
|
|
||||||
Message _$MessageFromJson(Map<String, dynamic> json) => Message(
|
Message _$MessageFromJson(Map<String, dynamic> json) => Message(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:fixnum/fixnum.dart';
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:twonly/src/model/contacts_model.dart';
|
import 'package:twonly/src/model/contacts_model.dart';
|
||||||
|
|
@ -12,7 +11,6 @@ import 'package:twonly/src/proto/api/client_to_server.pb.dart' as client;
|
||||||
import 'package:twonly/src/proto/api/client_to_server.pbserver.dart';
|
import 'package:twonly/src/proto/api/client_to_server.pbserver.dart';
|
||||||
import 'package:twonly/src/proto/api/error.pb.dart';
|
import 'package:twonly/src/proto/api/error.pb.dart';
|
||||||
import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
|
import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
// ignore: library_prefixes
|
// ignore: library_prefixes
|
||||||
|
|
@ -176,6 +174,10 @@ class ApiProvider {
|
||||||
DbContacts.deleteUser(fromUserId.toInt());
|
DbContacts.deleteUser(fromUserId.toInt());
|
||||||
updateNotifier();
|
updateNotifier();
|
||||||
break;
|
break;
|
||||||
|
case MessageKind.acceptRequest:
|
||||||
|
DbContacts.acceptUser(fromUserId.toInt());
|
||||||
|
updateNotifier();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log.shout("Got unknown MessageKind $message");
|
log.shout("Got unknown MessageKind $message");
|
||||||
}
|
}
|
||||||
|
|
@ -253,39 +255,6 @@ class ApiProvider {
|
||||||
return ClientToServer()..v0 = v0;
|
return ClientToServer()..v0 = v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getLocalizedString(BuildContext context, ErrorCode code) {
|
|
||||||
switch (code.toString()) {
|
|
||||||
case "Unknown":
|
|
||||||
return AppLocalizations.of(context)!.errorUnknown;
|
|
||||||
case "BadRequest":
|
|
||||||
return AppLocalizations.of(context)!.errorBadRequest;
|
|
||||||
case "TooManyRequests":
|
|
||||||
return AppLocalizations.of(context)!.errorTooManyRequests;
|
|
||||||
case "InternalError":
|
|
||||||
return AppLocalizations.of(context)!.errorInternalError;
|
|
||||||
case "InvalidInvitationCode":
|
|
||||||
return AppLocalizations.of(context)!.errorInvalidInvitationCode;
|
|
||||||
case "UsernameAlreadyTaken":
|
|
||||||
return AppLocalizations.of(context)!.errorUsernameAlreadyTaken;
|
|
||||||
case "SignatureNotValid":
|
|
||||||
return AppLocalizations.of(context)!.errorSignatureNotValid;
|
|
||||||
case "UsernameNotFound":
|
|
||||||
return AppLocalizations.of(context)!.errorUsernameNotFound;
|
|
||||||
case "UsernameNotValid":
|
|
||||||
return AppLocalizations.of(context)!.errorUsernameNotValid;
|
|
||||||
case "InvalidPublicKey":
|
|
||||||
return AppLocalizations.of(context)!.errorInvalidPublicKey;
|
|
||||||
case "SessionAlreadyAuthenticated":
|
|
||||||
return AppLocalizations.of(context)!.errorSessionAlreadyAuthenticated;
|
|
||||||
case "SessionNotAuthenticated":
|
|
||||||
return AppLocalizations.of(context)!.errorSessionNotAuthenticated;
|
|
||||||
case "OnlyOneSessionAllowed":
|
|
||||||
return AppLocalizations.of(context)!.errorOnlyOneSessionAllowed;
|
|
||||||
default:
|
|
||||||
return code.toString(); // Fallback for unrecognized keys
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result _asResult(server.ServerToClient msg) {
|
Result _asResult(server.ServerToClient msg) {
|
||||||
if (msg.v0.response.hasOk()) {
|
if (msg.v0.response.hasOk()) {
|
||||||
return Result.success(msg.v0.response.ok);
|
return Result.success(msg.v0.response.ok);
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,12 @@ Future<Result> rejectUserRequest(Int64 userId) async {
|
||||||
return encryptAndSendMessage(userId, msg);
|
return encryptAndSendMessage(userId, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Result> acceptUserRequest(Int64 userId) async {
|
||||||
|
Message msg =
|
||||||
|
Message(kind: MessageKind.acceptRequest, timestamp: DateTime.now());
|
||||||
|
return encryptAndSendMessage(userId, msg);
|
||||||
|
}
|
||||||
|
|
||||||
Future<Result> createNewUser(String username, String inviteCode) async {
|
Future<Result> createNewUser(String username, String inviteCode) async {
|
||||||
final storage = getSecureStorage();
|
final storage = getSecureStorage();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:gal/gal.dart';
|
import 'package:gal/gal.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
|
import 'package:twonly/src/proto/api/error.pb.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
Future<void> writeLogToFile(LogRecord record) async {
|
Future<void> writeLogToFile(LogRecord record) async {
|
||||||
final directory = await getApplicationDocumentsDirectory();
|
final directory = await getApplicationDocumentsDirectory();
|
||||||
|
|
@ -49,3 +52,36 @@ Uint8List getRandomUint8List(int length) {
|
||||||
|
|
||||||
return randomBytes;
|
return randomBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String errorCodeToText(BuildContext context, ErrorCode code) {
|
||||||
|
switch (code.toString()) {
|
||||||
|
case "Unknown":
|
||||||
|
return AppLocalizations.of(context)!.errorUnknown;
|
||||||
|
case "BadRequest":
|
||||||
|
return AppLocalizations.of(context)!.errorBadRequest;
|
||||||
|
case "TooManyRequests":
|
||||||
|
return AppLocalizations.of(context)!.errorTooManyRequests;
|
||||||
|
case "InternalError":
|
||||||
|
return AppLocalizations.of(context)!.errorInternalError;
|
||||||
|
case "InvalidInvitationCode":
|
||||||
|
return AppLocalizations.of(context)!.errorInvalidInvitationCode;
|
||||||
|
case "UsernameAlreadyTaken":
|
||||||
|
return AppLocalizations.of(context)!.errorUsernameAlreadyTaken;
|
||||||
|
case "SignatureNotValid":
|
||||||
|
return AppLocalizations.of(context)!.errorSignatureNotValid;
|
||||||
|
case "UsernameNotFound":
|
||||||
|
return AppLocalizations.of(context)!.errorUsernameNotFound;
|
||||||
|
case "UsernameNotValid":
|
||||||
|
return AppLocalizations.of(context)!.errorUsernameNotValid;
|
||||||
|
case "InvalidPublicKey":
|
||||||
|
return AppLocalizations.of(context)!.errorInvalidPublicKey;
|
||||||
|
case "SessionAlreadyAuthenticated":
|
||||||
|
return AppLocalizations.of(context)!.errorSessionAlreadyAuthenticated;
|
||||||
|
case "SessionNotAuthenticated":
|
||||||
|
return AppLocalizations.of(context)!.errorSessionNotAuthenticated;
|
||||||
|
case "OnlyOneSessionAllowed":
|
||||||
|
return AppLocalizations.of(context)!.errorOnlyOneSessionAllowed;
|
||||||
|
default:
|
||||||
|
return code.toString(); // Fallback for unrecognized keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ class _NewMessageView extends State<NewMessageView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadUsers() async {
|
Future<void> _loadUsers() async {
|
||||||
final users = await DbContacts.getUsers();
|
final users =
|
||||||
|
(await DbContacts.getUsers()).where((c) => c.accepted).toList();
|
||||||
setState(() {
|
setState(() {
|
||||||
_knownUsers = users;
|
_knownUsers = users;
|
||||||
_filteredUsers = List.from(_knownUsers);
|
_filteredUsers = List.from(_knownUsers);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:twonly/src/utils/api.dart';
|
import 'package:twonly/src/utils/api.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
class RegisterView extends StatefulWidget {
|
class RegisterView extends StatefulWidget {
|
||||||
const RegisterView({super.key, required this.callbackOnSuccess});
|
const RegisterView({super.key, required this.callbackOnSuccess});
|
||||||
|
|
@ -131,8 +132,7 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
final errMsg =
|
final errMsg = errorCodeToText(context, res.error);
|
||||||
ApiProvider.getLocalizedString(context, res.error);
|
|
||||||
showAlertDialog(context, "Oh no!", errMsg);
|
showAlertDialog(context, "Oh no!", errMsg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/model/contacts_model.dart';
|
import 'package:twonly/src/model/contacts_model.dart';
|
||||||
|
|
@ -93,7 +92,11 @@ class _SearchUsernameView extends State<SearchUsernameView> {
|
||||||
Text(AppLocalizations.of(context)!.searchUsernameQrCodeBtn),
|
Text(AppLocalizations.of(context)!.searchUsernameQrCodeBtn),
|
||||||
),
|
),
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30),
|
||||||
if (context.read<NotifyProvider>().allContacts.isNotEmpty)
|
if (context
|
||||||
|
.read<NotifyProvider>()
|
||||||
|
.allContacts
|
||||||
|
.where((contact) => !contact.accepted)
|
||||||
|
.isNotEmpty)
|
||||||
Container(
|
Container(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 4.0, vertical: 10),
|
padding: EdgeInsets.symmetric(horizontal: 4.0, vertical: 10),
|
||||||
|
|
@ -131,7 +134,11 @@ class ContactsListView extends StatefulWidget {
|
||||||
class _ContactsListViewState extends State<ContactsListView> {
|
class _ContactsListViewState extends State<ContactsListView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<Contact> contacts = context.read<NotifyProvider>().allContacts;
|
List<Contact> contacts = context
|
||||||
|
.read<NotifyProvider>()
|
||||||
|
.allContacts
|
||||||
|
.where((contact) => !contact.accepted)
|
||||||
|
.toList();
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: contacts.length,
|
itemCount: contacts.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
|
@ -172,9 +179,12 @@ class _ContactsListViewState extends State<ContactsListView> {
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.check, color: Colors.green),
|
icon: Icon(Icons.check, color: Colors.green),
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
// Handle accept action
|
await DbContacts.acceptUser(contact.userId.toInt());
|
||||||
print('Accepted ${contact.displayName}');
|
if (context.mounted) {
|
||||||
|
context.read<NotifyProvider>().update();
|
||||||
|
}
|
||||||
|
acceptUserRequest(contact.userId);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue