Skip to content

Commit

Permalink
polish
Browse files Browse the repository at this point in the history
  • Loading branch information
Desync-o-tron committed Oct 2, 2024
1 parent 816b078 commit f380a22
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 235 deletions.
2 changes: 1 addition & 1 deletion lib/DOM/history_importing_logic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ List<TrainingSession> importStrongCsv(String filepathORfileStr, Units units) {
final workoutName = rowList[0][1];
final duration = parseStrongWorkoutDuration(rowList[0][2]);
final exerciseName = rowList[0][3];
// final _setOrder = int.parse(rowList[0][4]); // unused..why this here
// final _setOrder = int.parse(rowList[0][4]); // todo unused..why this here
final weightRaw = double.tryParse(rowList[0][5]) ?? 0;
final weight = double.parse(weightRaw.toStringAsFixed(2));
final reps = int.tryParse(rowList[0][6]) ?? 0;
Expand Down
62 changes: 36 additions & 26 deletions lib/cloud_io/firestore_sync.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ class CloudStorage {
});

if (!isUserEmailVerified()) return;

// TrainHistoryDB.loadUserTrainingHistory(useCache: false);
// refreshCacheIfItsBeenXHours(12);
}

Expand Down Expand Up @@ -79,17 +77,22 @@ class CloudStorage {
"Sign in. Make sure to verify your email if not signing in with Google Sign In, etc...");
}
return await _retryWithExponentialBackoff(() async {
final docSnapshot = await firestore
.collection('users')
.doc(firebaseAuth.currentUser!.uid)
.get(const GetOptions(source: Source.server));
final data = docSnapshot.data(); // as Map<String, dynamic>?;

if (data != null && data.containsKey(_basicUserInfoKey)) {
final basicUserInfoJson = data[_basicUserInfoKey] as Map<String, dynamic>;
return BasicUserInfo.fromJson(basicUserInfoJson);
} else {
return BasicUserInfo();
try {
final docSnapshot = await firestore
.collection('users')
.doc(firebaseAuth.currentUser!.uid)
.get(const GetOptions(source: Source.server));
final data = docSnapshot.data(); // as Map<String, dynamic>?;

if (data != null && data.containsKey(_basicUserInfoKey)) {
final basicUserInfoJson = data[_basicUserInfoKey] as Map<String, dynamic>;
return BasicUserInfo.fromJson(basicUserInfoJson);
} else {
return BasicUserInfo();
}
} catch (e) {
print("test"); //todo rm
rethrow;
}
});
}
Expand Down Expand Up @@ -132,6 +135,7 @@ class CloudStorage {
await firebaseAuth.signOut();
// rethrow;
} else {
//todo just sign out & log???
// Handle other Firebase exceptions
rethrow;
}
Expand Down Expand Up @@ -179,20 +183,26 @@ class TrainingHistoryCubit extends Cubit<TrainingHistoryState> {
//todo re enable me
// try {
await CloudStorage._retryWithExponentialBackoff(() async {
QuerySnapshot<Object?> cloudTrainingHistory = await CloudStorage.firestore
.collection('users')
.doc(CloudStorage.firebaseAuth.currentUser!.uid)
.collection(CloudStorage._historyKey)
.get(GetOptions(source: useCache ? Source.cache : Source.server));

List<TrainingSession> sessions = [];
for (var doc in cloudTrainingHistory.docs) {
sessions.add(
TrainingSession.fromJson(doc.data() as Map<String, dynamic>)..id = doc.id,
);
try {
QuerySnapshot<Object?> cloudTrainingHistory = await CloudStorage.firestore
.collection('users')
.doc(CloudStorage.firebaseAuth.currentUser!.uid)
.collection(CloudStorage._historyKey)
.get(GetOptions(source: useCache ? Source.cache : Source.server));

List<TrainingSession> sessions = [];
for (var doc in cloudTrainingHistory.docs) {
sessions.add(
TrainingSession.fromJson(doc.data() as Map<String, dynamic>)..id = doc.id,
);
}
sessions.sort((a, b) => b.date.compareTo(a.date));
emit(TrainingHistoryLoaded(sessions));
} catch (e) {
print('gotcha');
rethrow; //todo rm me
}
sessions.sort((a, b) => b.date.compareTo(a.date));
emit(TrainingHistoryLoaded(sessions));

//todo whats up with trying to load history on startup for the first time?
});
// } catch (e) {
Expand Down
1 change: 0 additions & 1 deletion lib/exercises/create_new_exercise/muscle_selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ class MusclesDropdown extends StatelessWidget {
itemBuilder: (context, index) => ListTile(
title: Text(filteredMuscles[index]),
onTap: () {
// onMuscleAdded(filteredMuscles[index]);
if (filteredMuscles.contains(filteredMuscles[index])) {
onMuscleRemoved(filteredMuscles[index]);
} else {
Expand Down
16 changes: 3 additions & 13 deletions lib/history/history_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import 'package:intl/intl.dart';
import 'package:open_fitness_tracker/DOM/training_metadata.dart';
import 'package:open_fitness_tracker/cloud_io/firestore_sync.dart';
import 'package:open_fitness_tracker/common/common_widgets.dart';
import 'package:open_fitness_tracker/importing/import_training_ui.dart';
import 'package:open_fitness_tracker/importing/import_training_first_page.dart';
import 'package:open_fitness_tracker/navigation/routes.dart';
import 'package:open_fitness_tracker/utils/utils.dart';

import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -75,16 +76,9 @@ class HistoryPage extends StatelessWidget {
onSelected: (String result) {
final cubit = context.read<TrainingHistoryCubit>();
if (result == 'import') {
showDialog(
context: context,
builder: (BuildContext context) {
return const ExternalAppImportSelectionDialog();
},
);
routerConfig.push(routeNames.ImportExternalAppHistory.text);
} else if (result == 'refresh training history') {
cubit.loadUserTrainingHistory(useCache: false);
} else if (result == 'delete ENTIRE history') {
cubit.deleteEntireTrainingHistory();
}
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
Expand All @@ -96,10 +90,6 @@ class HistoryPage extends StatelessWidget {
value: 'refresh training history',
child: Text('Refresh training history cache'),
),
const PopupMenuItem<String>(
value: 'delete history',
child: Text('Delete entire history'),
),
],
);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/importing/ex_match_listview.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:open_fitness_tracker/DOM/exercise_metadata.dart';
import 'package:open_fitness_tracker/common/common_widgets.dart';
import 'package:open_fitness_tracker/exercises/ex_search_page.dart';
import 'package:open_fitness_tracker/exercises/ex_tile.dart';
import 'package:open_fitness_tracker/navigation/routes.dart';

class ExerciseMatch {
final Exercise foreignExercise;
Expand Down Expand Up @@ -220,6 +221,7 @@ class _MatchExercisesScrollViewState extends State<MatchExercisesScrollView> {

void _addNewExercise(
int index, Exercise foreignExercise, Function onExMatchFound) async {
// Exercise? newExercise = await routerConfig.push(routeNames.Exercises.text);
Exercise? newExercise = await Navigator.push<Exercise>(
context,
MaterialPageRoute(
Expand Down
File renamed without changes.
202 changes: 202 additions & 0 deletions lib/importing/import_training_first_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:open_fitness_tracker/DOM/basic_user_info.dart';
import 'package:open_fitness_tracker/DOM/history_importing_logic.dart';
import 'package:open_fitness_tracker/DOM/training_metadata.dart';
import 'package:open_fitness_tracker/common/common_widgets.dart';
import 'package:open_fitness_tracker/importing/import_inspection_page.dart';
import 'package:open_fitness_tracker/styles.dart';
import 'package:open_fitness_tracker/utils/utils.dart';

class ImportTrainingDataPage extends StatefulWidget {
const ImportTrainingDataPage({
super.key,
});

@override
State<ImportTrainingDataPage> createState() => _ImportTrainingDataPageState();
}

class _ImportTrainingDataPageState extends State<ImportTrainingDataPage> {
final Units units = Units();
late MassUnits selectedMassUnit;
late DistanceUnits selectedDistanceUnit;
bool setAsStandard = true;
String? filepathORfileStr;
OtherTrainingApps originApp = OtherTrainingApps.strong;

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Import Your Training History"),
),
body: SafeArea(
minimum: const EdgeInsets.all(40),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
originAppSelector(),
const SizedBox(height: 16),
fileSelectButton(context),
const SizedBox(height: 16),
massSelectDropdown(),
const SizedBox(height: 16),
distanceSelectDropdown(),
const SizedBox(height: 16),
setAsDefaultUnitsSwitch(),
BottomCancelOrCompleteButtons(
cancelLabel: "Cancel",
completeLabel: "Import",
onCancel: () {
Navigator.of(context).pop();
},
onComplete: runImport,
),
],
),
),
),
);

/*
for (var session in sessions) {
myStorage.addTrainingSessionToHistory(session);
}
*/
}

Row setAsDefaultUnitsSwitch() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('Set as Default Units for Me'),
Switch(
activeTrackColor: mediumGreen,
value: setAsStandard,
onChanged: (bool value) {
setState(() {
setAsStandard = value;
});
},
),
],
);
}

DropdownButtonFormField<DistanceUnits> distanceSelectDropdown() {
return DropdownButtonFormField<DistanceUnits>(
decoration: const InputDecoration(labelText: 'Distance Unit'),
value: units.preferredDistanceUnit,
onChanged: (DistanceUnits? newValue) {
setState(() {
units.preferredDistanceUnit = newValue!;
});
},
items: DistanceUnits.values.map((DistanceUnits unit) {
return DropdownMenuItem<DistanceUnits>(
value: unit,
child: Text(unit.text),
);
}).toList(),
);
}

Widget massSelectDropdown() {
return DropdownButtonFormField<MassUnits>(
decoration: const InputDecoration(labelText: 'Mass Unit'),
value: units.preferredMassUnit,
onChanged: (MassUnits? newValue) {
setState(() {
units.preferredMassUnit = newValue!;
});
},
items: MassUnits.values.map((MassUnits unit) {
return DropdownMenuItem<MassUnits>(
value: unit,
child: Text(unit.text),
);
}).toList(),
);
}

MyGenericButton fileSelectButton(BuildContext context) {
return MyGenericButton(
label: (filepathORfileStr == null) ? "Select file to Import" : "File Selected.",
onPressed: () async {
filepathORfileStr =
await getFileWithSnackbarErrors(context, ['csv', 'txt', 'json']);
setState(() {});
},
color: (filepathORfileStr == null) ? darkTan : mediumGreen,
);
}

DropdownMenu<String> originAppSelector() {
return DropdownMenu(
hintText: "Pick an app to import from",
initialSelection: OtherTrainingApps.strong.text,
width: double.infinity,
dropdownMenuEntries: <DropdownMenuEntry<String>>[
DropdownMenuEntry(
value: OtherTrainingApps.strong.text,
label: "Strong App",
),
const DropdownMenuEntry(
value: "Submit a github ticket w/ an example file to import.",
label: "Submit a github ticket w/ an example file to import.",
),
],
);
}

void runImport() {
if (filepathORfileStr == null) {
ScaffoldMessenger.of(context)
.showSnackBar(const SnackBar(content: Text('No file selected')));
return;
}

List<TrainingSession> sessions;
if (originApp == OtherTrainingApps.strong) {
try {
sessions = importStrongCsv(filepathORfileStr!, units);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
'Failed to import. Is the file malformed? Did you select the correct App')));
return;
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Select a valid App to import from.')));
return;
}

if (setAsStandard) {
var userInfoCubit = context.read<BasicUserInfoCubit>();
BasicUserInfo userInfo = userInfoCubit.state;
userInfo.preferredDistanceUnit = units.preferredDistanceUnit;
userInfo.preferredMassUnit = units.preferredMassUnit;
userInfoCubit.set(userInfo);
}
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) =>
ImportInspectionPage(newTrainingSessions: sessions)));
}
}

enum OtherTrainingApps {
strong('Strong');

const OtherTrainingApps(this.text);
final String text;
}
Loading

0 comments on commit f380a22

Please sign in to comment.