mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2026-02-01 04:14:24 +01:00
Add ContinuousModeDialog and integrate with ChatInputField
- Introduced a new dialog, ContinuousModeDialog, to inform users about the repercussions of the continuous mode. - Integrated ContinuousModeDialog with ChatInputField. The dialog is shown when the fast-forward icon is clicked, based on the user's shared preferences. - Leveraged shared preferences to remember if the user has chosen not to see the dialog again. - Enhanced the ChatInputField to handle different states and user interactions related to continuous mode.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import 'package:auto_gpt_flutter_client/views/chat/continuous_mode_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class ChatInputField extends StatefulWidget {
|
||||
// Callback to be triggered when the send button is pressed
|
||||
@@ -38,6 +40,40 @@ class _ChatInputFieldState extends State<ChatInputField> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _presentContinuousModeDialogIfNeeded() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final showContinuousModeDialog =
|
||||
prefs.getBool('showContinuousModeDialog') ?? true;
|
||||
|
||||
if (showContinuousModeDialog) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return ContinuousModeDialog(
|
||||
onProceed: () {
|
||||
Navigator.of(context).pop();
|
||||
_executeContinuousMode();
|
||||
},
|
||||
onCheckboxChanged: (bool value) async {
|
||||
await prefs.setBool('showContinuousModeDialog', !value);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
_executeContinuousMode();
|
||||
}
|
||||
}
|
||||
|
||||
void _executeContinuousMode() {
|
||||
if (!widget.isContinuousMode) {
|
||||
widget.onSendPressed(_controller.text);
|
||||
_controller.clear();
|
||||
_focusNode.unfocus();
|
||||
}
|
||||
widget.onContinuousModePressed();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Using LayoutBuilder to provide the current constraints of the widget,
|
||||
@@ -93,7 +129,6 @@ class _ChatInputFieldState extends State<ChatInputField> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// TODO: Include pop up to explain continuous mode reprecussions
|
||||
Tooltip(
|
||||
message: widget.isContinuousMode
|
||||
? ''
|
||||
@@ -104,12 +139,12 @@ class _ChatInputFieldState extends State<ChatInputField> {
|
||||
? Icons.pause
|
||||
: Icons.fast_forward),
|
||||
onPressed: () {
|
||||
// TODO: All of this logic should be handled at a higher level in the widget tree. Temporary
|
||||
if (!widget.isContinuousMode) {
|
||||
widget.onSendPressed(_controller.text);
|
||||
_controller.clear();
|
||||
_focusNode.unfocus();
|
||||
_presentContinuousModeDialogIfNeeded();
|
||||
} else {
|
||||
widget.onContinuousModePressed();
|
||||
}
|
||||
widget.onContinuousModePressed();
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
168
frontend/lib/views/chat/continuous_mode_dialog.dart
Normal file
168
frontend/lib/views/chat/continuous_mode_dialog.dart
Normal file
@@ -0,0 +1,168 @@
|
||||
import 'package:auto_gpt_flutter_client/constants/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ContinuousModeDialog extends StatefulWidget {
|
||||
final VoidCallback? onProceed;
|
||||
final ValueChanged<bool>? onCheckboxChanged;
|
||||
|
||||
const ContinuousModeDialog({
|
||||
Key? key,
|
||||
this.onProceed,
|
||||
this.onCheckboxChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ContinuousModeDialogState createState() => _ContinuousModeDialogState();
|
||||
}
|
||||
|
||||
class _ContinuousModeDialogState extends State<ContinuousModeDialog> {
|
||||
bool _attemptedToDismiss = false;
|
||||
bool _checkboxValue = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
setState(() {
|
||||
_attemptedToDismiss = true;
|
||||
});
|
||||
return false;
|
||||
},
|
||||
child: Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
side: BorderSide(
|
||||
color: _attemptedToDismiss
|
||||
? AppColors.accentDeniedLight
|
||||
: Colors.transparent,
|
||||
width: 3.0,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
width: 260,
|
||||
height: 251,
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
// Black circle exclamation icon
|
||||
Icon(Icons.error_outline,
|
||||
color: _attemptedToDismiss
|
||||
? AppColors.accentDeniedLight
|
||||
: Colors.black),
|
||||
const SizedBox(height: 8),
|
||||
// Title
|
||||
const Text(
|
||||
'Continuous Mode',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontFamily: 'Archivo',
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
// Block of text
|
||||
const SizedBox(
|
||||
width: 220,
|
||||
child: Text(
|
||||
'Agents operating in Continuous Mode will perform Actions without requesting authorization from the user. Configure the number of steps in the settings menu.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 12.50,
|
||||
fontFamily: 'Archivo',
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Buttons
|
||||
const SizedBox(height: 14),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Cancel Button
|
||||
SizedBox(
|
||||
width: 106,
|
||||
height: 28,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.grey,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
child: const Text(
|
||||
'Cancel',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12.50,
|
||||
fontFamily: 'Archivo',
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
// Proceed Button
|
||||
SizedBox(
|
||||
width: 106,
|
||||
height: 28,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColors.primaryLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
),
|
||||
onPressed: widget.onProceed, // Use the provided callback
|
||||
child: const Text(
|
||||
'Proceed',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12.50,
|
||||
fontFamily: 'Archivo',
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 11),
|
||||
// Checkbox and text
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Checkbox(
|
||||
value: _checkboxValue,
|
||||
onChanged: (bool? newValue) {
|
||||
setState(() {
|
||||
_checkboxValue = newValue ?? false;
|
||||
});
|
||||
if (widget.onCheckboxChanged != null) {
|
||||
widget.onCheckboxChanged!(_checkboxValue);
|
||||
}
|
||||
},
|
||||
),
|
||||
const Text(
|
||||
"Don't ask again",
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 11,
|
||||
fontFamily: 'Archivo',
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user