Recent Conversations Page, Conversations Page implemented'
This commit is contained in:
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
# A chat app built using Flutter for Both iOS and Android.
|
# A chat app built using Flutter for Both iOS and Android.
|
||||||
|
|
||||||
Backend is being covered by Appwrite. It is opensource and can be selfhosted, which is the main reason for it being used a backend.
|
Backend is being covered by Appwrite. It is opensource and can be selfhosted, which is the main reason for it being used as a backend.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
//const endPoint = 'http://10.15.45.11/v1';
|
//const endPoint = 'http://10.15.45.11/v1';
|
||||||
//const endPoint = 'https://api.theonasanyas.com/v1';
|
//const endPoint = 'https://api.theonasanyas.com/v1';
|
||||||
const endPoint = 'https://cloud.appwrite.io/v1';
|
class Constants {
|
||||||
const projectId = '678bdc7c00203eff8af5';
|
static Constants instance = Constants();
|
||||||
const selfSigned = false;
|
|
||||||
const databaseId = '678c8659000a7d6b5bff';
|
var endPoint = 'https://cloud.appwrite.io/v1';
|
||||||
const userCollectionId = '678c865e002fe1cddd06';
|
var projectId = '678bdc7c00203eff8af5';
|
||||||
const chatsCollectionId = '678c866c0038822276ad';
|
var selfSigned = false;
|
||||||
const convCollectionId = '678c8667001944dee794';
|
var databaseId = '678c8659000a7d6b5bff';
|
||||||
const imageStorageBucket = '678d2162002a6770aaad';
|
var userCollectionId = '678c865e002fe1cddd06';
|
||||||
|
var chatsCollectionId = '678c866c0038822276ad';
|
||||||
|
var convCollectionId = '678c8667001944dee794';
|
||||||
|
var imageStorageBucket = '678d2162002a6770aaad';
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:appwrite/models.dart' as model;
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:messaging_app/components/constants.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/conversations.dart';
|
||||||
import 'package:messaging_app/models/users.dart';
|
import 'package:messaging_app/models/users.dart';
|
||||||
import 'package:messaging_app/service/navigation_service.dart';
|
import 'package:messaging_app/service/navigation_service.dart';
|
||||||
@@ -25,9 +26,8 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
late final Storage storage;
|
late final Storage storage;
|
||||||
|
|
||||||
// Auth Status
|
// Auth Status
|
||||||
late AuthStatus status;
|
AuthStatus? status;
|
||||||
late model.User? user;
|
late model.User? user;
|
||||||
late model.Session session;
|
|
||||||
|
|
||||||
static MessagingProviders instance = MessagingProviders();
|
static MessagingProviders instance = MessagingProviders();
|
||||||
|
|
||||||
@@ -37,7 +37,10 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_init() {
|
_init() {
|
||||||
client.setEndpoint(endPoint).setProject(projectId).setSelfSigned();
|
client
|
||||||
|
.setEndpoint(Constants.instance.endPoint)
|
||||||
|
.setProject(Constants.instance.projectId)
|
||||||
|
.setSelfSigned();
|
||||||
account = Account(client);
|
account = Account(client);
|
||||||
database = Databases(client);
|
database = Databases(client);
|
||||||
storage = Storage(client);
|
storage = Storage(client);
|
||||||
@@ -48,6 +51,7 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
user = await account.get();
|
user = await account.get();
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
status = AuthStatus.authenticated;
|
status = AuthStatus.authenticated;
|
||||||
|
await updateLastSeen();
|
||||||
_autoLogin();
|
_autoLogin();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -69,13 +73,14 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
status = AuthStatus.authenticating;
|
status = AuthStatus.authenticating;
|
||||||
session = await account.createEmailPasswordSession(
|
await account.createEmailPasswordSession(
|
||||||
email: _email, password: _password);
|
email: _email, password: _password);
|
||||||
|
|
||||||
user = await account.get();
|
user = await account.get();
|
||||||
status = AuthStatus.authenticated;
|
status = AuthStatus.authenticated;
|
||||||
|
|
||||||
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
||||||
|
await updateLastSeen();
|
||||||
NavigationService.instance.navigateToReplacement("home");
|
NavigationService.instance.navigateToReplacement("home");
|
||||||
} on AppwriteException catch (e) {
|
} on AppwriteException catch (e) {
|
||||||
SnackBarService.instance.showSnackBarError(e.message!);
|
SnackBarService.instance.showSnackBarError(e.message!);
|
||||||
@@ -109,7 +114,7 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createUser(String _email, String _password, String _name,
|
Future<void> createUser(String _email, String _password, String _name,
|
||||||
Future<void> onSuccess(String _uid)) async {
|
Future<void> Function(String _uid) onSuccess) async {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
user = await account.create(
|
user = await account.create(
|
||||||
@@ -118,6 +123,7 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
status = AuthStatus.authenticated;
|
status = AuthStatus.authenticated;
|
||||||
await onSuccess(user!.$id);
|
await onSuccess(user!.$id);
|
||||||
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
||||||
|
await updateLastSeen();
|
||||||
NavigationService.instance.goBack();
|
NavigationService.instance.goBack();
|
||||||
NavigationService.instance.navigateToReplacement("home");
|
NavigationService.instance.navigateToReplacement("home");
|
||||||
} on AppwriteException catch (e) {
|
} on AppwriteException catch (e) {
|
||||||
@@ -136,8 +142,8 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
await database.createDocument(
|
await database.createDocument(
|
||||||
databaseId: databaseId,
|
databaseId: Constants.instance.databaseId,
|
||||||
collectionId: userCollectionId,
|
collectionId: Constants.instance.userCollectionId,
|
||||||
documentId: _documentId,
|
documentId: _documentId,
|
||||||
data: {
|
data: {
|
||||||
"name": _name,
|
"name": _name,
|
||||||
@@ -166,18 +172,51 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<Users> getUser(String userId) {
|
Stream<Users> getUser(String userId) {
|
||||||
var _userData = database.getDocument(
|
var _userData = database.getDocument(
|
||||||
databaseId: databaseId,
|
databaseId: Constants.instance.databaseId,
|
||||||
collectionId: userCollectionId,
|
collectionId: Constants.instance.userCollectionId,
|
||||||
documentId: userId,
|
documentId: userId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return _userData.asStream().map((_snapshot) {
|
return _userData.asStream().map((_document) {
|
||||||
return Users.fromData(_snapshot);
|
return Users.fromData(_document);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<List<Users>> getAllUsers(String _searchText) {
|
||||||
|
List<Users> _returnValue = [];
|
||||||
|
if (_searchText.isNotEmpty) {
|
||||||
|
var _usersData = database.listDocuments(
|
||||||
|
databaseId: Constants.instance.databaseId,
|
||||||
|
collectionId: Constants.instance.userCollectionId,
|
||||||
|
queries: [
|
||||||
|
Query.contains("name", _searchText),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return _usersData.asStream().map(
|
||||||
|
(_documentList) {
|
||||||
|
for (var _document in _documentList.documents) {
|
||||||
|
_returnValue.add(Users.fromData(_document));
|
||||||
|
}
|
||||||
|
return _returnValue;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Stream<List<Conversations>> getUserConversation(String userId) {
|
Stream<List<Conversations>> getUserConversation(String userId) {
|
||||||
//
|
//
|
||||||
List<dynamic> _chatId = [];
|
List<dynamic> _chatId = [];
|
||||||
@@ -185,8 +224,8 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
List<Conversations> _returnValue = [];
|
List<Conversations> _returnValue = [];
|
||||||
|
|
||||||
var _conversationData = database.getDocument(
|
var _conversationData = database.getDocument(
|
||||||
databaseId: databaseId,
|
databaseId: Constants.instance.databaseId,
|
||||||
collectionId: convCollectionId,
|
collectionId: Constants.instance.convCollectionId,
|
||||||
documentId: userId.trim(),
|
documentId: userId.trim(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -203,12 +242,24 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<Chats> getChat(String _chatId) {
|
||||||
|
var _chat = database.getDocument(
|
||||||
|
databaseId: Constants.instance.databaseId,
|
||||||
|
collectionId: Constants.instance.chatsCollectionId,
|
||||||
|
documentId: _chatId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return _chat.asStream().map((_document) {
|
||||||
|
return Chats.fromData(_document);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
uploadUserImage(XFile? file, String _uid) async {
|
uploadUserImage(XFile? file, String _uid) async {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
try {
|
try {
|
||||||
File _file = File(file!.path);
|
File _file = File(file!.path);
|
||||||
var _message = await storage.createFile(
|
var _message = await storage.createFile(
|
||||||
bucketId: imageStorageBucket,
|
bucketId: Constants.instance.imageStorageBucket,
|
||||||
fileId: ID.unique(),
|
fileId: ID.unique(),
|
||||||
file: InputFile.fromPath(path: _file.path, filename: file.name),
|
file: InputFile.fromPath(path: _file.path, filename: file.name),
|
||||||
permissions: [
|
permissions: [
|
||||||
@@ -217,7 +268,7 @@ class MessagingProviders extends ChangeNotifier {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
return "$endPoint/storage/buckets/${_message.bucketId}/files/${_message.$id}/view?project=$projectId";
|
return "${Constants.instance.endPoint}/storage/buckets/${_message.bucketId}/files/${_message.$id}/view?project=${Constants.instance.projectId}";
|
||||||
} on AppwriteException catch (e) {
|
} on AppwriteException catch (e) {
|
||||||
SnackBarService.instance.showSnackBarError(e.message!);
|
SnackBarService.instance.showSnackBarError(e.message!);
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:appwrite/models.dart';
|
||||||
|
import 'package:messaging_app/models/messages.dart';
|
||||||
|
|
||||||
|
class Chats {
|
||||||
|
String ownerId;
|
||||||
|
List<String> members;
|
||||||
|
String? type;
|
||||||
|
List<Messages>? messages;
|
||||||
|
|
||||||
|
Chats({
|
||||||
|
required this.ownerId,
|
||||||
|
required this.members,
|
||||||
|
required this.type,
|
||||||
|
required this.messages,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Chats.fromData(Document _document) {
|
||||||
|
List<Messages> _outMessages = [];
|
||||||
|
List<String> _outMembers = [];
|
||||||
|
List<dynamic> _messages = _document.data['messages'];
|
||||||
|
|
||||||
|
for (var _message in _messages) {
|
||||||
|
_outMessages.add(Messages.fromData(_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<dynamic> _members = _document.data['members'];
|
||||||
|
for (var _member in _members) {
|
||||||
|
_outMembers.add(_member);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Chats(
|
||||||
|
ownerId: _document.data['ownerId'],
|
||||||
|
members: _outMembers,
|
||||||
|
type: _document.data['type'],
|
||||||
|
messages: _outMessages,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ class Conversations {
|
|||||||
required this.details,
|
required this.details,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Conversations.fromData(String _chatId, String details) {
|
factory Conversations.fromData(String _chatId, String _details) {
|
||||||
return Conversations(
|
return Conversations(
|
||||||
chatId: _chatId,
|
chatId: _chatId,
|
||||||
details: Details.fromData(details),
|
details: Details.fromData(_details),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import 'dart:convert';
|
|||||||
class Details {
|
class Details {
|
||||||
String name;
|
String name;
|
||||||
String image;
|
String image;
|
||||||
int? unseenCount;
|
int unseenCount;
|
||||||
String lastMessage;
|
String? lastMessage;
|
||||||
DateTime? timeStamp;
|
DateTime? timeStamp;
|
||||||
|
|
||||||
Details({
|
Details({
|
||||||
@@ -15,14 +15,13 @@ class Details {
|
|||||||
required this.unseenCount,
|
required this.unseenCount,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Details.fromData(String _data) {
|
factory Details.fromData(String _details) {
|
||||||
Map _decodedData = json.decode(_data);
|
|
||||||
return Details(
|
return Details(
|
||||||
name: _decodedData['name'],
|
name: json.decode(_details)['name'],
|
||||||
image: _decodedData['image'],
|
image: json.decode(_details)['image'],
|
||||||
lastMessage: _decodedData['lastMessage'],
|
lastMessage: json.decode(_details)['lastMessage'],
|
||||||
timeStamp: DateTime.parse(_decodedData['timeStamp'] ?? ""),
|
timeStamp: DateTime.parse(json.decode(_details)['timeStamp'] ?? ""),
|
||||||
unseenCount: _decodedData['unseenCount'],
|
unseenCount: json.decode(_details)['unseenCount'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
enum MessageType {
|
||||||
|
Text,
|
||||||
|
Image,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Messages {
|
||||||
|
String message;
|
||||||
|
String senderId;
|
||||||
|
MessageType type;
|
||||||
|
DateTime timeStamp;
|
||||||
|
|
||||||
|
Messages({
|
||||||
|
required this.message,
|
||||||
|
required this.senderId,
|
||||||
|
required this.type,
|
||||||
|
required this.timeStamp,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Messages.fromData(String _message) {
|
||||||
|
var _messageType = json.decode(_message)['type'] == "text"
|
||||||
|
? MessageType.Text
|
||||||
|
: MessageType.Image;
|
||||||
|
|
||||||
|
return Messages(
|
||||||
|
message: json.decode(_message)['message'],
|
||||||
|
senderId: json.decode(_message)['senderId'],
|
||||||
|
type: _messageType,
|
||||||
|
timeStamp: DateTime.parse(json.decode(_message)['timeStamp'] ?? ""),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,27 @@
|
|||||||
import 'package:appwrite/models.dart';
|
import 'package:appwrite/models.dart';
|
||||||
|
|
||||||
class Users {
|
class Users {
|
||||||
|
String id;
|
||||||
String name;
|
String name;
|
||||||
String email;
|
String email;
|
||||||
String image;
|
String image;
|
||||||
DateTime lastSeen;
|
DateTime lastSeen;
|
||||||
|
|
||||||
Users({
|
Users({
|
||||||
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.email,
|
required this.email,
|
||||||
required this.image,
|
required this.image,
|
||||||
required this.lastSeen,
|
required this.lastSeen,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Users.fromData(Document _snapshot) {
|
factory Users.fromData(Document _document) {
|
||||||
return Users(
|
return Users(
|
||||||
name: _snapshot.data["name"],
|
id: _document.data['\$id'],
|
||||||
email: _snapshot.data["email"],
|
name: _document.data['name'],
|
||||||
image: _snapshot.data["image"],
|
email: _document.data['email'],
|
||||||
lastSeen: DateTime.parse(_snapshot.data["lastSeen"]),
|
image: _document.data['image'],
|
||||||
|
lastSeen: DateTime.parse(_document.data['lastSeen']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,234 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:messaging_app/components/messaging_provider.dart';
|
||||||
|
import 'package:messaging_app/models/chats.dart';
|
||||||
|
import 'package:messaging_app/models/messages.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
|
class ConversationsPage extends StatefulWidget {
|
||||||
|
ConversationsPage({
|
||||||
|
super.key,
|
||||||
|
required this.conversationId,
|
||||||
|
// required this.receiverId,
|
||||||
|
required this.chatImage,
|
||||||
|
required this.chatName,
|
||||||
|
});
|
||||||
|
|
||||||
|
String conversationId;
|
||||||
|
// String receiverId;
|
||||||
|
String chatName;
|
||||||
|
String chatImage;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return _ConversationsPageState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ConversationsPageState extends State<ConversationsPage> {
|
||||||
|
//
|
||||||
|
|
||||||
|
late double _deviceHeight;
|
||||||
|
late double _deviceWidth;
|
||||||
|
late MessagingProviders _auth;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
//
|
||||||
|
_deviceHeight = MediaQuery.of(context).size.height;
|
||||||
|
_deviceWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
|
title: Text(widget.chatName),
|
||||||
|
titleTextStyle: TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
body: ChangeNotifierProvider<MessagingProviders>.value(
|
||||||
|
value: MessagingProviders.instance,
|
||||||
|
child: _conversationPageUI(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _conversationPageUI() {
|
||||||
|
return Builder(builder: (_context) {
|
||||||
|
_auth = Provider.of<MessagingProviders>(_context);
|
||||||
|
return Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
_messageListView(),
|
||||||
|
_messageInputField(_context),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _messageListView() {
|
||||||
|
return Container(
|
||||||
|
height: _deviceHeight * 0.75,
|
||||||
|
width: _deviceWidth,
|
||||||
|
child: StreamBuilder<Chats>(
|
||||||
|
stream: MessagingProviders.instance.getChat(widget.conversationId),
|
||||||
|
builder: (_context, _snapshot) {
|
||||||
|
return _snapshot.hasData
|
||||||
|
? ListView.builder(
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 10,
|
||||||
|
),
|
||||||
|
itemCount: _snapshot.data!.messages!.length,
|
||||||
|
itemBuilder: (BuildContext _context, int _index) {
|
||||||
|
var _message = _snapshot.data!.messages![_index];
|
||||||
|
return _messageView(_message);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: Text("");
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _messageView(Messages _message) {
|
||||||
|
bool _isOwnMessage = false;
|
||||||
|
if (_message.senderId == _auth.user!.$id) {
|
||||||
|
_isOwnMessage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 10),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment:
|
||||||
|
_isOwnMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
_isOwnMessage ? Container() : _imageViewBubble(),
|
||||||
|
_textMessageBubble(_isOwnMessage, _message),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _textMessageBubble(bool _isOwnMessage, Messages _message) {
|
||||||
|
List<Color> _colorScheme = _isOwnMessage
|
||||||
|
? [Colors.blue, Color.fromRGBO(42, 117, 188, 1)]
|
||||||
|
: [Color.fromRGBO(49, 69, 69, 1), Color.fromRGBO(43, 43, 43, 1)];
|
||||||
|
return Container(
|
||||||
|
height: _deviceHeight * 0.10,
|
||||||
|
width: _deviceWidth * 0.75,
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
gradient: LinearGradient(
|
||||||
|
colors: _colorScheme,
|
||||||
|
stops: [0.25, 0.85],
|
||||||
|
begin: Alignment.bottomLeft,
|
||||||
|
end: Alignment.bottomRight),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(_message.message),
|
||||||
|
Text(
|
||||||
|
timeago.format(_message.timeStamp),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white70,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _imageViewBubble() {
|
||||||
|
return Container(
|
||||||
|
height: _deviceHeight * 0.05,
|
||||||
|
width: _deviceHeight * 0.05,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(500),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(
|
||||||
|
widget.chatImage,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _messageInputField(BuildContext _context) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
children: [
|
||||||
|
_messageText(),
|
||||||
|
_imageUpload(),
|
||||||
|
_sendMessage(_context),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _messageText() {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color.fromRGBO(43, 43, 43, 1),
|
||||||
|
borderRadius: BorderRadius.circular(30)
|
||||||
|
),
|
||||||
|
margin: EdgeInsets.symmetric(
|
||||||
|
horizontal: _deviceWidth * 0.04,
|
||||||
|
vertical: _deviceHeight * 0.02
|
||||||
|
),
|
||||||
|
width: _deviceWidth * 0.70,
|
||||||
|
child: TextFormField(
|
||||||
|
validator: (_input) {
|
||||||
|
if (_input == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChanged: (_input) {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
onSaved: (_input) {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
cursorColor: Colors.white,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: "type a message",
|
||||||
|
),
|
||||||
|
autocorrect: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _sendMessage(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: _deviceHeight * 0.045,
|
||||||
|
width: _deviceHeight * 0.045,
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.send,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _imageUpload() {
|
||||||
|
return SizedBox(
|
||||||
|
height: _deviceHeight * 0.045,
|
||||||
|
width: _deviceHeight * 0.045,
|
||||||
|
child: FloatingActionButton(onPressed: () {},
|
||||||
|
backgroundColor: Colors.blue,
|
||||||
|
child: Icon(Icons.camera_enhance),),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:messaging_app/pages/profile_page.dart';
|
import 'package:messaging_app/pages/profile_page.dart';
|
||||||
import 'package:messaging_app/pages/recent_converstations.dart';
|
import 'package:messaging_app/pages/recent_converstations_page.dart';
|
||||||
|
import 'package:messaging_app/pages/search_page.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
const HomePage({super.key});
|
const HomePage({super.key});
|
||||||
@@ -14,10 +15,11 @@ class HomePage extends StatefulWidget {
|
|||||||
|
|
||||||
class _HomePageState extends State<HomePage>
|
class _HomePageState extends State<HomePage>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
|
//TickerProviderStateMixin
|
||||||
// //
|
// //
|
||||||
late double _deviceHeight;
|
late double _deviceHeight;
|
||||||
late double _deviceWidth;
|
late double _deviceWidth;
|
||||||
late TabController _tabController;
|
late final TabController _tabController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -42,10 +44,10 @@ class _HomePageState extends State<HomePage>
|
|||||||
_deviceWidth = MediaQuery.of(context).size.width;
|
_deviceWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
// backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
// backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||||
title: Text("Slick Messenger"),
|
title: Text("the messenger"),
|
||||||
titleTextStyle: TextStyle(fontSize: 16),
|
titleTextStyle: TextStyle(fontSize: 16),
|
||||||
bottom: TabBar(
|
bottom: TabBar(
|
||||||
unselectedLabelColor: Colors.grey,
|
unselectedLabelColor: Colors.grey,
|
||||||
@@ -56,19 +58,19 @@ class _HomePageState extends State<HomePage>
|
|||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.people_outline,
|
Icons.people_outline,
|
||||||
size: 25,
|
size: 30,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.chat_bubble_outline,
|
Icons.chat_bubble_outline,
|
||||||
size: 25,
|
size: 30,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.person_outline,
|
Icons.person_outline,
|
||||||
size: 25,
|
size: 30,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -82,7 +84,7 @@ class _HomePageState extends State<HomePage>
|
|||||||
return TabBarView(
|
return TabBarView(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: [
|
children: [
|
||||||
Placeholder(),
|
SearchPage( deviceHeight: _deviceHeight , deviceWidth: _deviceWidth,),
|
||||||
RecentConverstationsPage(_deviceHeight, _deviceWidth),
|
RecentConverstationsPage(_deviceHeight, _deviceWidth),
|
||||||
ProfilePage(_deviceHeight, _deviceWidth),
|
ProfilePage(_deviceHeight, _deviceWidth),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
},
|
},
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Login'.toUpperCase(),
|
'LOGIN',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
import 'package:messaging_app/components/messaging_provider.dart';
|
import 'package:messaging_app/components/messaging_provider.dart';
|
||||||
import 'package:messaging_app/models/users.dart';
|
import 'package:messaging_app/models/users.dart';
|
||||||
|
import 'package:messaging_app/service/snackbar_service.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
class ProfilePage extends StatelessWidget {
|
class ProfilePage extends StatelessWidget {
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ class ProfilePage extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _profilePageUI() {
|
Widget _profilePageUI() {
|
||||||
return Builder(builder: (BuildContext _context) {
|
return Builder(builder: (BuildContext _context) {
|
||||||
|
SnackBarService.instance.buildContext = _context;
|
||||||
_auth = Provider.of<MessagingProviders>(_context);
|
_auth = Provider.of<MessagingProviders>(_context);
|
||||||
return StreamBuilder<Users>(
|
return StreamBuilder<Users>(
|
||||||
stream: MessagingProviders.instance.getUser(_auth.user!.$id),
|
stream: MessagingProviders.instance.getUser(_auth.user!.$id),
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
||||||
import 'package:messaging_app/components/messaging_provider.dart';
|
|
||||||
import 'package:messaging_app/models/conversations.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:timeago/timeago.dart' as timeago;
|
|
||||||
|
|
||||||
class RecentConverstationsPage extends StatelessWidget {
|
|
||||||
//
|
|
||||||
|
|
||||||
final double _deviceHeight;
|
|
||||||
final double _deviceWidth;
|
|
||||||
late MessagingProviders _auth;
|
|
||||||
|
|
||||||
RecentConverstationsPage(this._deviceHeight, this._deviceWidth);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
height: _deviceHeight,
|
|
||||||
width: _deviceWidth,
|
|
||||||
child: ChangeNotifierProvider<MessagingProviders>.value(
|
|
||||||
value: MessagingProviders.instance,
|
|
||||||
child: _conversationView(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _conversationView() {
|
|
||||||
return Builder(builder: (_context) {
|
|
||||||
_auth = Provider.of<MessagingProviders>(_context);
|
|
||||||
return Container(
|
|
||||||
height: _deviceHeight,
|
|
||||||
width: _deviceWidth,
|
|
||||||
child: StreamBuilder<List<Conversations>>(
|
|
||||||
stream: MessagingProviders.instance
|
|
||||||
.getUserConversation(_auth.user!.$id),
|
|
||||||
builder: (_, _snapshot) {
|
|
||||||
return _snapshot.hasData
|
|
||||||
? ListView.builder(
|
|
||||||
itemCount: _snapshot.data!.length,
|
|
||||||
itemBuilder: (_context, _index) {
|
|
||||||
var _details = _snapshot.data![_index].details;
|
|
||||||
return ListTile(
|
|
||||||
onTap: () {
|
|
||||||
//
|
|
||||||
},
|
|
||||||
title: Text(_details.name),
|
|
||||||
subtitle: Text(_details.lastMessage),
|
|
||||||
leading: Container(
|
|
||||||
width: 50,
|
|
||||||
height: 50,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
image: DecorationImage(
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
image: NetworkImage(_details.image),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: _listTrailingWidget(_details.timeStamp),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: SpinKitWanderingCubes(
|
|
||||||
color: Colors.blue,
|
|
||||||
size: 50.0,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _listTrailingWidget(DateTime? _date) {
|
|
||||||
return Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
timeago.format(_date!),
|
|
||||||
style: TextStyle(fontSize: 15),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 12,
|
|
||||||
width: 12,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.blue,
|
|
||||||
borderRadius: BorderRadius.circular(100),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
import 'package:messaging_app/components/messaging_provider.dart';
|
||||||
|
import 'package:messaging_app/models/conversations.dart';
|
||||||
|
import 'package:messaging_app/pages/conversations_page.dart';
|
||||||
|
import 'package:messaging_app/service/navigation_service.dart';
|
||||||
|
import 'package:messaging_app/service/snackbar_service.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class RecentConverstationsPage extends StatelessWidget {
|
||||||
|
//
|
||||||
|
final double _deviceHeight;
|
||||||
|
final double _deviceWidth;
|
||||||
|
late MessagingProviders _auth;
|
||||||
|
|
||||||
|
RecentConverstationsPage(this._deviceHeight, this._deviceWidth);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
height: _deviceHeight,
|
||||||
|
width: _deviceWidth,
|
||||||
|
child: ChangeNotifierProvider<MessagingProviders>.value(
|
||||||
|
value: MessagingProviders.instance,
|
||||||
|
child: _conversationView(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _conversationView() {
|
||||||
|
return Builder(builder: (_context) {
|
||||||
|
SnackBarService.instance.buildContext = _context;
|
||||||
|
_auth = Provider.of<MessagingProviders>(_context);
|
||||||
|
return SizedBox(
|
||||||
|
height: _deviceHeight,
|
||||||
|
width: _deviceWidth,
|
||||||
|
child: StreamBuilder<List<Conversations>>(
|
||||||
|
stream: MessagingProviders.instance
|
||||||
|
.getUserConversation(_auth.user!.$id),
|
||||||
|
builder: (_, _snapshot) {
|
||||||
|
if (_snapshot.hasData) {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: _snapshot.data!.length,
|
||||||
|
itemBuilder: (_context, _index) {
|
||||||
|
var _details = _snapshot.data![_index].details;
|
||||||
|
var _chatId = _snapshot.data![_index].chatId;
|
||||||
|
return ListTile(
|
||||||
|
onTap: () {
|
||||||
|
//
|
||||||
|
NavigationService.instance.navigateToRoute(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (BuildContext _context) {
|
||||||
|
return ConversationsPage(
|
||||||
|
conversationId: _chatId,
|
||||||
|
chatName: _details.name,
|
||||||
|
chatImage: _details.image,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: Text(_details.name),
|
||||||
|
subtitle: Text(_details.lastMessage!),
|
||||||
|
leading: Container(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(_details.image),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: _listTrailingWidget(_details.timeStamp),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (_snapshot.hasError) {
|
||||||
|
return Align(
|
||||||
|
child: Text(
|
||||||
|
"no active conversation",
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return SpinKitWanderingCubes(
|
||||||
|
color: Colors.blue,
|
||||||
|
size: 50.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _listTrailingWidget(DateTime? _date) {
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"last message",
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
timeago.format(_date!),
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -226,7 +226,7 @@ class _RegisterationPageState extends State<RegisterationPage> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_image == null) {
|
if (_image == null) {
|
||||||
SnackBarService.instance
|
SnackBarService.instance
|
||||||
.showSnackBarError("Please Select Image");
|
.showSnackBarError("Please Select an Image");
|
||||||
}
|
}
|
||||||
if (_formKey.currentState!.validate() && _image != null) {
|
if (_formKey.currentState!.validate() && _image != null) {
|
||||||
//
|
//
|
||||||
@@ -247,7 +247,7 @@ class _RegisterationPageState extends State<RegisterationPage> {
|
|||||||
},
|
},
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
child: Text(
|
child: Text(
|
||||||
'Register'.toUpperCase(),
|
"REGISTER",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:messaging_app/components/messaging_provider.dart';
|
||||||
|
import 'package:messaging_app/models/users.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
|
|
||||||
|
class SearchPage extends StatefulWidget {
|
||||||
|
SearchPage({
|
||||||
|
super.key,
|
||||||
|
required this.deviceHeight,
|
||||||
|
required this.deviceWidth,
|
||||||
|
});
|
||||||
|
|
||||||
|
double deviceHeight;
|
||||||
|
double deviceWidth;
|
||||||
|
late MessagingProviders _auth;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SearchPage> createState() => _SearchPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SearchPageState extends State<SearchPage> {
|
||||||
|
late String _searchText;
|
||||||
|
late List<Users> _usersData;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_searchText = '';
|
||||||
|
_usersData = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: widget.deviceHeight,
|
||||||
|
width: widget.deviceWidth,
|
||||||
|
child: ChangeNotifierProvider.value(
|
||||||
|
value: MessagingProviders.instance,
|
||||||
|
child: _searchPaheUI(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _searchPaheUI() {
|
||||||
|
return Builder(builder: (_context) {
|
||||||
|
widget._auth = Provider.of<MessagingProviders>(_context);
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
_searchPageUIField(),
|
||||||
|
_searchPageUIList(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _searchPageUIField() {
|
||||||
|
return Container(
|
||||||
|
height: widget.deviceHeight * 0.08,
|
||||||
|
width: widget.deviceWidth,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: widget.deviceHeight * 0.02),
|
||||||
|
child: TextField(
|
||||||
|
autocorrect: false,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onChanged: (_input) {
|
||||||
|
setState(() {
|
||||||
|
_searchText = _input;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
prefixIcon: Icon(Icons.search),
|
||||||
|
labelText: "search",
|
||||||
|
labelStyle: TextStyle(color: Colors.white),
|
||||||
|
border: OutlineInputBorder(borderSide: BorderSide.none),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _searchPageUIList() {
|
||||||
|
return StreamBuilder<List<Users>>(
|
||||||
|
stream: MessagingProviders.instance.getAllUsers(_searchText.trim()),
|
||||||
|
builder: (_, _snapshot) {
|
||||||
|
if (_snapshot.hasData) {
|
||||||
|
_usersData = _snapshot.data!
|
||||||
|
.where((_data) => _data.id != widget._auth.user!.$id)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return _snapshot.hasData
|
||||||
|
? SizedBox(
|
||||||
|
height: widget.deviceHeight * 0.70,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: _usersData.length,
|
||||||
|
itemBuilder: (_, _index) {
|
||||||
|
var _userData = _usersData[_index];
|
||||||
|
var _isUserActive = _userData.lastSeen.isBefore(
|
||||||
|
DateTime.now().toUtc().subtract(
|
||||||
|
Duration(
|
||||||
|
minutes: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return ListTile(
|
||||||
|
title: Text(_userData.name),
|
||||||
|
leading: Container(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(100),
|
||||||
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: NetworkImage(_userData.image),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
trailing: Column(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceEvenly,
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
_isUserActive
|
||||||
|
? Text(
|
||||||
|
"last seen",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Text(
|
||||||
|
"active",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_isUserActive
|
||||||
|
? Text(
|
||||||
|
timeago.format(
|
||||||
|
_userData.lastSeen,
|
||||||
|
),
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
|
height: 10,
|
||||||
|
width: 10,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.blue,
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(100),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
: Container()
|
||||||
|
// : SpinKitWanderingCubes(
|
||||||
|
// color: Colors.blue,
|
||||||
|
// size: 50.0,
|
||||||
|
// );
|
||||||
|
;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,8 +6,6 @@ class SnackBarService {
|
|||||||
BuildContext? _buildContext;
|
BuildContext? _buildContext;
|
||||||
static SnackBarService instance = SnackBarService();
|
static SnackBarService instance = SnackBarService();
|
||||||
|
|
||||||
SnackBarService() {}
|
|
||||||
|
|
||||||
set buildContext(BuildContext _context) {
|
set buildContext(BuildContext _context) {
|
||||||
_buildContext = _context;
|
_buildContext = _context;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user