how could I place a conditional for next action - flutter

I would like to condition the sign out action depending If I have already or not sign in. I just tried with an "If" before everything but it show a "expected identifier" and "expected )". I would like to learn abut this part
I tried with an "If" conditional before PopUp menu.
appBar: AppBar(
title: Text("Categoria"),
backgroundColor: Color.fromARGB(150, 255, 0, 0),
actions: [
if (FirebaseAuth.instance.signInWithEmailAndPassword(email: "usu", password: "cla")==true){
PopupMenuButton(
onSelected: (Menu item) {
setState(() {
if (item == Menu.logout) {
FirebaseAuth.instance.signOut();
Navigator.push(context, MaterialPageRoute(
builder: (context) => Login()));
}
});
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<Menu>>[
PopupMenuItem(value: Menu.logout,
child: Text("Cerrar sesión")
)
],
)
}
],
Here is the upgrated code after ur advices

You can check the current auth state:
FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});

put the above the line of PopupMenuButton
title: Text("Categoria"),
backgroundColor: Color.fromARGB(150, 255, 0, 0),
actions: [
if (FirebaseAuth.instance.signInWithEmailAndPassword(email: "usu" password: "cla"))
PopupMenuButton(
onSelected: (Menu item) {
setState(() {
if (item == Menu.logout) {
FirebaseAuth.instance.signOut();
Navigator.push(context, MaterialPageRoute(
builder: (context) => Login()));
}
});
},
itemBuilder: (BuildContext context) =>
<PopupMenuEntry<Menu>>[
PopupMenuItem(value: Menu.logout,
child: Text("Cerrar sesión")
)
],
)
],
),
you can use if clause only like that after return part:
return Column(
children: [
if(condition == true) // or you just can write condition
Text('true')
]
)
or you can use ? and :
return Container(
child:
condition == true // or you just can write condition
? Text('true')
: Text('false')
)

Related

Provider function called but no change notified

I have a widget in my settings screen something like this:
Widget autoplay()
{
return ChangeNotifierProvider<AutoplayToggle>(
create: (context) => AutoplayToggle(),
child: Consumer<AutoplayToggle>(
builder: (context, provider, child) {
return Container(
color: provider.isPause ? accent : primary,
width: 45,
child: Switch.adaptive(
value: isPause,
onChanged: (value) async {
setState(() {
isPause= value;
});
await UserPrefs.setAutoplay(isPause);
provider.toggleAutoplay();
},
),
);
},
),
),
}
and this is my class:
class AutoplayToggle with ChangeNotifier{
bool isPause = false;
void toggleAutoplay()
{
isPause = !isPause;
print(isPause);
notifyListeners();
}
}
I printed couple of statements to debug and every time I toggle the switch the function is being called as the values will change from false to true, however, it is not notifying the change. Any idea on whats going wrong?
can you try add "lazy" : false to ChangeNotifierProvider ?
Don't use setState in onChange method
return ChangeNotifierProvider<AutoplayToggle>(
create: (context) => AutoplayToggle(),
child: Consumer<AutoplayToggle>(
builder: (context, provider, child) {
return Container(
color: provider.isPause ? accent : primary,
width: 45,
child: Switch.adaptive(
value: provider.isPause,
onChanged: (value) async {
await UserPrefs.setAutoplay(isPause);
provider.toggleAutoplay();
},
),
);
},
),
);

Flutter) Dialog TextButton's function is executed automatically without tab the button

