Pages Implementation
Implemented Profile and Recent Conversation skeleton pages
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# messaging_app
|
||||
## Messaging App - messaging_app
|
||||
|
||||
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 using is a backend.
|
||||
Backend is being covered by Appwrite. It is opensource and can be selfhosted, which is the main reason for it being used a backend.
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
description: This file stores settings for Dart & Flutter DevTools.
|
||||
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
|
||||
extensions:
|
||||
- provider: true
|
||||
@@ -1,10 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
import 'package:appwrite/models.dart' as models;
|
||||
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/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';
|
||||
|
||||
@@ -24,29 +25,31 @@ class MessagingProviders extends ChangeNotifier {
|
||||
late final Storage storage;
|
||||
|
||||
// Auth Status
|
||||
AuthStatus? status;
|
||||
|
||||
models.User? user;
|
||||
models.Session? session;
|
||||
late AuthStatus status;
|
||||
late model.User? user;
|
||||
late model.Session session;
|
||||
|
||||
static MessagingProviders instance = MessagingProviders();
|
||||
|
||||
MessagingProviders() {
|
||||
init();
|
||||
loadUser();
|
||||
_init();
|
||||
_loadUser();
|
||||
}
|
||||
|
||||
init() {
|
||||
_init() {
|
||||
client.setEndpoint(endPoint).setProject(projectId).setSelfSigned();
|
||||
account = Account(client);
|
||||
database = Databases(client);
|
||||
storage = Storage(client);
|
||||
}
|
||||
|
||||
loadUser() async {
|
||||
_loadUser() async {
|
||||
try {
|
||||
user = await account.get();
|
||||
status = AuthStatus.authenticated;
|
||||
if (user != null) {
|
||||
status = AuthStatus.authenticated;
|
||||
_autoLogin();
|
||||
}
|
||||
} catch (e) {
|
||||
status = AuthStatus.notAuthenticated;
|
||||
} finally {
|
||||
@@ -54,7 +57,11 @@ class MessagingProviders extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void loginWithEmailAndPassword(String _email, String _password) async {
|
||||
void _autoLogin() {
|
||||
NavigationService.instance.navigateToReplacement("home");
|
||||
}
|
||||
|
||||
void login(String _email, String _password) async {
|
||||
//
|
||||
notifyListeners();
|
||||
try {
|
||||
@@ -65,17 +72,11 @@ class MessagingProviders extends ChangeNotifier {
|
||||
session = await account.createEmailPasswordSession(
|
||||
email: _email, password: _password);
|
||||
|
||||
user = await account.get();
|
||||
status = AuthStatus.authenticated;
|
||||
var value = await database.getDocument(
|
||||
databaseId: databaseId,
|
||||
collectionId: userCollectionId,
|
||||
documentId: session!.userId,
|
||||
);
|
||||
|
||||
SnackBarService.instance
|
||||
.showSnackBarSuccess("Welcome! ${value.data['name']}");
|
||||
SnackBarService.instance.showSnackBarSuccess("Welcome! ${user!.name}");
|
||||
NavigationService.instance.navigateToReplacement("home");
|
||||
account.deleteSession(sessionId: 'current');
|
||||
} on AppwriteException catch (e) {
|
||||
SnackBarService.instance.showSnackBarError(e.message!);
|
||||
status = AuthStatus.error;
|
||||
@@ -91,6 +92,22 @@ class MessagingProviders extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void logout() async {
|
||||
try {
|
||||
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<void> createUser(String _email, String _password, String _name,
|
||||
Future<void> onSuccess(String _uid)) async {
|
||||
notifyListeners();
|
||||
@@ -149,6 +166,43 @@ class MessagingProviders extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Stream<Users> getUser(String userId) {
|
||||
var _userData = database.getDocument(
|
||||
databaseId: databaseId,
|
||||
collectionId: userCollectionId,
|
||||
documentId: userId,
|
||||
);
|
||||
|
||||
return _userData.asStream().map((_snapshot) {
|
||||
return Users.fromData(_snapshot);
|
||||
});
|
||||
}
|
||||
|
||||
Stream<List<Conversations>> getUserConversation(String userId) {
|
||||
//
|
||||
List<dynamic> _chatId = [];
|
||||
List<dynamic> _details = [];
|
||||
List<Conversations> _returnValue = [];
|
||||
|
||||
var _conversationData = database.getDocument(
|
||||
databaseId: databaseId,
|
||||
collectionId: convCollectionId,
|
||||
documentId: userId.trim(),
|
||||
);
|
||||
|
||||
return _conversationData.asStream().map(
|
||||
(_snapshot) {
|
||||
_chatId = _snapshot.data['chatId'];
|
||||
_details = _snapshot.data['details'];
|
||||
|
||||
for (int i = 0; i < _chatId.length; i++) {
|
||||
_returnValue.add(Conversations.fromData(_chatId[i], _details[i]));
|
||||
}
|
||||
return _returnValue;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
uploadUserImage(XFile? file, String _uid) async {
|
||||
notifyListeners();
|
||||
try {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class MessagingApp extends StatelessWidget {
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.dark,
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
primaryColor: Color.fromRGBO(42, 117, 188, 1.0),
|
||||
primaryColor: Color.fromRGBO(42, 117, 188, 1.0),
|
||||
colorScheme: ColorScheme.dark(),
|
||||
useMaterial3: true,
|
||||
),
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import 'package:messaging_app/models/details.dart';
|
||||
|
||||
class Conversations {
|
||||
String chatId;
|
||||
Details details;
|
||||
|
||||
Conversations({
|
||||
required this.chatId,
|
||||
required this.details,
|
||||
});
|
||||
|
||||
factory Conversations.fromData(String _chatId, String details) {
|
||||
return Conversations(
|
||||
chatId: _chatId,
|
||||
details: Details.fromData(details),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'dart:convert';
|
||||
|
||||
class Details {
|
||||
String name;
|
||||
String image;
|
||||
int? unseenCount;
|
||||
String lastMessage;
|
||||
DateTime? timeStamp;
|
||||
|
||||
Details({
|
||||
required this.name,
|
||||
required this.image,
|
||||
required this.lastMessage,
|
||||
required this.timeStamp,
|
||||
required this.unseenCount,
|
||||
});
|
||||
|
||||
factory Details.fromData(String _data) {
|
||||
Map _decodedData = json.decode(_data);
|
||||
return Details(
|
||||
name: _decodedData['name'],
|
||||
image: _decodedData['image'],
|
||||
lastMessage: _decodedData['lastMessage'],
|
||||
timeStamp: DateTime.parse(_decodedData['timeStamp'] ?? ""),
|
||||
unseenCount: _decodedData['unseenCount'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:appwrite/models.dart';
|
||||
|
||||
class Users {
|
||||
String name;
|
||||
String email;
|
||||
String image;
|
||||
DateTime lastSeen;
|
||||
|
||||
Users({
|
||||
required this.name,
|
||||
required this.email,
|
||||
required this.image,
|
||||
required this.lastSeen,
|
||||
});
|
||||
|
||||
factory Users.fromData(Document _snapshot) {
|
||||
return Users(
|
||||
name: _snapshot.data["name"],
|
||||
email: _snapshot.data["email"],
|
||||
image: _snapshot.data["image"],
|
||||
lastSeen: DateTime.parse(_snapshot.data["lastSeen"]),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:messaging_app/pages/profile_page.dart';
|
||||
import 'package:messaging_app/pages/recent_converstations.dart';
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
const HomePage({super.key});
|
||||
@@ -10,17 +12,80 @@ class HomePage extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> {
|
||||
class _HomePageState extends State<HomePage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
// //
|
||||
late double _deviceHeight;
|
||||
late double _deviceWidth;
|
||||
late TabController _tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(
|
||||
length: 3,
|
||||
vsync: this,
|
||||
initialIndex: 1,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
//
|
||||
_deviceHeight = MediaQuery.of(context).size.height;
|
||||
_deviceWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
title: Text("Messaging App"),
|
||||
titleTextStyle: TextStyle(fontSize: 15),
|
||||
title: Text("Slick Messenger"),
|
||||
titleTextStyle: TextStyle(fontSize: 16),
|
||||
bottom: TabBar(
|
||||
unselectedLabelColor: Colors.grey,
|
||||
indicatorColor: Colors.blue,
|
||||
labelColor: Colors.blue,
|
||||
controller: _tabController,
|
||||
tabs: [
|
||||
Tab(
|
||||
icon: Icon(
|
||||
Icons.people_outline,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
icon: Icon(
|
||||
Icons.chat_bubble_outline,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
icon: Icon(
|
||||
Icons.person_outline,
|
||||
size: 25,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: _tabBarPages(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _tabBarPages() {
|
||||
return TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
Placeholder(),
|
||||
RecentConverstationsPage(_deviceHeight, _deviceWidth),
|
||||
ProfilePage(_deviceHeight, _deviceWidth),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:messaging_app/service/snackbar_service.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
const LoginPage({super.key,});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
@@ -41,7 +41,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
value: MessagingProviders.instance,
|
||||
child: _loginPageUI(),
|
||||
),
|
||||
//_loginPageUI(),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -172,12 +171,12 @@ class _LoginPageState extends State<LoginPage> {
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
//Login User
|
||||
_auth.loginWithEmailAndPassword(_email!, _password!);
|
||||
_auth.login(_email!, _password!);
|
||||
}
|
||||
},
|
||||
color: Colors.blue,
|
||||
child: Text(
|
||||
'Login',
|
||||
'Login'.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
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/users.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ProfilePage extends StatelessWidget {
|
||||
//
|
||||
|
||||
final double _deviceHeight;
|
||||
final double _deviceWidth;
|
||||
late MessagingProviders _auth;
|
||||
|
||||
ProfilePage(this._deviceHeight, this._deviceWidth, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: _deviceHeight,
|
||||
width: _deviceWidth,
|
||||
child: ChangeNotifierProvider<MessagingProviders>.value(
|
||||
value: MessagingProviders.instance,
|
||||
child: _profilePageUI(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _profilePageUI() {
|
||||
return Builder(builder: (BuildContext _context) {
|
||||
_auth = Provider.of<MessagingProviders>(_context);
|
||||
return StreamBuilder<Users>(
|
||||
stream: MessagingProviders.instance.getUser(_auth.user!.$id),
|
||||
builder: (_, _snapshot) {
|
||||
var _userData = _snapshot.data;
|
||||
return _snapshot.hasData
|
||||
? Align(
|
||||
child: SizedBox(
|
||||
height: _deviceHeight * 0.50,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_userImageWidget(_userData!.image),
|
||||
_userNameWidget(_userData.name),
|
||||
_userEmailWidget(_userData.email),
|
||||
_logoutButton(),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
: SpinKitWanderingCubes(
|
||||
color: Colors.blue,
|
||||
size: 50.0,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Widget _userImageWidget(String _image) {
|
||||
double _imageRadius = _deviceHeight * 0.20;
|
||||
return Container(
|
||||
height: _imageRadius,
|
||||
width: _imageRadius,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(_imageRadius),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.fill,
|
||||
image: NetworkImage(_image),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _userNameWidget(String _name) {
|
||||
return Container(
|
||||
height: _deviceHeight * 0.05,
|
||||
width: _deviceWidth,
|
||||
child: Text(
|
||||
_name,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _userEmailWidget(String _email) {
|
||||
return Container(
|
||||
height: _deviceHeight * 0.03,
|
||||
width: _deviceWidth,
|
||||
child: Text(
|
||||
_email,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white24,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _logoutButton() {
|
||||
return Container(
|
||||
height: _deviceHeight * 0.06,
|
||||
width: _deviceWidth * 0.80,
|
||||
child: MaterialButton(
|
||||
onPressed: () {
|
||||
_auth.logout();
|
||||
},
|
||||
color: Colors.red,
|
||||
child: Text(
|
||||
"Logout".toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
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),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -224,7 +224,6 @@ class _RegisterationPageState extends State<RegisterationPage> {
|
||||
width: _deviceWidth,
|
||||
child: MaterialButton(
|
||||
onPressed: () {
|
||||
String name = _name!;
|
||||
if (_image == null) {
|
||||
SnackBarService.instance
|
||||
.showSnackBarError("Please Select Image");
|
||||
@@ -234,12 +233,12 @@ class _RegisterationPageState extends State<RegisterationPage> {
|
||||
_auth.createUser(
|
||||
_email!,
|
||||
_password!,
|
||||
name,
|
||||
_name!,
|
||||
(String _uid) async {
|
||||
var _url = await _auth.uploadUserImage(_image, _uid);
|
||||
_auth.createUserInDB(_uid, _email!, name, _url);
|
||||
_auth.createUserInDB(_uid, _email!, _name!, _url);
|
||||
if (_auth.status == AuthStatus.authenticated) {
|
||||
_auth.loginWithEmailAndPassword(_email!, _password!);
|
||||
_auth.login(_email!, _password!);
|
||||
}
|
||||
//
|
||||
},
|
||||
@@ -248,7 +247,7 @@ class _RegisterationPageState extends State<RegisterationPage> {
|
||||
},
|
||||
color: Colors.blue,
|
||||
child: Text(
|
||||
'Register',
|
||||
'Register'.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
|
||||
@@ -23,7 +23,7 @@ class NavigationService {
|
||||
}
|
||||
|
||||
// Manually Call Function
|
||||
goBack() {
|
||||
void goBack() {
|
||||
return navigatorKey!.currentState!.pop();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-26
@@ -1,54 +1,31 @@
|
||||
name: messaging_app
|
||||
description: "A new Flutter project."
|
||||
# The following line prevents the package from being accidentally published to
|
||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
# followed by an optional build number separated by a +.
|
||||
# Both the version and the builder number may be overridden in flutter
|
||||
# build by specifying --build-name and --build-number, respectively.
|
||||
# In Android, build-name is used as versionName while build-number used as versionCode.
|
||||
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
publish_to: 'none'
|
||||
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.6.0
|
||||
|
||||
# Dependencies specify other packages that your package needs in order to work.
|
||||
# To automatically upgrade your package dependencies to the latest versions
|
||||
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
||||
# dependencies can be manually updated by changing the version numbers below to
|
||||
# the latest version available on pub.dev. To see which dependencies have newer
|
||||
# versions available, run `flutter pub outdated`.
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.8
|
||||
appwrite: 13.1.1
|
||||
timeago: ^3.7.0
|
||||
flutter_spinkit: ^5.2.1
|
||||
provider: ^6.1.2
|
||||
image_picker: ^1.1.2
|
||||
timeago: ^3.7.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
|
||||
flutter_lints: ^5.0.0
|
||||
|
||||
flutter:
|
||||
|
||||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
|
||||
Reference in New Issue
Block a user