import 'dart:convert'; import 'dart:io'; import 'package:csv/csv.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter/material.dart' as material; import 'package:fmassive/database.dart'; import 'package:fmassive/delete_all_sets.dart'; import 'package:fmassive/main.dart'; import 'package:fmassive/sound_picker.dart'; import 'package:moor/moor.dart'; class SettingsPage extends StatelessWidget { const SettingsPage({super.key, required this.search}); final String search; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: _SettingsPage(search: search), ), ); } } class _SettingsPage extends StatefulWidget { const _SettingsPage({required this.search}); final String search; @override createState() => _SettingsPageState(); } class _SettingsPageState extends State<_SettingsPage> { late Stream stream; @override void initState() { super.initState(); stream = (db.select(db.settings)..limit(1)).watchSingle(); } @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder( stream: stream, builder: (context, snapshot) { final settings = snapshot.data; print('build: $settings'); if (settings == null) return Container(); final filteredItems = [ {'title': 'Alarm', 'value': settings.alarm}, {'title': 'Vibrate', 'value': settings.vibrate}, {'title': 'Notify', 'value': settings.notify}, {'title': 'Images', 'value': settings.images}, {'title': 'Show Unit', 'value': settings.showUnit}, {'title': 'Steps', 'value': settings.steps}, {'title': 'Sound', 'value': settings.sound}, {'title': 'Import sets', 'value': null}, {'title': 'Delete all sets', 'value': null}, ] .where((item) => (item['title'] as String) .toLowerCase() .contains(widget.search.toLowerCase()),) .toList(); return material.Column( children: [ Expanded( child: ListView.builder( itemCount: filteredItems.length, itemBuilder: (context, index) { final item = filteredItems[index]; if (item['title'] == 'Delete all sets') return DeleteAllSets(mounted: mounted); if (item['title'] == 'Import sets') return Center( child: ElevatedButton( child: const Text("Import sets"), onPressed: () async { final result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['csv'],); if (result == null) return; final file = File(result.files.single.path!); final input = file.openRead(); final fields = await input .transform(utf8.decoder) .transform(const CsvToListConverter(eol: "\n")) .skip(1) .toList(); final gymSets = fields.map((row) => GymSetsCompanion( id: Value(int.tryParse(row[0]) ?? 0), name: Value(row[1]), reps: Value(int.tryParse(row[2]) ?? 0), weight: Value(double.tryParse(row[3]) ?? 0), created: Value(row[4]), unit: Value(row[5]), hidden: Value(row[6] == 'true'), image: Value(row[7]), sets: Value(int.tryParse(row[8]) ?? 0), minutes: Value(int.tryParse(row[9]) ?? 0), seconds: Value(int.tryParse(row[10]) ?? 0), steps: Value(row[11]), ),); await db.batch( (batch) => batch.insertAll(db.gymSets, gymSets),); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Imported sets')),); }, ),); if (item['title'] == 'Sound') { return Center( child: SoundPicker( path: settings.sound, onSelect: (path) { db .update(db.settings) .write(SettingsCompanion(sound: Value(path))); }, ), ); } return SwitchListTile( title: Text(item['title'].toString()), value: (item['value'] ?? false) as bool, onChanged: (value) { switch (item['title']) { case 'Alarm': db .update(db.settings) .write(SettingsCompanion(alarm: Value(value))); break; case 'Vibrate': db.update(db.settings).write( SettingsCompanion(vibrate: Value(value)),); break; case 'Notify': db .update(db.settings) .write(SettingsCompanion(notify: Value(value))); break; case 'Images': db .update(db.settings) .write(SettingsCompanion(images: Value(value))); break; case 'Show Unit': db.update(db.settings).write( SettingsCompanion(showUnit: Value(value)),); break; case 'Steps': db .update(db.settings) .write(SettingsCompanion(steps: Value(value))); break; } }, ); }, ), ), ], ); }, ), ); } }