feat: implement settings screen with reminders, biometrics, theme, and PDF export
- Daily reminder scheduling via flutter_local_notifications (inexact, repeating at chosen time) - Biometric lock gate on app launch with auto-prompt and manual unlock button - Theme mode selector (System/Light/Dark) persisted to settings DB - PDF export of full mood history shared via share_plus - Android: POST_NOTIFICATIONS, USE_BIOMETRIC permissions; switched to FlutterFragmentActivity
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:pdf/pdf.dart';
|
||||
import 'package:pdf/widgets.dart' as pw;
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
import '../database/app_database.dart';
|
||||
|
||||
class ExportService {
|
||||
static String _fmtDate(DateTime dt) =>
|
||||
'${dt.year}-${dt.month.toString().padLeft(2, '0')}-'
|
||||
'${dt.day.toString().padLeft(2, '0')} '
|
||||
'${dt.hour.toString().padLeft(2, '0')}:'
|
||||
'${dt.minute.toString().padLeft(2, '0')}';
|
||||
|
||||
static String _level(int? v) => v == null ? '—' : '$v/5';
|
||||
|
||||
static String _sleep(int? mins) {
|
||||
if (mins == null) return '—';
|
||||
final h = mins ~/ 60;
|
||||
final m = mins % 60;
|
||||
return m > 0 ? '${h}h ${m}m' : '${h}h';
|
||||
}
|
||||
|
||||
static Future<void> exportToPdf(List<MoodEntry> entries) async {
|
||||
final doc = pw.Document();
|
||||
|
||||
doc.addPage(
|
||||
pw.MultiPage(
|
||||
pageFormat: PdfPageFormat.a4,
|
||||
build: (ctx) => [
|
||||
pw.Header(
|
||||
level: 0,
|
||||
child: pw.Text('DailyYou — Mood Journal'),
|
||||
),
|
||||
pw.SizedBox(height: 12),
|
||||
pw.TableHelper.fromTextArray(
|
||||
headerStyle: pw.TextStyle(fontWeight: pw.FontWeight.bold),
|
||||
cellAlignments: {
|
||||
0: pw.Alignment.centerLeft,
|
||||
1: pw.Alignment.center,
|
||||
2: pw.Alignment.center,
|
||||
3: pw.Alignment.center,
|
||||
4: pw.Alignment.center,
|
||||
5: pw.Alignment.center,
|
||||
},
|
||||
headers: [
|
||||
'Date & time',
|
||||
'Mood',
|
||||
'Sleep',
|
||||
'Energy',
|
||||
'Positivity',
|
||||
'Self-worth',
|
||||
],
|
||||
data: entries
|
||||
.map((e) => [
|
||||
_fmtDate(e.timestamp),
|
||||
'${e.moodLevel}/5',
|
||||
_sleep(e.sleepMinutes),
|
||||
_level(e.energyLevel),
|
||||
_level(e.positivityLevel),
|
||||
_level(e.selfWorthLevel),
|
||||
])
|
||||
.toList(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final bytes = await doc.save();
|
||||
final dir = await getTemporaryDirectory();
|
||||
final file = File('${dir.path}/dailyou_export.pdf');
|
||||
await file.writeAsBytes(bytes);
|
||||
|
||||
await SharePlus.instance.share(
|
||||
ShareParams(
|
||||
files: [XFile(file.path, mimeType: 'application/pdf')],
|
||||
subject: 'DailyYou Export',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user