Hi I'm newbie at coding and Flutter is my first language.
I want to delete Firestore data(Chat List) which is in the ListView from the StreamBuilder when user long tab the 'OK' button in AlertDialog.
(Process Summary:
longPress one item of the ListViewBuilder
show check AlertDialog
tab 'OK'
OK button's Function execute)
But when i longPress the item, then the deleteFunction(OK button's function) is automatically executed before i see the dialog.
How can I make it?
It is really difficult!
Here is my code
StreamBuilder(
stream: chatRoomDB,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.active &&
snapshot.data != null) {
return ListView(
children: snapshot.data!.docs
.map<Widget>((DocumentSnapshot ds) {
Map<String, dynamic> data =
ds.data()! as Map<String, dynamic>;
receiverProfileImageURL = data['ProfileImageURL'];
receiverUID = data['UserID'];
receiverNickName = data['NickName'];
msgContent = data['MsgContent'];
chatID = data['ChatID'];
return Container(
margin: EdgeInsets.all(3),
child: ListTile(
shape: Border(
bottom:
BorderSide(color: Colors.grey, width: 1)),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChattingRoom(
chatID: data['ChatID'],
receiverUID: data['UserID'],
receiverImageURL:
data['ProfileImageURL'],
receiverNickName: data['NickName'],
)));
},
onLongPress: () => checkDialog2(
context: context,
msg: 'Delete?',
okButtonString: 'OK',
okFunction: chatDBDeleteFunction(
data['UserID'], data['ChatID']),
noButtonString: 'No'),
leading: Container(
child: CircleAvatar(
foregroundImage: NetworkImage(
'$receiverProfileImageURL',
),
backgroundImage:
NetworkImage('$errorImageURL'),
)),
title: Text('$receiverNickName'),
),
);
}).toList());
}
return Container();
})
checkDialog2({
required context,
required String? msg,
required String? okButtonString,
required Future<dynamic> okFunction,
required String? noButtonString,
}) {
print(1);
okFunctions(okFunc) {
print(3);
okFunction;
Navigator.pop(context);
print(4);
}
print(5);
showDialog(
context: context,
builder: (context) {
print(2);
return AlertDialog(content: Text('$msg'), actions: <Widget>[
TextButton(
onPressed: () => okFunctions(okFunction),
child: Text(
'$okButtonString',
textAlign: TextAlign.end,
),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text(
'$noButtonString',
textAlign: TextAlign.end,
),
),
]);
});
}
Future chatDBDeleteFunction(receiverUID, chatID) async {
await FirebaseFirestore.instance
.collection('ChatMessage')
.doc('${FirebaseAuth.instance.currentUser?.uid}')
.collection(chatID)
.get()
.then((QuerySnapshot qs) => {
qs.docs.forEach((DocumentSnapshot snapshot) {
snapshot.reference.delete();
})
});
Log Order is,
print 1->5>2 and automatically deleted + showDialog.
At that time(list item already disappeared), if i tab the 'OK' button, then print '3' and error(because there is nothing to delete)
(ps. although i change the okfunction to the void Function, it starts automatically. same)
Thanks for your help
I would prefer passing the UserId and ChatId and then call the chatDBDeleteFunction(receiverUID, chatID) Function and pass the values from values
TextButton(
onPressed: () {
Class.chatDBDeleteFunction(receiverUID, chatID)
}
)
The chatDBDeleteFunction(receiverUID, chatID) function can be static

showDialog always returns null

I try to build cusom confirmation dialog. I tried many different options, but none of them worked for me as it should
Now I have stopped at this one:
Future<bool?> showConfirmationDialog(BuildContext context, String action, {String title = 'Confirmation'}) {
bool result = false;
var confirmDialog = AlertDialog(
title: Text(title),
content: SizedBox(
height: 50,
child: Text(
action,
),
),
actions: [
TextButton(
child: const Text("OK"),
onPressed: () {
Navigator.pop(context, true);
},
),
TextButton(
child: const Text("Cancel"),
onPressed: () {
Navigator.of(context).pop(false);
},
)
],
);
return showDialog<bool>(
context: context,
builder: (BuildContext context) {
return confirmDialog;
},
);
}
but I always get null in result:
confirmDismiss: (DismissDirection direction) async {
var result = await showConfirmationDialog(context, 'Are you sure?');
// here result is null always
if (result == true){
print('yes');
return true;
}
else if(result == false){
print('no');
return false;
}
}
How to make a confirmation dialog box in flutter correctly?

Flutter : how to conditionally repeat a showDialog inside a ListView

I am using the flutter_reactive_ble_example to connect to my Bluetooth module by modifying the file device_list.dart.
and I wonder how do I re prompt the user if password is wrong.
I'm fairly new to flutter, please do ask more details if required.
here is the code snippet that I currently have:
Flexible(
child: ListView(
children: widget.scannerState.discoveredDevices
.map(
(device) => ListTile(
title: Text(tile.name),
subtitle: Text("${tile.name}\n: ${tile.sub}"),
leading: const ConnectIcon(),
onTap: () async {
//stop the scan
widget.stopScan();
//connect to the device
await widget.deviceConn.connect(device.id);
//prompt user for password
final inputData = await showDialog(
context: context,
barrierDismissible:
false, // prevent user from closing the dialog by pressing outside the dialog
builder: (_) {
String userData = "";
return AlertDialog(
title: new Text("Enter Password"),
content: new TextField(
onChanged: (value) {
userData = value;
},
),
actions: <Widget>[
ElevatedButton(
child: Text('Ok'),
onPressed: () async {
//on press subscribe and send the password
response = await ble.subscribeToCharacteristic(characteristic);
//if data failure check, how do I reshow this showDialog??
response.listen((event) {
if(event == 1){
//if return 1, password correct
Navigator.of(context).pop(userData);
}else{
//if not reshow Dialog
//howw?
}
}
//send password
ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
},
)
],
);
},
);
Navigator.of(context).pop(
inputData); // pass data back to the previous page
},
),
)
.toList(),
),
),
You can use a recursion I think, here an example
Future _showPasswordDialog(){
return showDialog(
context: context,
barrierDismissible:
false, // prevent user from closing the dialog by pressing outside the dialog
builder: (_) {
String userData = "";
return AlertDialog(
title: new Text("Enter Password"),
content: new TextField(
onChanged: (value) {
userData = value;
},
),
actions: <Widget>[
ElevatedButton(
child: Text('Ok'),
onPressed: () async {
//on press subscribe and send the password
response = await ble.subscribeToCharacteristic(characteristic);
//if data failure check, how do I reshow this showDialog??
response.listen((event) {
if(event == 1){
//if return 1, password correct
Navigator.of(context).pop(userData);
}else{
//if not reshow Dialog
//howw?
Navigator.of(context).pop();
_showPasswordDialog();
}
}
//send password
ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
},
)
],
);
},
);
}
separate the the alert prompting as another function, and return user details if login success else return null.
Future<String> promptAlert(BuildContext context){
return showDialog(
context: context,
barrierDismissible:
false, // prevent user from closing the dialog by pressing outside the dialog
builder: (_) {
String userData = "";
return AlertDialog(
title: new Text("Enter Password"),
content: new TextField(
onChanged: (value) {
userData = value;
},
),
actions: <Widget>[
ElevatedButton(
child: Text('Ok'),
onPressed: () async {
//on press subscribe and send the password
response = await ble.subscribeToCharacteristic(characteristic);
//if data failure check, how do I reshow this showDialog??
response.listen((event) {
if(event == 1){
//if return 1, password correct
Navigator.of(context).pop(userData);
}else{
Navigator.of(context).pop();
}
}
//send password
ble.writeCharacteristicWithoutResponse(characteristic, value: userData);
},
)
],
);
},
);
}
and check for the returned value is not null on the ListItem onTap
bool isLogin = (await promptAlert(context)) !=null;
while(isLogin ){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: Duration(seconds: 2),
content: Text('Login Failed Try again')));
String user= await Future.delayed(
Duration(seconds: 2), () => promptAlert(context));
isLogin = user !=null;
}
If you want to show a snackbar and delayed alert,
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: Duration(seconds: 2),
content: Text('Login Failed Try again'),
));
Future.delayed(
Duration(seconds: 2), () => promptAlert(context));

