318 lines
9.2 KiB
Dart
318 lines
9.2 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'package:appwrite/appwrite.dart';
|
|
import 'package:appwrite/models.dart' as model;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:messaging_app/components/constants.dart';
|
|
import 'package:messaging_app/models/chats.dart';
|
|
import 'package:messaging_app/models/conversations.dart';
|
|
import 'package:messaging_app/models/users.dart';
|
|
import 'package:messaging_app/service/navigation_service.dart';
|
|
import 'package:messaging_app/service/snackbar_service.dart';
|
|
|
|
enum AuthStatus {
|
|
notAuthenticated,
|
|
authenticated,
|
|
authenticating,
|
|
userNotFound,
|
|
error,
|
|
}
|
|
|
|
class MessagingProviders extends ChangeNotifier {
|
|
//
|
|
Client client = Client();
|
|
late final Account account;
|
|
late final Databases database;
|
|
late final Storage storage;
|
|
late model.User? user;
|
|
|
|
// Auth Status
|
|
AuthStatus? status;
|
|
|
|
static MessagingProviders instance = MessagingProviders();
|
|
|
|
MessagingProviders() {
|
|
_init();
|
|
_loadUser();
|
|
}
|
|
|
|
_init() {
|
|
client
|
|
.setEndpoint(Constants.instance.endPoint)
|
|
.setProject(Constants.instance.projectId)
|
|
.setSelfSigned();
|
|
account = Account(client);
|
|
database = Databases(client);
|
|
storage = Storage(client);
|
|
}
|
|
|
|
_loadUser() async {
|
|
try {
|
|
user = await account.get();
|
|
if (user != null) {
|
|
status = AuthStatus.authenticated;
|
|
await updateLastSeen();
|
|
NavigationService.instance.navigateToReplacement("home");
|
|
}
|
|
} catch (e) {
|
|
status = AuthStatus.notAuthenticated;
|
|
}
|
|
}
|
|
|
|
void login(String _email, String _password) async {
|
|
//
|
|
try {
|
|
status != AuthStatus.error;
|
|
|
|
try {
|
|
status = AuthStatus.authenticating;
|
|
await account.createEmailPasswordSession(
|
|
email: _email, password: _password);
|
|
|
|
user = await account.get();
|
|
status = AuthStatus.authenticated;
|
|
|
|
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
|
await updateLastSeen();
|
|
NavigationService.instance.navigateToReplacement("home");
|
|
} on AppwriteException catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.message!);
|
|
status = AuthStatus.error;
|
|
user = null;
|
|
//
|
|
} on Exception catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
//
|
|
}
|
|
} on Exception catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
}
|
|
}
|
|
|
|
void logout() async {
|
|
try {
|
|
await updateLastSeen();
|
|
await account.deleteSession(sessionId: 'current');
|
|
// user = null;
|
|
status = AuthStatus.notAuthenticated;
|
|
// await onSuccess();
|
|
SnackBarService.instance.showSnackBarError("logged out successfully");
|
|
await NavigationService.instance.navigateToReplacement("login");
|
|
} on AppwriteException catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.message!);
|
|
} on Exception catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
}
|
|
}
|
|
|
|
Future<void> createUser(String _email, String _password, String _name,
|
|
Future<void> Function(String _uid) onSuccess) async {
|
|
try {
|
|
user = await account.create(
|
|
userId: ID.unique(), email: _email, password: _password, name: _name);
|
|
|
|
status = AuthStatus.authenticated;
|
|
await onSuccess(user!.$id);
|
|
SnackBarService.instance.showSnackBarSuccess("welcome! ${user!.name}");
|
|
// await updateLastSeen();
|
|
NavigationService.instance.goBack();
|
|
NavigationService.instance.navigateToReplacement("home");
|
|
} on AppwriteException catch (e) {
|
|
status = AuthStatus.error;
|
|
user = null;
|
|
SnackBarService.instance.showSnackBarError(e.message!);
|
|
} on Exception catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
//
|
|
}
|
|
}
|
|
|
|
Future<void> createUserInDB(
|
|
String _documentId, String _email, String _name, String _imageURL) async {
|
|
try {
|
|
await database.createDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.userCollectionId,
|
|
documentId: _documentId,
|
|
data: {
|
|
"name": _name,
|
|
"email": _email,
|
|
"lastSeen": DateTime.now().toUtc().toIso8601String(),
|
|
"image": _imageURL
|
|
},
|
|
permissions: [
|
|
Permission.read(Role.any()),
|
|
//Permission.update(Role.user(_documentId)),
|
|
],
|
|
);
|
|
|
|
status = AuthStatus.authenticated;
|
|
} on AppwriteException catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.message!);
|
|
status = AuthStatus.error;
|
|
user = null;
|
|
//
|
|
} on Exception catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
status = AuthStatus.error;
|
|
user = null;
|
|
//
|
|
}
|
|
}
|
|
|
|
Future<void> updateLastSeen() async {
|
|
await database.updateDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.userCollectionId,
|
|
documentId: user!.$id,
|
|
data: {"lastSeen": DateTime.now().toUtc().toIso8601String()},
|
|
);
|
|
}
|
|
|
|
Stream<User> getUser(String userId) async* {
|
|
//
|
|
var _userData = database.getDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.userCollectionId,
|
|
documentId: userId,
|
|
);
|
|
|
|
updateLastSeen();
|
|
yield* _userData.asStream().map((_document) {
|
|
return User.fromData(_document);
|
|
});
|
|
}
|
|
|
|
Stream<List<User>> getAllUsers(String _searchText) async* {
|
|
//
|
|
List<User> _returnValue = [];
|
|
if (_searchText.isNotEmpty) {
|
|
var _usersData = database.listDocuments(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.userCollectionId,
|
|
queries: [
|
|
Query.contains("name", _searchText),
|
|
],
|
|
);
|
|
|
|
yield* _usersData.asStream().map(
|
|
(_documentList) {
|
|
for (var _document in _documentList.documents) {
|
|
_returnValue.add(User.fromData(_document));
|
|
}
|
|
_returnValue.sort((a, b) => b.lastSeen.compareTo(a.lastSeen));
|
|
return _returnValue;
|
|
},
|
|
);
|
|
} else {
|
|
yield* Stream.empty();
|
|
}
|
|
}
|
|
|
|
Stream<List<Conversations>> getUserConversation(String userId) async* {
|
|
//
|
|
List<dynamic> _chatId = [];
|
|
List<dynamic> _details = [];
|
|
List<dynamic> _lastModified = [];
|
|
List<Conversations> _returnValue = [];
|
|
|
|
var _conversationData = database.getDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.convCollectionId,
|
|
documentId: userId.trim(),
|
|
);
|
|
|
|
yield* _conversationData.asStream().map(
|
|
(_snapshot) {
|
|
_chatId = _snapshot.data['chatId'];
|
|
_details = _snapshot.data['details'];
|
|
_lastModified = _snapshot.data['lastModified'];
|
|
|
|
for (int i = 0; i < _chatId.length; i++) {
|
|
_returnValue.add(Conversations.fromData(
|
|
_chatId[i], _details[i], _lastModified[i]));
|
|
}
|
|
_returnValue.sort((a, b) => b.lastModified!.compareTo(a.lastModified!));
|
|
return _returnValue;
|
|
},
|
|
);
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
Stream<Chats> getMessage(String _chatId) async* {
|
|
//
|
|
try {
|
|
var _chat = database.getDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.chatsCollectionId,
|
|
documentId: _chatId,
|
|
);
|
|
yield* _chat.asStream().map(
|
|
(_document) {
|
|
return Chats.fromDocument(_document);
|
|
},
|
|
);
|
|
} on AppwriteException catch (e) {
|
|
e.message!;
|
|
yield* Stream.empty();
|
|
} on Exception catch (e) {
|
|
e.toString();
|
|
yield* Stream.empty();
|
|
}
|
|
// else {}
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> sendMessage(String _chatId, Map<String, dynamic> _messages,
|
|
String _newOrUpdate) async {
|
|
//
|
|
if (_newOrUpdate == 'new') {
|
|
await database.createDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.chatsCollectionId,
|
|
documentId: _chatId,
|
|
data: _messages,
|
|
);
|
|
} else if (_newOrUpdate == 'update') {
|
|
await database.updateDocument(
|
|
databaseId: Constants.instance.databaseId,
|
|
collectionId: Constants.instance.chatsCollectionId,
|
|
documentId: _chatId,
|
|
data: _messages,
|
|
);
|
|
}
|
|
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<String> uploadUserImage(XFile? file, String _uid) async {
|
|
//
|
|
notifyListeners();
|
|
try {
|
|
File _file = File(file!.path);
|
|
var _message = await storage.createFile(
|
|
bucketId: Constants.instance.imageStorageBucket,
|
|
fileId: ID.unique(),
|
|
file: InputFile.fromPath(path: _file.path, filename: file.name),
|
|
permissions: [
|
|
Permission.read(Role.any()),
|
|
// Permission.update(Role.user(_uid))
|
|
],
|
|
);
|
|
|
|
return "${Constants.instance.endPoint}/storage/buckets/${_message.bucketId}/files/${_message.$id}/view?project=${Constants.instance.projectId}";
|
|
} on AppwriteException catch (e) {
|
|
SnackBarService.instance.showSnackBarError(e.message!);
|
|
//
|
|
} on Exception catch (e) {
|
|
status = AuthStatus.error;
|
|
user = null;
|
|
SnackBarService.instance.showSnackBarError(e.toString());
|
|
//
|
|
}
|
|
return "";
|
|
}
|
|
}
|