import 'dart:async'; import 'dart:io'; import 'package:bloc/bloc.dart'; import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:paperless_mobile/features/logging/models/parsed_log_message.dart'; import 'package:paperless_mobile/core/service/file_service.dart'; import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; import 'package:path/path.dart' as p; import 'package:permission_handler/permission_handler.dart'; import 'package:rxdart/rxdart.dart'; part 'app_logs_state.dart'; final _fileNameFormat = DateFormat("yyyy-MM-dd"); class AppLogsCubit extends Cubit { StreamSubscription? _fileChangesSubscription; final LocalNotificationService _localNotificationService; AppLogsCubit( DateTime date, this._localNotificationService, ) : super(AppLogsStateInitial(date: date)); Future loadLogs(DateTime date) async { if (date == state.date) { return; } _fileChangesSubscription?.cancel(); emit(AppLogsStateLoading(date: date)); final logDir = FileService.instance.logDirectory; final availableLogs = (await logDir .list() .whereType() .where((event) => event.path.endsWith('.log')) .map((e) => _fileNameFormat.parse(p.basenameWithoutExtension(e.path))) .toList()) .sorted(); final logFile = _getLogfile(date); if (!await logFile.exists()) { emit(AppLogsStateLoaded( date: date, logs: [], availableLogs: availableLogs, )); } try { _updateLogsFromFile(logFile, date, availableLogs); _fileChangesSubscription = logFile.watch().listen((event) async { if (!isClosed) { _updateLogsFromFile(logFile, date, availableLogs); } }); } catch (e) { emit(AppLogsStateError( error: e, date: date, )); } } void _updateLogsFromFile( File file, DateTime date, List availableLogs) async { final logs = await file.readAsLines(); final parsedLogs = ParsedLogMessage.parse(logs).reversed.toList(); emit(AppLogsStateLoaded( date: date, logs: parsedLogs, availableLogs: availableLogs, )); } Future clearLogs(DateTime date) async { final logFile = _getLogfile(date); await logFile.writeAsString(''); await loadLogs(date); } Future copyToClipboard(DateTime date) async { final file = _getLogfile(date); if (!await file.exists()) { return; } final content = await file.readAsString(); Clipboard.setData(ClipboardData(text: content)); } Future saveLogs(DateTime date, String locale) async { var formattedDate = _fileNameFormat.format(date); final filename = 'paperless_mobile_logs_$formattedDate.log'; // final parentDir = await FilePicker.platform.getDirectoryPath( // dialogTitle: "Save log from ${DateFormat.yMd(locale).format(date)}", // initialDirectory: Platform.isAndroid // ? FileService.instance.downloadsDirectory.path // : null, // ); // if (parentDir == null) { // return; // } final logFile = _getLogfile(date); final parentDir = FileService.instance.downloadsDirectory; final downloadedFile = await logFile.copy(p.join(parentDir.path, filename)); _localNotificationService.notifyFileDownload(filePath: downloadedFile.path); } File _getLogfile(DateTime date) { return File(p.join(FileService.instance.logDirectory.path, '${_fileNameFormat.format(date)}.log')); } @override Future close() async { await _fileChangesSubscription?.cancel(); return super.close(); } }