fetchConfig method
Orchestrate the branded loading sequence and advance to the welcome step.
Phase 1 (spinner) runs until _fetchChartConfig resolves; phase 2 (the
determinate bar) covers the heavier config calls.
Implementation
Future<void> fetchConfig() async {
_loading = true;
_progress = 0;
_chartResolved = false;
_loadingMessageKey = '';
notifyListeners();
// Phase 1 → Phase 2: public branding (logo + color + name + early language).
await _fetchChartConfig();
try {
// Contents config. Show the first message immediately so the user
// always sees a status from the start of the determinate bar.
_messageChangeTimer?.cancel();
_loadingMessageKey = 'content';
notifyListeners();
updateProgress(15);
_contentsRaw = await _apiService.fetchContentsConfig();
_resolveContentsForCurrentLanguage();
updateProgress(35);
// Request config (workspace + definitive language).
_messageChangeTimer?.cancel();
_loadingMessageKey = 'request';
notifyListeners();
updateProgress(60);
final config = await _apiService.fetchRequestConfig();
_requestConfig = config;
// Check if request returned an error (e.g. PROCESSED)
if (config['error'] == true) {
_configErrorMessage = config['message'] as String?;
_loading = false;
goToStep(DataleonFlowStep.alreadyProcessed);
return;
}
final workspaceString =
config['result']?['metadata']?['workspace'] as String?;
if (workspaceString != null && workspaceString.isNotEmpty) {
_workspace = jsonDecode(workspaceString) as Map<String, dynamic>;
}
final language = config['result']?['metadata']?['language'] as String? ??
dashboardConfiguration['languageApp'] as String?;
if (language != null && language.isNotEmpty) {
_languageCode = normalizeLanguage(language);
}
// Re-confirm the contents slice with the definitive language.
_resolveContentsForCurrentLanguage();
// Theme: preload fonts while the bar eases 60 → 88.
_messageChangeTimer?.cancel();
_loadingMessageKey = 'theme';
notifyListeners();
updateProgress(88);
notifyListeners();
try {
await _loadCustomFonts();
} catch (_) {}
updateProgress(90);
// Ready.
_messageChangeTimer?.cancel();
_loadingMessageKey = 'ready';
notifyListeners();
updateProgress(100);
// Keep the loader visible briefly after reaching 100%.
await Future.delayed(const Duration(milliseconds: 900));
_loading = false;
goToStep(DataleonFlowStep.welcome);
} catch (e) {
_configErrorMessage = e.toString();
_loading = false;
// 403 / PROCESSED → alreadyProcessed, other errors → error page
if (e is DataleonApiException && e.statusCode == 403) {
goToStep(DataleonFlowStep.alreadyProcessed);
} else {
goToStep(DataleonFlowStep.error);
}
}
}