import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:venera/utils/ext.dart'; class LogItem { final LogLevel level; final String title; final String content; final DateTime time = DateTime.now(); @override toString() => "${level.name} $title $time \n$content\n\n"; LogItem(this.level, this.title, this.content); } enum LogLevel { error, warning, info } class Log { static final List _logs = []; static List get logs => _logs; static const maxLogLength = 3000; static const maxLogNumber = 500; static bool ignoreLimitation = false; /// only for debug static const String? logFile = null; static void printWarning(String text) { print('\x1B[33m$text\x1B[0m'); } static void printError(String text) { print('\x1B[31m$text\x1B[0m'); } static void addLog(LogLevel level, String title, String content) { if (!ignoreLimitation && content.length > maxLogLength) { content = "${content.substring(0, maxLogLength)}..."; } if (kDebugMode) { switch (level) { case LogLevel.error: printError(content); case LogLevel.warning: printWarning(content); case LogLevel.info: print(content); } } var newLog = LogItem(level, title, content); if (newLog == _logs.lastOrNull) { return; } _logs.add(newLog); if(logFile != null) { File(logFile!).writeAsString(newLog.toString(), mode: FileMode.append); } if (_logs.length > maxLogNumber) { var res = _logs.remove( _logs.firstWhereOrNull((element) => element.level == LogLevel.info)); if (!res) { _logs.removeAt(0); } } } static info(String title, String content) { addLog(LogLevel.info, title, content); } static warning(String title, String content) { addLog(LogLevel.warning, title, content); } static error(String title, String content, [Object? stackTrace]) { if(stackTrace != null) { content += "\n${stackTrace.toString()}"; } addLog(LogLevel.error, title, content); } static void clear() => _logs.clear(); @override String toString() { var res = "Logs\n\n"; for (var log in _logs) { res += log.toString(); } return res; } }