From a7a7629931b46de5780819b150c7b3d90ef6b552 Mon Sep 17 00:00:00 2001 From: Zach Aw Date: Thu, 2 Jul 2026 06:25:11 +0800 Subject: [PATCH] feat(settings): pull-to-refresh re-fetches the model list The installed-model list (Model Manager on the Settings tab) only re-fetched when the server or app mode changed, so models installed or removed outside the app (via the Lemonade server itself or another client) never showed up without an app restart. Wrap the Settings tab ListView in a RefreshIndicator that awaits the same fetchModels() the screen already relies on, matching the existing pull-to-refresh pattern in omni_router_screen / account_screen / admin_models_tab. AlwaysScrollableScrollPhysics so the pull works even when the content fits on screen. --- lib/screens/nexus/settings_tab.dart | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/screens/nexus/settings_tab.dart b/lib/screens/nexus/settings_tab.dart index eecfddb..34edacb 100644 --- a/lib/screens/nexus/settings_tab.dart +++ b/lib/screens/nexus/settings_tab.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../providers/account_provider.dart'; import '../../providers/app_mode_provider.dart'; import '../../providers/billing_providers.dart'; +import '../../providers/models_provider.dart'; import '../../providers/nexus_gateway_provider.dart'; import '../../providers/omni_router_provider.dart'; import '../../providers/theme_provider.dart'; @@ -36,17 +37,25 @@ class SettingsTab extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final mode = ref.watch(appModeProvider); - return ListView( - padding: const EdgeInsets.all(16), - children: [ - _profile(context, ref), - const SizedBox(height: 18), - if (mode.showsModelManager) ...[ - const ModelManager(), + // Pull-to-refresh re-fetches the installed model list from the selected + // server, so models installed/removed outside the app (e.g. via the + // Lemonade server itself or another client) show up without a restart — + // the list otherwise only updates on server/app-mode changes. + return RefreshIndicator( + onRefresh: () => ref.read(modelsProvider.notifier).fetchModels(), + child: ListView( + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.all(16), + children: [ + _profile(context, ref), const SizedBox(height: 18), + if (mode.showsModelManager) ...[ + const ModelManager(), + const SizedBox(height: 18), + ], + ..._groups(context, ref), ], - ..._groups(context, ref), - ], + ), ); }