fix: text sharing
This commit is contained in:
@@ -541,12 +541,10 @@ final loadConversationProvider = FutureProvider.family<Conversation, String>((
|
||||
|
||||
// Provider to automatically load and set the default model from user settings or OpenWebUI
|
||||
final defaultModelProvider = FutureProvider<Model?>((ref) async {
|
||||
// Initialize the settings watcher
|
||||
ref.watch(_settingsWatcherProvider);
|
||||
// Watch user settings to refresh when default model changes
|
||||
ref.watch(appSettingsProvider);
|
||||
// Handle reviewer mode first
|
||||
final reviewerMode = ref.watch(reviewerModeProvider);
|
||||
// Initialize the settings watcher (side-effect only)
|
||||
ref.read(_settingsWatcherProvider);
|
||||
// Read settings without subscribing to rebuilds to avoid watch/await hazards
|
||||
final reviewerMode = ref.read(reviewerModeProvider);
|
||||
if (reviewerMode) {
|
||||
// Check if a model is manually selected
|
||||
final currentSelected = ref.read(selectedModelProvider);
|
||||
@@ -563,20 +561,18 @@ final defaultModelProvider = FutureProvider<Model?>((ref) async {
|
||||
final models = await ref.read(modelsProvider.future);
|
||||
if (models.isNotEmpty) {
|
||||
final defaultModel = models.first;
|
||||
Future.microtask(() {
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = defaultModel;
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Auto-selected demo model: ${defaultModel.name}',
|
||||
);
|
||||
}
|
||||
});
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = defaultModel;
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Auto-selected demo model: ${defaultModel.name}',
|
||||
);
|
||||
}
|
||||
return defaultModel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final api = ref.watch(apiServiceProvider);
|
||||
final api = ref.read(apiServiceProvider);
|
||||
if (api == null) return null;
|
||||
|
||||
try {
|
||||
@@ -656,15 +652,11 @@ final defaultModelProvider = FutureProvider<Model?>((ref) async {
|
||||
}
|
||||
}
|
||||
|
||||
// Defer the state update to avoid modifying providers during initialization
|
||||
final modelToSet = selectedModel;
|
||||
Future.microtask(() {
|
||||
// Only update if this is not a manual selection
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = modelToSet;
|
||||
foundation.debugPrint('DEBUG: Set default model: ${modelToSet.name}');
|
||||
}
|
||||
});
|
||||
// Update selection immediately inside provider context
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = selectedModel;
|
||||
foundation.debugPrint('DEBUG: Set default model: ${selectedModel.name}');
|
||||
}
|
||||
|
||||
return selectedModel;
|
||||
} catch (e) {
|
||||
@@ -675,15 +667,12 @@ final defaultModelProvider = FutureProvider<Model?>((ref) async {
|
||||
final models = await ref.read(modelsProvider.future);
|
||||
if (models.isNotEmpty) {
|
||||
final fallbackModel = models.first;
|
||||
// Defer the state update
|
||||
Future.microtask(() {
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = fallbackModel;
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Fallback to first available model: ${fallbackModel.name}',
|
||||
);
|
||||
}
|
||||
});
|
||||
if (!ref.read(isManualModelSelectionProvider)) {
|
||||
ref.read(selectedModelProvider.notifier).state = fallbackModel;
|
||||
foundation.debugPrint(
|
||||
'DEBUG: Fallback to first available model: ${fallbackModel.name}',
|
||||
);
|
||||
}
|
||||
return fallbackModel;
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
|
||||
@@ -9,7 +9,8 @@ import '../../features/auth/providers/unified_auth_providers.dart';
|
||||
import '../../features/chat/providers/chat_providers.dart';
|
||||
import '../../features/chat/services/file_attachment_service.dart';
|
||||
import '../../core/providers/app_providers.dart';
|
||||
// No server chat creation here; follow chat flow on first send
|
||||
import 'navigation_service.dart';
|
||||
// Server chat creation/title generation occur on first send via chat providers
|
||||
|
||||
/// Lightweight payload for a share event
|
||||
class SharedPayload {
|
||||
@@ -26,20 +27,21 @@ final pendingSharedPayloadProvider = StateProvider<SharedPayload?>((_) => null);
|
||||
|
||||
/// Initializes listening to OS share intents and handles them
|
||||
final shareReceiverInitializerProvider = Provider<void>((ref) {
|
||||
// Do nothing on web/desktop
|
||||
// Only mobile platforms handle OS share intents
|
||||
if (kIsWeb) return;
|
||||
|
||||
final sub = StreamController<SharedPayload>.broadcast();
|
||||
if (!(Platform.isAndroid || Platform.isIOS)) return;
|
||||
|
||||
// Listen for app readiness: authenticated and model available
|
||||
void maybeProcessPending() {
|
||||
final navState = ref.read(authNavigationStateProvider);
|
||||
final model = ref.read(selectedModelProvider);
|
||||
final pending = ref.read(pendingSharedPayloadProvider);
|
||||
final isOnChatRoute = NavigationService.currentRoute == Routes.chat;
|
||||
if (pending != null &&
|
||||
pending.hasAnything &&
|
||||
navState == AuthNavigationState.authenticated &&
|
||||
model != null) {
|
||||
model != null &&
|
||||
isOnChatRoute) {
|
||||
_processPayload(ref, pending);
|
||||
ref.read(pendingSharedPayloadProvider.notifier).state = null;
|
||||
}
|
||||
@@ -51,6 +53,8 @@ final shareReceiverInitializerProvider = Provider<void>((ref) {
|
||||
(_, __) => maybeProcessPending(),
|
||||
);
|
||||
ref.listen(selectedModelProvider, (_, __) => maybeProcessPending());
|
||||
// Also poll once shortly after navigation settles to ensure ChatPage is ready
|
||||
Future.delayed(const Duration(milliseconds: 150), () => maybeProcessPending());
|
||||
|
||||
// Hook into share_handler
|
||||
final handler = sh.ShareHandler.instance;
|
||||
@@ -85,7 +89,6 @@ final shareReceiverInitializerProvider = Provider<void>((ref) {
|
||||
// Ensure cleanup
|
||||
ref.onDispose(() async {
|
||||
await streamSub.cancel();
|
||||
await sub.close();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -169,9 +172,8 @@ Future<void> _processPayload(Ref ref, SharedPayload payload) async {
|
||||
final current = ref.read(inputFocusTriggerProvider);
|
||||
ref.read(inputFocusTriggerProvider.notifier).state = current + 1;
|
||||
}
|
||||
// Do NOT create a placeholder server chat here. The drawer will refresh
|
||||
// when the user sends their first message, matching in-app behavior.
|
||||
// This allows the user to add a caption before sending
|
||||
// Do NOT create a server chat here. The chat is created on first send
|
||||
// (with server syncing + title generation) in chat_providers.dart.
|
||||
} catch (e) {
|
||||
debugPrint('ShareReceiver: failed to process payload: $e');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user