import "dart:async"; import "package:flutter/material.dart"; import "package:quotegen_client/services/quote_api_v2.dart"; class SessionProvider extends ChangeNotifier { String? currentSessionId; bool isLoading = true; bool canRender = true; Timer? _renderEnableTimer; int _submitCount = 0; Future initializeSession(QuoteSessionRequest request) async { try { QuoteSession session = await QuoteGeneratorApiV2.createSession(request); currentSessionId = session.id; print("Session created: ${session.id}"); } catch (e) { print("Failed to creat session: $e"); } } void setLoaded() { isLoading = false; notifyListeners(); } void onSubmit({ String? changedField, required QuoteSessionRequest request, VoidCallback? onDebounceSettled, }) async { int currentSubmit = ++_submitCount; _renderEnableTimer?.cancel(); if (canRender) { canRender = false; notifyListeners(); } _renderEnableTimer = Timer(Duration(seconds: 5), () { canRender = true; notifyListeners(); }); await Future.delayed(Duration(milliseconds: 700)); if (currentSubmit != _submitCount) return; // fire the callback so render gets cleared onDebounceSettled?.call(); print("Submitting field: $changedField"); // wait for session to be ready while (currentSessionId == null) { await Future.delayed(Duration(milliseconds: 100)); } QuoteSessionRequest updateRequest; if (changedField == null) { updateRequest = request; } else { final engagement = (changedField == "engagement" || changedField.startsWith("engagement_")) ? _buildPartialEngagement(changedField, request) : null; final shouldClearEngagement = changedField == "engagement" && engagement == null; updateRequest = QuoteSessionRequest( displayName: changedField == "display_name" ? request.displayName : null, username: changedField == "handle" ? request.username : null, text: changedField == "content" ? request.text : null, timestamp: changedField == "datetime" ? request.timestamp : null, avatarUrl: changedField == "avatar_image" ? request.avatarUrl : null, imageUrl: changedField == "post_image" ? request.imageUrl : null, verified: changedField == "verified" ? request.verified : null, engagement: engagement, clearAvatarUrl: changedField == "avatar_image" && request.avatarUrl == null, clearImageUrl: changedField == "post_image" && request.imageUrl == null, clearEngagement: shouldClearEngagement, ); } await QuoteGeneratorApiV2.updateSession(currentSessionId!, updateRequest); print("Session updated"); } QuoteEngagement? _buildPartialEngagement(String field, QuoteSessionRequest req) { final eng = req.engagement; if (field == "engagement") { return eng; } return QuoteEngagement( likes: field == "engagement_likes" ? eng?.likes : null, retweets: field == "engagement_retweets" ? eng?.retweets : null, replies: field == "engagement_replies" ? eng?.replies : null, views: field == "engagement_views" ? eng?.views : null, ); } @override void dispose() { _renderEnableTimer?.cancel(); super.dispose(); } }