import 'package:flutter/foundation.dart'; import 'package:qpay/http/http.dart'; import 'package:qpay/browser.dart'; const appBuildNumber = 4; /// Describes the result of the build-number check performed during splash. enum SplashCheckStatus { checking, noUpdate, updateAvailable } class SplashProvider extends ChangeNotifier { final Http _http = Http(); SplashCheckStatus _status = SplashCheckStatus.checking; Map? _updatePayload; bool _isRefreshing = false; SplashCheckStatus get status => _status; Map? get updatePayload => _updatePayload; bool get isRefreshing => _isRefreshing; /// The store / download URL from the server payload, or `null` if /// the server didn't include one. String? get downloadUrl => _updatePayload?['downloadUrl']?.toString(); /// Calls the server endpoint to see whether a newer app build exists. /// /// * 204 → no new build — proceed with normal app loading. /// * 200 → a new build is available — the splash screen will show a /// non-dismissible bottom sheet offering the user a hard refresh. Future checkVersion() async { _status = SplashCheckStatus.checking; notifyListeners(); try { final buildNumber = appBuildNumber; final response = await _http.getRaw( '/public/app-version/check/app?currentBuildNumber=$buildNumber', ); if (response.statusCode == 204) { _status = SplashCheckStatus.noUpdate; } else if (response.statusCode == 200) { _status = SplashCheckStatus.updateAvailable; _updatePayload = response.data is Map ? response.data as Map : null; } else { // Unexpected status code – don't block the user. _status = SplashCheckStatus.noUpdate; } } catch (_) { // Network / server errors should not prevent the app from loading. _status = SplashCheckStatus.noUpdate; } notifyListeners(); } /// 1. Sends a POST request to clear the Cloudflare cache. /// 2. Waits 5 seconds to give the CDN time to propagate. /// 3. Performs a hard refresh by reloading the current URL, which /// forces the browser to re-fetch all cached assets. Future clearCacheAndRefresh() async { _isRefreshing = true; notifyListeners(); try { await _http.postRaw('/public/cache/cloudflare/clear'); } catch (_) { // Proceed with refresh even if the cache-clear request fails. } // Allow Cloudflare a few seconds to flush its edge cache. await Future.delayed(const Duration(seconds: 5)); // Hard-refresh: navigate to the current location which triggers a // full page reload on web (and restarts the app on other platforms). Browser.location.href = Browser.location.href; } }