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; // Auth Status AuthStatus? status; late model.User? user; 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(); _autoLogin(); } } catch (e) { status = AuthStatus.notAuthenticated; } finally { notifyListeners(); } } void _autoLogin() { NavigationService.instance.navigateToReplacement("home"); } void login(String _email, String _password) async { // notifyListeners(); 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()); // } notifyListeners(); } 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(); await NavigationService.instance.navigateToReplacement("login"); SnackBarService.instance.showSnackBarError("logged out successfully"); } on AppwriteException catch (e) { SnackBarService.instance.showSnackBarError(e.message!); } on Exception catch (e) { SnackBarService.instance.showSnackBarError(e.toString()); } notifyListeners(); } Future createUser(String _email, String _password, String _name, Future Function(String _uid) onSuccess) async { notifyListeners(); 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()); // } notifyListeners(); } Future createUserInDB( String _documentId, String _email, String _name, String _imageURL) async { notifyListeners(); 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; // } notifyListeners(); } Future updateLastSeen() async { await database.updateDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.userCollectionId, documentId: user!.$id, data: {"lastSeen": DateTime.now().toUtc().toIso8601String()}, ); } Stream getUser(String userId) { // var _userData = database.getDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.userCollectionId, documentId: userId, ); return _userData.asStream().map((_document) { return User.fromData(_document); }); } Stream> getAllUsers(String _searchText) async* { // // while (true) { List _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> getUserConversation(String userId) async* { // // while (true) { List _chatId = []; List _details = []; List _lastModified = []; List _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; }, ); // } } // Stream> getUserConversations(String userId) async* { // // // // while (true) { // List _chatId = []; // List _details = []; // List _lastModified = []; // List _returnValue = []; // var _conversationData = await database.getDocument( // databaseId: Constants.instance.databaseId, // collectionId: Constants.instance.convCollectionId, // documentId: userId.trim(), // ); // yield _conversationData.toMap 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; // }, // ); // // } // } Stream getMessage(String _chatId) async* { // // while (true) { var _chat = database.getDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.chatsCollectionId, documentId: _chatId, ); yield* _chat.asStream().map( (_document) { return Chats.fromDocument(_document); }, ); // } } Future getConversationLink(var _linkId) async { // try { var _conversationLinkDetail = await database.getDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.conversationLinkId, documentId: _linkId, ); notifyListeners(); return _conversationLinkDetail.data['chatId']; } on AppwriteException catch (e) { notifyListeners(); return ''; } } Future newMesaage(Map _chat) async { // var chatId = ID.unique(); await database.createDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.chatsCollectionId, documentId: chatId, data: _chat, ); notifyListeners(); return chatId; } Future sendMessage( String chatId, Map _messages) async { // await database.updateDocument( databaseId: Constants.instance.databaseId, collectionId: Constants.instance.chatsCollectionId, documentId: chatId, data: _messages, ); notifyListeners(); } Future 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()); // } notifyListeners(); return ""; } }