import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; import '../homepage/screen_homepage.dart'; import '../log/class_sitecheck.dart'; import '../log/class_sitelog.dart'; class Monitor2App extends StatefulWidget { const Monitor2App({super.key}); @override State createState() => Monitor2AppState(); } class Monitor2AppState extends State { List sites = []; List logs = []; Timer? timer; bool isChecking = false; final GlobalKey messengerKey = GlobalKey(); @override void initState() { super.initState(); loadSites().then((_) { loadLogs().then((_) { setState(() {}); checkAllSites(); timer = Timer.periodic( const Duration(hours: 1), (_) => checkAllSites(), ); }); }); } @override void dispose() { timer?.cancel(); super.dispose(); } Future getLogFile() async { final dir = await getApplicationDocumentsDirectory(); return File('${dir.path}/logs.dat'); } Future getSitesFile() async { final dir = await getApplicationDocumentsDirectory(); return File('${dir.path}/sites.dat'); } Future loadLogs() async { try { final file = await getLogFile(); if (await file.exists()) { final lines = await file.readAsLines(); logs = lines.map((l) => SiteLog.fromCsv(l)).toList(); } } catch (_) {} } Future saveLogs() async { final file = await getLogFile(); final lastLogs = logs.length > 10000 ? logs.sublist(logs.length - 10000) : logs; await file.writeAsString(lastLogs.map((l) => l.toCsv()).join('\n')); } Future loadSites() async { try { final file = await getSitesFile(); if (await file.exists()) { final lines = await file.readAsLines(); sites = lines.map((l) => SiteCheck.fromLine(l)).toList(); } else { sites = [ SiteCheck('https://flutter.dev'), SiteCheck('https://google.com'), ]; await saveSites(); } } catch (_) { sites = [ SiteCheck('https://flutter.dev'), SiteCheck('https://google.com'), ]; await saveSites(); } } Future saveSites() async { final file = await getSitesFile(); final lastSites = sites.length > 100 ? sites.sublist(sites.length - 100) : sites; await file.writeAsString(lastSites.map((s) => s.toLine()).join('\n')); } Future checkAllSites({bool showSnackBar = false}) async { if (isChecking) return; setState(() { isChecking = true; }); for (var site in sites) { try { final response = await http .get(Uri.parse(site.url)) .timeout(const Duration(seconds: 10)); addLog(site.url, response.statusCode); } catch (e) { addLog(site.url, -1); } } setState(() { isChecking = false; }); if (showSnackBar) { messengerKey.currentState?.showSnackBar( const SnackBar(content: Text('Vérification des sites terminée ✅')), ); } } void addLog(String url, int statusCode) { logs.add(SiteLog(DateTime.now(), url, statusCode)); if (logs.length > 10000) { logs = logs.sublist(logs.length - 10000); } saveLogs(); } void addSite(String url) async { if (sites.length >= 100) { messengerKey.currentState?.showSnackBar( const SnackBar(content: Text('Limite de 100 sites atteinte 🚫')), ); return; } setState(() { sites.add(SiteCheck(url)); }); await saveSites(); } void removeSite(int index) async { setState(() { sites.removeAt(index); }); await saveSites(); } @override Widget build(BuildContext context) { return MaterialApp( scaffoldMessengerKey: messengerKey, title: 'Surveillance de sites', theme: ThemeData(primarySwatch: Colors.blue), home: HomePage( sites: sites, logs: logs, addSite: addSite, removeSite: removeSite, forceCheck: () => checkAllSites(showSnackBar: true), isChecking: isChecking, ), ); } }