Skip to content

Commit

Permalink
Add quick access to models settings in chat page
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamKarolDiCioccio committed Sep 18, 2024
1 parent 4b5a4ec commit 07d4c2d
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 78 deletions.
30 changes: 22 additions & 8 deletions app/lib/frontend/dialogs/model_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,34 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:gap/gap.dart';
import 'package:open_local_ui/backend/private/models/model.dart';
import 'package:open_local_ui/backend/private/providers/model.dart';
import 'package:open_local_ui/backend/private/providers/model_settings.dart';
import 'package:provider/provider.dart';
import 'package:unicons/unicons.dart';

class ModelSettingsDialog extends StatefulWidget {
final Model model;
final String modelName;

const ModelSettingsDialog({super.key, required this.model});
const ModelSettingsDialog({super.key, required this.modelName});

@override
ModelSettingsDialogState createState() => ModelSettingsDialogState();
}

class ModelSettingsDialogState extends State<ModelSettingsDialog> {
late Model _model;
late ModelSettings _settings;
final TextEditingController _controller = TextEditingController();

@override
void initState() {
_model = context.read<ModelProvider>().models.firstWhere(
(model) => model.name == widget.modelName,
);

super.initState();
}

@override
void dispose() {
_controller.dispose();
Expand All @@ -33,14 +44,14 @@ class ModelSettingsDialogState extends State<ModelSettingsDialog> {
Widget build(BuildContext context) {
late String modelName;

if (widget.model.name.length > 20) {
modelName = '${widget.model.name.substring(0, 20)}...';
if (_model.name.length > 20) {
modelName = '${_model.name.substring(0, 20)}...';
} else {
modelName = widget.model.name;
modelName = _model.name;
}

return ChangeNotifierProvider(
create: (context) => ModelSettingsProvider(widget.model.name),
create: (context) => ModelSettingsProvider(_model.name),
builder: (context, _) => AlertDialog(
title: Text(
AppLocalizations.of(context)
Expand Down Expand Up @@ -346,11 +357,14 @@ class ModelSettingsDialogState extends State<ModelSettingsDialog> {
}
}

Future<void> showModelSettingsDialog(Model model, BuildContext context) async {
Future<void> showModelSettingsDialog(
String modelName,
BuildContext context,
) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return ModelSettingsDialog(model: model);
return ModelSettingsDialog(modelName: modelName);
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion app/lib/frontend/pages/dashboard/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ class _ModelListTileState extends State<ModelListTile> {
AppLocalizations.of(context).snackBarWarningTitle,
AppLocalizations.of(context).enteringCriticalSectionSnackBar,
SnackbarContentType.warning,
onTap: () => showModelSettingsDialog(widget.model, context),
onTap: () => showModelSettingsDialog(widget.model.name, context),
),
),
const Gap(8),
Expand Down
147 changes: 78 additions & 69 deletions app/lib/frontend/widgets/chat_toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:gap/gap.dart';
import 'package:open_local_ui/backend/private/providers/chat.dart';
import 'package:open_local_ui/backend/private/providers/model.dart';
import 'package:open_local_ui/core/snackbar.dart';
import 'package:open_local_ui/frontend/dialogs/model_settings.dart';
import 'package:provider/provider.dart';
import 'package:unicons/unicons.dart';

Expand Down Expand Up @@ -43,35 +44,56 @@ class _ChatToolbarWidgetState extends State<ChatToolbarWidget> {
}
}

@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const ChatModelSelectionWidget(),
const Gap(16),
// const ChatOptionBarWidget(),
// const Gap(16),
ElevatedButton.icon(
label: Text(
AppLocalizations.of(context).chatToolbarNewSessionButton,
style: const TextStyle(fontSize: 18.0),
Widget _buildModelSelectionWidget(BuildContext context) {
final List<DropdownMenuEntry> modelsMenuEntries = [];

for (final model in context.read<ModelProvider>().models) {
late String modelName;

if (model.name.length > 20) {
modelName = '${model.name.substring(0, 20)}...';
} else {
modelName = model.name;
}

modelsMenuEntries.add(
DropdownMenuEntry(
value: model.name,
label: modelName,
),
);
}

return DropdownMenu(
key: const Key('model_selector'),
enabled: context.watch<ModelProvider>().modelsCount > 0 &&
!context.watch<ChatProvider>().isGenerating,
menuHeight: 128,
menuStyle: MenuStyle(
elevation: WidgetStateProperty.all(
8.0,
),
shape: WidgetStateProperty.all(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
),
icon: const Icon(UniconsLine.plus),
onPressed: !context.watch<ChatProvider>().isGenerating
? () => _newSession()
: null,
),
],
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0),
),
),
enableSearch: true,
hintText: AppLocalizations.of(context).chatToolbarModelSelectorHint,
initialSelection: context.watch<ChatProvider>().modelName,
dropdownMenuEntries: modelsMenuEntries,
onSelected: (value) => context.read<ChatProvider>().setModel(value ?? ''),
);
}
}

class ChatOptionBarWidget extends StatelessWidget {
const ChatOptionBarWidget({super.key});

@override
Widget build(BuildContext context) {
// ignore: unused_element
Widget _buildChatOptionBarWidget(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(
Expand Down Expand Up @@ -115,56 +137,43 @@ class ChatOptionBarWidget extends StatelessWidget {
),
);
}
}

class ChatModelSelectionWidget extends StatelessWidget {
const ChatModelSelectionWidget({super.key});

@override
Widget build(BuildContext context) {
final List<DropdownMenuEntry> modelsMenuEntries = [];

for (final model in context.read<ModelProvider>().models) {
late String modelName;

if (model.name.length > 20) {
modelName = '${model.name.substring(0, 20)}...';
} else {
modelName = model.name;
}

modelsMenuEntries.add(
DropdownMenuEntry(
value: model.name,
label: modelName,
),
);
}

return DropdownMenu(
enabled: context.watch<ModelProvider>().modelsCount > 0 &&
!context.watch<ChatProvider>().isGenerating,
menuHeight: 128,
menuStyle: MenuStyle(
elevation: WidgetStateProperty.all(
8.0,
),
shape: WidgetStateProperty.all(
const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16.0)),
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (context.read<ChatProvider>().modelName.isNotEmpty)
IconButton(
tooltip: AppLocalizations.of(context).modelsPageSettingsButton,
icon: const Icon(UniconsLine.setting),
onPressed: () => SnackBarHelpers.showSnackBar(
AppLocalizations.of(context).snackBarWarningTitle,
AppLocalizations.of(context).enteringCriticalSectionSnackBar,
SnackbarContentType.warning,
onTap: () => showModelSettingsDialog(
context.read<ChatProvider>().modelName,
context,
),
),
),
if (context.read<ChatProvider>().modelName.isNotEmpty) const Gap(16),
_buildModelSelectionWidget(context),
const Gap(16),
// _buildChatOptionBarWidget(context),
// const Gap(16),
ElevatedButton.icon(
key: const Key('new_session_button'),
label: Text(
AppLocalizations.of(context).chatToolbarNewSessionButton,
style: const TextStyle(fontSize: 18.0),
),
icon: const Icon(UniconsLine.plus),
onPressed: !context.watch<ChatProvider>().isGenerating
? () => _newSession()
: null,
),
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16.0),
),
),
enableSearch: true,
hintText: AppLocalizations.of(context).chatToolbarModelSelectorHint,
initialSelection: context.watch<ChatProvider>().modelName,
dropdownMenuEntries: modelsMenuEntries,
onSelected: (value) => context.read<ChatProvider>().setModel(value ?? ''),
],
);
}
}

0 comments on commit 07d4c2d

Please sign in to comment.