How to refresh content View on Body after add or crud data in flutter?

I'm the newbie Flutter Developer. I got any problem when I tap the custom drawer, body content viewed the widget after that I tap add button with api and success created new data. but when back to drawer can't reload automatically. below are some of my codecs.
I user drawerbehavior version 0.0.8
MyCustomDrawer code
DrawerScaffold(
percentage: 1,
cornerRadius: 0,
appBar: AppBarProps(
title: Text(
"ToDO",
style: TextStyle(fontFamily: 'Acme'),
),
centerTitle: true,
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () => tambahAgenda(context, '4', true))
]),
menuView: new MenuView(
menu: menu,
headerView: headerView(context),
footerView: footerView(context),
animation: false,
textStyle: TextStyle(fontFamily: 'Acme', color: Colors.white),
color: Theme.of(context).primaryColor,
selectedItemId: selectedMenuItemId,
onMenuItemSelected: (String itemId) {
selectedMenuItemId = itemId;
if (itemId == 'beranda') {
setState(() => _widget = IsiBerandaUI());
} else if (itemId == 'agenda') {
setState(() => _widget = Container());
} else if (itemId == 'kalenderagenda') {
setState(() => _widget = AgendaCalendarUI());
}
},
),
contentView: Screen(
contentBuilder: (context) => Center(child: _widget),
color: Colors.white,
),
);
_navigateAndDisplaySelection(
BuildContext context, String idKategori, bool statusLogin) async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => TambahAgendaUI()),
);
if (result != null) {
// bloc.fetchAllAgendaTGL(idKategori, statusLogin);
setState(() {
selectedMenuItemId = 'kalenderagenda';
_widget = AgendaCalendarUI();
});
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => Beranda(
selectedMenuItemId: 'kalenderagenda',
)));
Scaffold.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(
content: Text(
"$result",
style: TextStyle(fontFamily: 'googleSans'),
)));
}
}
and myadd data navigator like this
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) => Beranda(
selectedMenuItemId: 'kalenderagenda',
)
)
);
But When I pushReplacement widget get any error.
any conclusion ???