diff --git a/lib/DOM/history_importing_logic.dart b/lib/DOM/history_importing_logic.dart index 5cebbc2..d4c41a0 100644 --- a/lib/DOM/history_importing_logic.dart +++ b/lib/DOM/history_importing_logic.dart @@ -1,12 +1,22 @@ import 'dart:io'; import 'package:csv/csv.dart'; +import 'package:flutter/foundation.dart'; import 'package:intl/intl.dart'; import 'training_metadata.dart'; import 'exercise_metadata.dart'; -List importStrongCsv(String filePath, Units units) { - final List rows = File(filePath).readAsLinesSync(); +List importStrongCsv(String filepathORfileStr, Units units) { + final List rows; + if (kIsWeb) { + rows = filepathORfileStr.split("\n"); + if (rows.last.isEmpty) { + rows.removeLast(); + } + } else { + rows = File(filepathORfileStr).readAsLinesSync(); + } rows.removeAt(0); + //todo we should save teh header & compare it to see if it ever changes and bricks shit //todo save the header.. if it ever changes, lets make a pub/sub topic on gcs or some error medium to lmk!!! List sessions = []; @@ -26,8 +36,7 @@ List importStrongCsv(String filePath, Units units) { for (int i = 0; i < rows.length; i++) { var row = rows[i]; - final rowList = const CsvToListConverter() - .convert(row, shouldParseNumbers: false); // as List; + var rowList = const CsvToListConverter().convert(row, shouldParseNumbers: false); final date = DateFormat("yyyy-MM-dd HH:mm:ss").parse(rowList[0][0]); final workoutName = rowList[0][1]; final duration = parseStrongWorkoutDuration(rowList[0][2]); diff --git a/lib/cloud_io/firestore_sync.dart b/lib/cloud_io/firestore_sync.dart index ec992f8..6f20410 100644 --- a/lib/cloud_io/firestore_sync.dart +++ b/lib/cloud_io/firestore_sync.dart @@ -372,7 +372,7 @@ class ExercisesCubit extends Cubit { } Future removeExercises(List exercisesToRemove) async { - // Implement the method + //todo Implement the method // For now, let's emit an error emit(ExercisesError("removeExercises method not implemented")); } diff --git a/lib/importing/import_matching_page.dart b/lib/importing/import_matching_page.dart index 4b474a8..c2e2a8b 100644 --- a/lib/importing/import_matching_page.dart +++ b/lib/importing/import_matching_page.dart @@ -48,7 +48,7 @@ class _ImportInspectionPageState extends State { } else { exercisesState = exercisesState as ExercisesLoaded; } - matchPairs = _exerciseMatcher(newExs, exercisesState, 90); + matchPairs = _exerciseMatcher(newExs, exercisesState, 86); return Scaffold( appBar: AppBar( title: Text( diff --git a/lib/importing/import_training_ui.dart b/lib/importing/import_training_ui.dart index c515760..9bcaba2 100644 --- a/lib/importing/import_training_ui.dart +++ b/lib/importing/import_training_ui.dart @@ -56,7 +56,7 @@ class _ImportTrainingDataPageState extends State { late MassUnits selectedMassUnit; late DistanceUnits selectedDistanceUnit; bool setAsStandard = true; - String? filepath; + String? filepathORfileStr; @override void initState() { @@ -76,15 +76,17 @@ class _ImportTrainingDataPageState extends State { mainAxisSize: MainAxisSize.min, children: [ MyGenericButton( - label: (filepath == null) ? "Select file to Import" : "File Selected.", + label: (filepathORfileStr == null) + ? "Select file to Import" + : "File Selected.", onPressed: () async { //todo for web? // https://github.com/miguelpruivo/flutter_file_picker/wiki/FAQ - filepath = + filepathORfileStr = await getFileWithSnackbarErrors(context, ['csv', 'txt', 'json']); setState(() {}); }, - color: (filepath == null) ? darkTan : mediumGreen, + color: (filepathORfileStr == null) ? darkTan : mediumGreen, ), const SizedBox(height: 16), DropdownButtonFormField( @@ -143,13 +145,14 @@ class _ImportTrainingDataPageState extends State { Navigator.of(context).pop(); }, onComplete: () { - if (filepath == null) { + if (filepathORfileStr == null) { ScaffoldMessenger.of(context) .showSnackBar(const SnackBar(content: Text('No file selected'))); return; } - List sessions = importStrongCsv(filepath!, units); + List sessions = + importStrongCsv(filepathORfileStr!, units); if (setAsStandard) { var userInfoCubit = context.read(); diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index cff2ab4..a243edb 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,8 +1,9 @@ +import 'dart:convert'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'dart:async'; - import 'package:open_fitness_tracker/DOM/exercise_metadata.dart'; typedef Exercises = List; @@ -167,25 +168,34 @@ String enumToReadableString(Object o) { .toLowerCase(); } +/// will return the whole file as a string if on web. Future getFileWithSnackbarErrors( BuildContext context, List allowedExtensions) async { + String? filePath; var scaffoldMessenger = ScaffoldMessenger.of(context); + FilePickerResult? result = await FilePicker.platform .pickFiles(type: FileType.custom, allowedExtensions: allowedExtensions); - if (result == null) { + if (result == null && result!.files.isNotEmpty) { scaffoldMessenger.showSnackBar( const SnackBar(content: Text('No file selected')), ); return null; } - String? filePath = result.files.single.path; + if (kIsWeb) { + final fileBytes = result.files.first.bytes; + return utf8.decode(fileBytes!); + } + + filePath = result.files.single.path; if (filePath == null) { scaffoldMessenger.showSnackBar( const SnackBar(content: Text('No file selected. Is the path accessable?')), ); return null; } + return filePath; }