From 58803d82500a66c5274252815990682331fb8690 Mon Sep 17 00:00:00 2001 From: Nishchal Siddharth Pandey Date: Sun, 18 Oct 2020 14:04:25 +0530 Subject: [PATCH] Create community done. Registration time username regex check fixed. Signed-off-by: Nishchal Siddharth Pandey --- lib/app_screens/create_community.dart | 261 ++++++++++++++++++++++---- lib/app_screens/create_post.dart | 3 + lib/authentication/register.dart | 45 ++--- 3 files changed, 246 insertions(+), 63 deletions(-) diff --git a/lib/app_screens/create_community.dart b/lib/app_screens/create_community.dart index d5041f2..5e5cb7e 100755 --- a/lib/app_screens/create_community.dart +++ b/lib/app_screens/create_community.dart @@ -1,6 +1,10 @@ +import 'dart:io'; + import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_storage/firebase_storage.dart'; import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; class CreateGroup extends StatefulWidget { @override @@ -16,6 +20,10 @@ class _CreateGroupState extends State { int _radioVisibility = 0; int _radioPosts = 0; int _radioVerification = 0; + final GlobalKey _scaffoldKey = GlobalKey(); + String noticeText = "Add Cover Photo"; + int mediaType = 0; // 0 for none, 1 for image, 2 for video + File media; void _handleRadioValueChange1(int value) { setState(() { @@ -48,6 +56,7 @@ class _CreateGroupState extends State { @override Widget build(BuildContext context) { return Scaffold( + key: _scaffoldKey, appBar: AppBar( title: Text( 'Create Community', @@ -105,24 +114,53 @@ class _CreateGroupState extends State { style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), - FlatButton( - child: Row( - children: [ - Icon( - Icons.add_box, - size: 24, - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Text( - 'Add Cover Photo', - style: TextStyle(fontSize: 18), + mediaType == 0 + ? FlatButton( + child: Row( + children: [ + Icon( + Icons.add_box, + size: 24, + ), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: Text( + noticeText, + style: TextStyle(fontSize: 18), + ), + ) + ], ), + onPressed: () { + _showImagePicker(context); + }, ) - ], - ), - onPressed: () {}, - ), + : Row( + children: [ + SizedBox( + width: 15, + ), + Text( + '$noticeText', + style: TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.bold, + ), + ), + Spacer(), + IconButton( + icon: Icon(Icons.cancel), + onPressed: () { + setState(() { + noticeText = "Add Cover Photo"; + mediaType = 0; + photoUrl = null; + media = null; + }); + }, + ) + ], + ), Padding( padding: EdgeInsets.all(8.0), child: Container( @@ -380,31 +418,180 @@ class _CreateGroupState extends State { ); } - createCommunity() { - username = FirebaseAuth.instance.currentUser.displayName; + createCommunity() async { String commName = nameController.text; - String about = aboutController.text; - int time = DateTime.now().millisecondsSinceEpoch; - List nameSearchList = List(); - String temp = ""; - for (int i = 0; i < commName.length; i++) { - temp = temp + commName[i]; - nameSearchList.add(temp); + if (commName.isEmpty || RegExp("[^a-z^A-Z^0-9]+").hasMatch(commName) || commName.length < 3 || commName.length > 25) { + await showAlertDialog(context); + return; + } + _scaffoldKey.currentState.showSnackBar(SnackBar( + behavior: SnackBarBehavior.floating, + duration: Duration(hours: 1), + content: Row( + children: [ + CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(Colors.grey), + ), + SizedBox( + width: 15, + ), + Text("Uploading...") + ], + ), + )); + try { + username = FirebaseAuth.instance.currentUser.displayName; + FirebaseFirestore instance = FirebaseFirestore.instance; + + final snapShot = + await instance.collection('communities').doc(commName).get(); + if (snapShot != null && snapShot.exists) { + _scaffoldKey.currentState.hideCurrentSnackBar(); + print("Failed, community name exists."); + _scaffoldKey.currentState.showSnackBar(SnackBar( + behavior: SnackBarBehavior.floating, + content: Text('Community name already exists. Try different.'), + )); + return; + } + + String about = aboutController.text; + int time = DateTime.now().millisecondsSinceEpoch; + + if (mediaType == 1) await uploadMedia(commName); + + List nameSearchList = List(); + String temp = ""; + for (int i = 0; i < commName.length; i++) { + temp = temp + commName[i]; + nameSearchList.add(temp); + } + + instance.collection('communities').doc(commName).set({ + 'name': commName, + 'about': about, + 'photoUrl': photoUrl, + 'privacy': _radioPrivacy, + 'visibility': _radioVisibility, + 'posts': _radioPosts, + 'verification': _radioVerification, + 'nameSearch': nameSearchList, + 'creationTime': time, + }); + + instance.collection('communities/$commName/admins').doc(username).set({}); + + _scaffoldKey.currentState.hideCurrentSnackBar(); + _scaffoldKey.currentState.showSnackBar(SnackBar( + behavior: SnackBarBehavior.floating, + content: Text('Community creation done.'), + )); + } catch (e) { + print(e.toString()); + _scaffoldKey.currentState.hideCurrentSnackBar(); + _scaffoldKey.currentState.showSnackBar(SnackBar( + behavior: SnackBarBehavior.floating, + content: Text('Community creation failed.'), + )); } + } - FirebaseFirestore instance = FirebaseFirestore.instance; - instance.collection('communities').doc(commName).set({ - 'name': commName, - 'about': about, - 'photoUrl': photoUrl, - 'privacy': _radioPrivacy, - 'visibility': _radioVisibility, - 'posts': _radioPosts, - 'verification': _radioVerification, - 'nameSearch': nameSearchList, - 'creationTime': time, + _showImagePicker(context) { + showModalBottomSheet( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)), + ), + context: context, + builder: (BuildContext bc) { + return SafeArea( + child: Container( + child: Wrap( + children: [ + ListTile( + leading: Icon(Icons.photo_library), + title: Text('From Gallery'), + onTap: () { + _imageFromGallery(); + Navigator.of(context).pop(); + }, + ), + ListTile( + leading: Icon(Icons.photo_camera), + title: Text('Camera'), + onTap: () { + _imageFromCamera(); + Navigator.of(context).pop(); + }, + ), + ], + ))); + }); + } + + _imageFromGallery() async { + final file = await ImagePicker().getImage( + source: ImageSource.gallery, + maxHeight: 1024, + maxWidth: 1024, + imageQuality: 90); + if (file == null) return null; + media = File(file.path); + setState(() { + noticeText = "Image selected for upload!"; + mediaType = 1; }); + } - instance.collection('communities/$commName/admins').doc(username).set({}); + _imageFromCamera() async { + final file = await ImagePicker().getImage( + source: ImageSource.camera, + maxHeight: 1024, + maxWidth: 1024, + imageQuality: 90); + if (file == null) return null; + media = File(file.path); + setState(() { + noticeText = "Image selected for upload!"; + mediaType = 1; + }); + } + + uploadMedia(String key) async { + StorageUploadTask uploadTask; + if (mediaType == 1) + uploadTask = FirebaseStorage.instance + .ref() + .child('coverPhotos/$key.jpg') + .putFile(media); + StorageTaskSnapshot storageSnap = await uploadTask.onComplete; + photoUrl = await storageSnap.ref.getDownloadURL(); + debugPrint("Successful media upload!"); + return photoUrl; + } + + showAlertDialog(BuildContext context) async { + Widget okButton = FlatButton( + child: Text("OK"), + onPressed: () { + Navigator.of(context).pop(); + }, + ); + + // set up the AlertDialog + AlertDialog alert = AlertDialog( + title: Text("Community name should be alphanumeric"), + content: Text("No special characters or spaces allowed. Length should be between 3 and 25 (inclusive)"), + actions: [ + okButton, + ], + ); + + // show the dialog + await showDialog( + context: context, + builder: (BuildContext context) { + return alert; + }, + ); } } diff --git a/lib/app_screens/create_post.dart b/lib/app_screens/create_post.dart index bf081fc..1e22b92 100755 --- a/lib/app_screens/create_post.dart +++ b/lib/app_screens/create_post.dart @@ -390,6 +390,9 @@ class _CreatePostState extends State { _showImagePicker(context) { showModalBottomSheet( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)), + ), context: context, builder: (BuildContext bc) { return SafeArea( diff --git a/lib/authentication/register.dart b/lib/authentication/register.dart index 08f22c9..6620d8d 100755 --- a/lib/authentication/register.dart +++ b/lib/authentication/register.dart @@ -148,8 +148,7 @@ class _RegisterState extends State { ), validator: (value) { if (value.isEmpty || - !RegExp( - r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") + !RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") .hasMatch(value)) return 'Enter valid email'; return null; }, @@ -185,9 +184,7 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), validator: (value) { @@ -213,14 +210,12 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), validator: (value) { if (value.isEmpty || - value.contains('[^A-Za-z0-9]') || + RegExp("[^a-z^A-Z^0-9]+").hasMatch(value) || value.length < 3 || value.length > 20) return 'Enter valid username of length atleast 3 and atmost 20'; @@ -242,9 +237,7 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), ), @@ -263,9 +256,7 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), ), @@ -284,9 +275,7 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), ), @@ -305,9 +294,7 @@ class _RegisterState extends State { border: OutlineInputBorder(), focusedBorder: OutlineInputBorder( borderSide: - BorderSide(color: Theme - .of(context) - .buttonColor), + BorderSide(color: Theme.of(context).buttonColor), ), ), ), @@ -354,7 +341,7 @@ class _RegisterState extends State { try { FirebaseFirestore instance = FirebaseFirestore.instance; final snapShot = - await instance.collection('users').doc(_usernameText.text).get(); + await instance.collection('users').doc(_usernameText.text).get(); if (snapShot != null && snapShot.exists) { _scaffoldKey.currentState.hideCurrentSnackBar(); print("Failed, username exists."); @@ -371,9 +358,15 @@ class _RegisterState extends State { password: _passwordController.text, )) .user; - await DatabaseService(uid: user.uid).updateUserData(_emailController.text, - _displayName.text, _usernameText.text, url, _mottoText.text,_websiteText.text,_hometownText.text, - _currentCityText.text); + await DatabaseService(uid: user.uid).updateUserData( + _emailController.text, + _displayName.text, + _usernameText.text, + url, + _mottoText.text, + _websiteText.text, + _hometownText.text, + _currentCityText.text); if (user != null) { if (!user.emailVerified) await user.sendEmailVerification(); @@ -403,7 +396,7 @@ class _RegisterState extends State { _scaffoldKey.currentState.showSnackBar(SnackBar( behavior: SnackBarBehavior.floating, content: - Text('Registration failed. Email ID or username already exists!'), + Text('Registration failed. Email ID or username already exists!'), )); } }