watchLocalization function
Watch for Dart file changes and auto-generate missing localization keys
Implementation
Future<void> watchLocalization({
required int debounceSeconds,
required bool verbose,
}) async {
final libDir = Directory('${Directory.current.path}/lib');
if (!libDir.existsSync()) {
print('${ColorsText.red}✗ Error: lib/ directory not found${ColorsText.reset}');
print('${ColorsText.yellow}Make sure you are in a Flutter project directory${ColorsText.reset}');
return;
}
// Check if l10n directory exists
final l10nDir = Directory('${Directory.current.path}/lib/l10n');
if (!l10nDir.existsSync()) {
print('${ColorsText.red}✗ Error: lib/l10n/ directory not found${ColorsText.reset}');
print('${ColorsText.yellow}Initialize localization first: ${ColorsText.cyan}flyer make --lang ar,en${ColorsText.reset}');
return;
}
// Print header
print('${ColorsText.cyan}═══════════════════════════════════════════════════════════${ColorsText.reset}');
print('${ColorsText.cyan} Auto-Generate Missing Localization Keys${ColorsText.reset}');
print('${ColorsText.cyan}═══════════════════════════════════════════════════════════${ColorsText.reset}\n');
Timer? debounceTimer;
bool isAnalyzing = false;
DateTime lastModified = DateTime.now();
// Initial analysis
final now = DateTime.now();
final timeStr = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}';
print('${ColorsText.blue}🔍 [$timeStr] Running initial analysis...${ColorsText.reset}');
await _analyzeAndAddKeys(verbose, timeStr);
// Start watching
print('${ColorsText.green}✓ Ready! Watching for file changes...${ColorsText.reset}');
print('${ColorsText.gray} Debounce: ${debounceSeconds}s | Verbose: ${verbose ? 'ON' : 'OFF'}${ColorsText.reset}');
print('${ColorsText.gray} Press Ctrl+C to stop${ColorsText.reset}\n');
libDir.watch(recursive: true).listen((event) {
// Only process .dart files (ignore .arb files to prevent loops)
if (!event.path.endsWith('.dart') || event.path.contains('/l10n/')) {
return;
}
// Only process modify events (file save)
if (event.type != FileSystemEvent.modify) {
return;
}
// Skip duplicate events (some editors trigger multiple events)
final file = File(event.path);
if (file.existsSync()) {
final modifiedTime = file.lastModifiedSync();
if (modifiedTime.difference(lastModified).inMilliseconds < 100) {
return;
}
lastModified = modifiedTime;
}
// Get filename for logging
final fileName = event.path.split('/').last;
if (verbose) {
print('${ColorsText.gray}📝 File saved: $fileName${ColorsText.reset}');
}
// Cancel previous timer
debounceTimer?.cancel();
// Start new debounced timer
debounceTimer = Timer(Duration(seconds: debounceSeconds), () async {
if (!isAnalyzing) {
isAnalyzing = true;
// Get current time
final now = DateTime.now();
final timeStr = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}';
if (!verbose) {
print('${ColorsText.blue}🔍 [$timeStr] Analyzing $fileName...${ColorsText.reset}');
}
await _analyzeAndAddKeys(verbose, timeStr);
isAnalyzing = false;
}
});
});
// Keep the process running
await Future.delayed(Duration(days: 365));
}