From d3600df5f2d120122839ebd578d92b81ee6a9544 Mon Sep 17 00:00:00 2001 From: Felix Holz Date: Mon, 12 Feb 2024 20:49:43 +0100 Subject: [PATCH] update readme --- README.md | 77 +++++++++++++++- .../firestore_activity_data_interface.dart | 89 ------------------- .../firestore_workout_data_interface.dart | 86 ------------------ 3 files changed, 76 insertions(+), 176 deletions(-) delete mode 100644 lib/backend/database/firebase/firestore_activity_data_interface.dart delete mode 100644 lib/backend/database/firebase/firestore_workout_data_interface.dart diff --git a/README.md b/README.md index 06d05ad9..b70201d3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,78 @@ # NeverSkip Fitness -Ever set a fitness goal and quit halfway through? NeverSkip keeps you motivated all the way through and helps you build healthy behaviors. +> Ever set a fitness goal and quit halfway through? NeverSkip keeps you motivated all the way +> through and helps you build healthy behaviors. + +Record your performance for every exercise and replace your old paper fitness logbook. Build your +own workout plan and get in shape! + +## Features + +NeverSkip puts you as the athlete in the center, and it is designed to support and motivate you in +achieving your goals. It doesn't matter if you want increase your bench press, lose or gain some +weight, achieve a new personal record, or just want to stay consistent with your workouts. +NeverSkip helps you to stay on track by providing a clear overview of your current performance and +progress, without losing sight of your long term goals. +The app is designed with usability as the main priority: no clutter, no complicated UI, no +unnecessary features. Just the tools you need to stay on track and motivated. + +*WORKOUT PLANNER* + +- Build your own individual workout plan with our easy to use workout planner. +- Select from more than 100 gym or calisthenics exercises, or add your own. + +*CALENDAR* + +- One swipe or tap away from the home screen +- The calendar shows you which exercises are scheduled for today - and the following days as well. +- Go to the gym, open the NeverSkip Calendar, and get to work. + +*PERFORMANCE TRACKING* + +- Log your performance for every exercise. This includes weight, reps, and sets. +- Also supports calisthenics exercises. +- See your performance from your last few workout sessions. +- Helps you to progressively overload the exercise see your improvements over time. + +*SOCIAL MEDIA SHARING* + +- Share an overview of your last workout to instagram stories or other social media platforms. +- Shows your time in the gym, your current workout streak, all exercises you did, and your + performance for each exercise. +- Optionally, you can chose to omit your performance data, if you don't feel comfortable sharing + that. + +*ACTIVITY CHART* + +- See on which weekdays you work out the most. +- Keeps you motivated to stay consistent. +- Looks cool if you have a consistent workout schedule. + +*GOALS AND ACHIEVEMENTS* + +- Set weight goals for specific exercises. +- See how far you have progressed, and how far you still have to go. +- You can be proud of completed goals - hey will be displayed as achievements after you complete + them. + +*CUSTOM COLOR THEME* + +- Different color schemes and dark modes should offer you an individual experience. + +## Development + +NeverSkip is developed with Flutter, and is available for Android and iOS. The app currently uses +Google Firebase as a backend, with an extremely fast custom caching layer on top, to get amazing app +startup times. +To get the app working with your own backend, have a look at the firebase implementation +at `lib/backend/database/firebase`. + +Build and run the app with the following commands: + +``` +flutter pub get +flutter run +``` + +For any questions, feel free to contact me or open an issue. + diff --git a/lib/backend/database/firebase/firestore_activity_data_interface.dart b/lib/backend/database/firebase/firestore_activity_data_interface.dart deleted file mode 100644 index 043cc7b3..00000000 --- a/lib/backend/database/firebase/firestore_activity_data_interface.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:frederic/backend/activities/frederic_activity.dart'; -import 'package:frederic/backend/database/frederic_data_interface.dart'; -import 'package:hive/hive.dart'; - -@Deprecated('only use for debugging') -class FirestoreActivityDataInterface - implements FredericDataInterface { - FirestoreActivityDataInterface( - {required this.firestoreInstance, required this.activitiesCollection}); - - final FirebaseFirestore firestoreInstance; - final CollectionReference> activitiesCollection; - - Box? _dataBox; - - @override - Future> reload() async { - if (_dataBox == null) _dataBox = await Hive.openBox('activities'); - await _dataBox!.clear(); - - List activities = []; - Map entries = {}; - - QuerySnapshot?> global = - await activitiesCollection.where('owner', isEqualTo: 'global').get(); - QuerySnapshot?> private = await activitiesCollection - .where('owner', isEqualTo: FirebaseAuth.instance.currentUser?.uid) - .get(); - - for (int i = 0; i < global.docs.length; i++) { - var doc = global.docs[i]; - if (doc.data() == null) continue; - FredericActivity activity = FredericActivity(); - activity.fromMap(doc.id, doc.data()!); - activities.add(activity); - entries[doc.id] = activity; - } - - for (int i = 0; i < private.docs.length; i++) { - var doc = private.docs[i]; - if (doc.data() == null) continue; - FredericActivity activity = FredericActivity(); - activity.fromMap(doc.id, doc.data()!); - activities.add(activity); - entries[doc.id] = activity; - } - _dataBox!.putAll(entries); - - return activities; - } - - @override - Future> get() async { - if (await Hive.boxExists('activities')) { - if (_dataBox == null) _dataBox = await Hive.openBox('activities'); - return _dataBox!.values.toList(); - } else { - return reload(); - } - } - - @override - Future create(FredericActivity object) { - return createFromMap(object.toMap()); - } - - @override - Future createFromMap(Map data) async { - DocumentReference> newActivity = - await activitiesCollection.add(data); - DocumentSnapshot> snapshot = await newActivity.get(); - if (snapshot.data() == null) - throw Exception('Creation of Activity has Failed!'); - return FredericActivity.fromMap(snapshot.id, snapshot.data()!); - } - - @override - Future delete(FredericActivity object) { - return activitiesCollection.doc(object.id).delete(); - } - - @override - Future update(FredericActivity object) async { - await activitiesCollection.doc(object.id).update(object.toMap()); - return object; - } -} diff --git a/lib/backend/database/firebase/firestore_workout_data_interface.dart b/lib/backend/database/firebase/firestore_workout_data_interface.dart deleted file mode 100644 index f896ce86..00000000 --- a/lib/backend/database/firebase/firestore_workout_data_interface.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:frederic/backend/backend.dart'; -import 'package:frederic/backend/database/frederic_data_interface.dart'; -import 'package:hive/hive.dart'; - -@Deprecated('only use for debugging') -class FirestoreWorkoutDataInterface - implements FredericDataInterface { - FirestoreWorkoutDataInterface( - {required this.firestoreInstance, required this.workoutsCollection}); - - final FirebaseFirestore firestoreInstance; - final CollectionReference> workoutsCollection; - - Box? _dataBox; - - @override - Future create(FredericWorkout object) { - return createFromMap(object.toMap()); - } - - @override - Future createFromMap(Map data) async { - DocumentReference> newWorkout = - await workoutsCollection.add(data); - DocumentSnapshot> snapshot = await newWorkout.get(); - if (snapshot.data() == null) - throw Exception('Creation of Activity has Failed!'); - return FredericWorkout.fromMap(snapshot.id, snapshot.data()!); - } - - @override - Future delete(FredericWorkout object) { - return workoutsCollection.doc(object.id).delete(); - } - - @override - Future> get() async { - if (await Hive.boxExists('workouts')) { - if (_dataBox == null) _dataBox = await Hive.openBox('workouts'); - return _dataBox!.values.toList(); - } else { - return reload(); - } - } - - @override - Future update(FredericWorkout object) async { - await workoutsCollection.doc(object.id).update(object.toMap()); - return object; - } - - @override - Future> reload() async { - if (_dataBox == null) _dataBox = await Hive.openBox('workouts'); - await _dataBox!.clear(); - - List workouts = []; - Map entries = {}; - - QuerySnapshot> global = - await workoutsCollection.where('owner', isEqualTo: 'global').get(); - - QuerySnapshot> private = await workoutsCollection - .where('owner', isEqualTo: FirebaseAuth.instance.currentUser?.uid) - .get(); - - for (int i = 0; i < global.docs.length; i++) { - var doc = global.docs[i]; - if (!doc.exists) continue; - FredericWorkout workout = FredericWorkout.fromMap(doc.id, doc.data()); - workouts.add(workout); - entries[doc.id] = workout; - } - for (int i = 0; i < private.docs.length; i++) { - var doc = private.docs[i]; - if (!doc.exists) continue; - FredericWorkout workout = FredericWorkout.fromMap(doc.id, doc.data()); - workouts.add(workout); - entries[doc.id] = workout; - } - _dataBox!.putAll(entries); - return workouts; - } -}