Brandon Presley
19f9dd9b3b
Our app is so fast these will look like bugs to flicker in front of the user.
183 lines
6.9 KiB
Dart
183 lines
6.9 KiB
Dart
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<Setting> stream;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
stream = (db.select(db.settings)..limit(1)).watchSingle();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: StreamBuilder<Setting>(
|
|
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;
|
|
}
|
|
},
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|