import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; const String _shareIntakeDebugLogKey = 'share_intake_debug_log_v1'; const int _maxShareIntakeDebugEvents = 40; class ShareIntakeDebugEvent { const ShareIntakeDebugEvent({ required this.at, required this.stage, required this.message, }); factory ShareIntakeDebugEvent.fromJson(Map json) { return ShareIntakeDebugEvent( at: DateTime.parse( json['at'] as String? ?? DateTime.now().toUtc().toIso8601String(), ).toLocal(), stage: json['stage'] as String? ?? 'unknown', message: json['message'] as String? ?? '', ); } final DateTime at; final String stage; final String message; Map toJson() { return { 'at': at.toUtc().toIso8601String(), 'stage': stage, 'message': message, }; } } class ShareIntakeDebugLog { const ShareIntakeDebugLog(); Future> read() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); final String? raw = prefs.getString(_shareIntakeDebugLogKey); if (raw == null || raw.isEmpty) { return const []; } try { final List items = jsonDecode(raw) as List; return items .whereType>() .map(ShareIntakeDebugEvent.fromJson) .toList(growable: false); } on FormatException { return const []; } } Future record(String stage, String message) async { final SharedPreferences prefs = await SharedPreferences.getInstance(); final List current = await read(); final List next = [ ShareIntakeDebugEvent(at: DateTime.now(), stage: stage, message: message), ...current, ].take(_maxShareIntakeDebugEvents).toList(growable: false); await prefs.setString( _shareIntakeDebugLogKey, jsonEncode( next .map((ShareIntakeDebugEvent event) => event.toJson()) .toList(growable: false), ), ); } Future clear() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.remove(_shareIntakeDebugLogKey); } }