@@ -739,6 +739,7 @@ class _SelectModelButtonState extends State<SelectModelButton> {
739739 );
740740 },
741741 child: _CurrentModelButton (
742+ key: ValueKey (state.availableModels? .selectedModel.name),
742743 modelName: state.availableModels? .selectedModel.name ?? "" ,
743744 onTap: () => popoverController.show (),
744745 ),
@@ -760,29 +761,94 @@ class _PopoverSelectModel extends StatelessWidget {
760761 Widget build (BuildContext context) {
761762 return BlocBuilder <SelectModelBloc , SelectModelState >(
762763 builder: (context, state) {
763- return ListView .builder (
764- shrinkWrap: true ,
765- itemCount: state.availableModels? .models.length ?? 0 ,
764+ if (state.availableModels == null ||
765+ state.availableModels! .models.isEmpty) {
766+ return const SizedBox .shrink ();
767+ }
768+
769+ // Separate models into local and cloud models
770+ final localModels = state.availableModels! .models
771+ .where ((model) => model.isLocal)
772+ .toList ();
773+
774+ final cloudModels = state.availableModels! .models
775+ .where ((model) => ! model.isLocal)
776+ .toList ();
777+
778+ return Padding (
766779 padding: const EdgeInsets .fromLTRB (8 , 4 , 8 , 12 ),
767- itemBuilder: (context, index) {
768- return _ModelItem (
769- model: state.availableModels! .models[index],
770- onTap: () {
771- context.read <SelectModelBloc >().add (
772- SelectModelEvent .selectModel (
773- state.availableModels! .models[index],
774- ),
775- );
776- onClose ();
777- },
778- );
779- },
780+ child: Column (
781+ mainAxisSize: MainAxisSize .min,
782+ crossAxisAlignment: CrossAxisAlignment .start,
783+ children: [
784+ // Local AI Models Section
785+ if (localModels.isNotEmpty) ...[
786+ _ModelSectionHeader (
787+ title: LocaleKeys .chat_changeFormat_localModel.tr (),
788+ ),
789+ const SizedBox (height: 4 ),
790+ ...localModels.map (
791+ (model) => _ModelItem (
792+ model: model,
793+ onTap: () {
794+ context.read <SelectModelBloc >().add (
795+ SelectModelEvent .selectModel (model),
796+ );
797+ onClose ();
798+ },
799+ ),
800+ ),
801+ const SizedBox (height: 8 ),
802+ ],
803+
804+ // Cloud AI Models Section
805+ if (cloudModels.isNotEmpty) ...[
806+ if (localModels.isNotEmpty)
807+ _ModelSectionHeader (
808+ title: LocaleKeys .chat_changeFormat_cloudModel.tr (),
809+ ),
810+ const VSpace (4 ),
811+ ...cloudModels.map (
812+ (model) => _ModelItem (
813+ model: model,
814+ onTap: () {
815+ context.read <SelectModelBloc >().add (
816+ SelectModelEvent .selectModel (model),
817+ );
818+ onClose ();
819+ },
820+ ),
821+ ),
822+ ],
823+ ],
824+ ),
780825 );
781826 },
782827 );
783828 }
784829}
785830
831+ class _ModelSectionHeader extends StatelessWidget {
832+ const _ModelSectionHeader ({
833+ required this .title,
834+ });
835+
836+ final String title;
837+
838+ @override
839+ Widget build (BuildContext context) {
840+ return Padding (
841+ padding: const EdgeInsets .only (top: 4 , bottom: 2 ),
842+ child: FlowyText (
843+ title,
844+ fontSize: 12 ,
845+ color: Theme .of (context).hintColor,
846+ fontWeight: FontWeight .w500,
847+ ),
848+ );
849+ }
850+ }
851+
786852class _ModelItem extends StatelessWidget {
787853 const _ModelItem ({
788854 required this .model,
@@ -794,10 +860,8 @@ class _ModelItem extends StatelessWidget {
794860
795861 @override
796862 Widget build (BuildContext context) {
797- var modelName = model.name;
798- if (model.isLocal) {
799- modelName += " (${LocaleKeys .chat_changeFormat_localModel .tr ()})" ;
800- }
863+ final modelName = model.name;
864+
801865 return FlowyTextButton (
802866 modelName,
803867 fillColor: Colors .transparent,
@@ -810,6 +874,7 @@ class _CurrentModelButton extends StatelessWidget {
810874 const _CurrentModelButton ({
811875 required this .modelName,
812876 required this .onTap,
877+ super .key,
813878 });
814879
815880 final String modelName;
0 commit comments