import "package:flutter/material.dart"; import "package:provider/provider.dart"; import "../../src/api/openrouter_client.dart"; import "../providers/settings_provider.dart"; class ModelPicker extends StatefulWidget { const ModelPicker(); @override State createState() => _ModelPickerState(); } class _ModelPickerState extends State { late Future>> _modelsFuture; @override void initState() { super.initState(); _modelsFuture = _loadModels(); } Future>> _loadModels() async { try { final apiKey = context.read().settings.openRouterApiKey; if (apiKey == null || apiKey.isEmpty) { return [ {"id": "openai/gpt-4o", "name": "GPT-4o"}, {"id": "anthropic/claude-sonnet-4.6", "name": "Claude Sonnet 4.6"}, {"id": "google/gemini-2.0-flash-001", "name": "Gemini 2.0 Flash"}, ]; } final client = await OpenRouterClientFactory.create(apiKey: apiKey); final models = await client.listModels(); client.close(); return models; } catch (e) { return [ {"id": "openai/gpt-4o", "name": "GPT-4o"}, {"id": "anthropic/claude-sonnet-4.6", "name": "Claude Sonnet 4.6"}, {"id": "google/gemini-2.0-flash-001", "name": "Gemini 2.0 Flash"}, ]; } } @override Widget build(BuildContext context) { return Consumer( builder: (context, settingsProvider, _) { final currentModel = settingsProvider.normalizeModelId( settingsProvider.settings.model, ); return FutureBuilder>>( future: _modelsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Text("Loading models..."); } final models = snapshot.data ?? []; final selectedModel = models.firstWhere( (m) => m["id"] == currentModel, orElse: () => {"id": currentModel, "name": currentModel}, ); return GestureDetector( onTap: () => _showModelMenu( context, models, currentModel, settingsProvider, ), child: Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 8, ), decoration: BoxDecoration( border: Border.all(color: const Color(0xFFE2E8F0)), borderRadius: BorderRadius.circular(6), ), child: Text(selectedModel["name"] as String? ?? currentModel), ), ); }, ); }, ); } void _showModelMenu( BuildContext context, List> models, String currentModel, SettingsProvider settingsProvider, ) { showDialog( context: context, builder: (ctx) => Dialog( child: Container( constraints: const BoxConstraints(maxHeight: 400), child: SingleChildScrollView( child: Column( children: models.map((model) { final modelId = model["id"] as String; final modelName = model["name"] as String? ?? modelId; final isSelected = modelId == currentModel; return Container( color: isSelected ? const Color(0xFFF1F5F9) : Colors.transparent, child: GestureDetector( onTap: () { settingsProvider.updateModel(modelId); Navigator.pop(ctx); }, child: Padding( padding: const EdgeInsets.all(12), child: Row( children: [ if (isSelected) const Padding( padding: EdgeInsets.only(right: 8), child: Text( "✓", style: TextStyle(fontWeight: FontWeight.bold), ), ), Expanded(child: Text(modelName)), ], ), ), ), ); }).toList(), ), ), ), ), ); } }