exerlog / exer_log Goto Github PK
View Code? Open in Web Editor NEWexer_log - authored by @KalleHallden
License: MIT License
exer_log - authored by @KalleHallden
License: MIT License
Since you've included your google-services.json
file in the repo, which contains your API key:
https://github.com/KalleHallden/exer_log/blob/3893b56325da513b9fff304d97911d6b58509979/app/exerlog/android/app/google-services.json#L38-L42
you might want to consider adding restrictions to this key:
https://stackoverflow.com/a/57067722
Also, remember: once you publish your key, you can no longer treat it as private, even if you remove it from the repo.
Whene creating a New Worckout after providing the name of it
i get an exception that says the following:
(the file that has the Exeption is this one)
It not a big thing but you should remove or replace this line from the README
from
CD into the project
cd exer_log/app/exerlog
to
CD into the project
cd exer_log
because the app source code is no longer inside of the app/exerlog
Steps to reproduce:
Current: Nothing happens
Expected: I should be able to see workout for that day
When you initially uploaded all the code, the flutter folder on your local machine has a .git folder inside, causing now a flutter folder that's seems empty and has that little icon in the github view.
I recommend to delete the .git folder inside the flutter folder and to commit-push again the contents of that folder, in case you don't want the content to be public on the repo, just add it to the .gitignore.
Problem:
When multiple workouts are logged for the same day, there is no indication on the day (or the subsequent page when the day is clicked) that there is more than one workout logged. It appears that the subsequent page (set_widget) only displays that last workout information.
Should each workout on the same day be displayed on the same page, one after the other?
Should the Totals
data at the top be a grand total of all workouts?
We should future-proof the way we use colours in the app so that, if we want, we can easily add themes in the future. linked to PR #94
There are some minor warnings in application code can i remove that..
For any unexpected issue, we can show the Generic Error Screen. We can also add some generic error widgets.
Problem:
Suggestion:
The template
should be separate from the original workout it was created from. The template should remain even when the workout is deleted.
Might also need a 'manage template' page to allow create/edit/delete of templates.
Steps to reproduce:
Expected: After login, the user should navigate to the Workout screen
It would be a good enhancement to create some common base classes/simple API for your AlertDialogs, so that much repeated, similar, mostly design boilerplate code can be eliminated from various places.
In the end we can go, for example, from this:
The entire DeleteWorkoutAlert.class
Plus
showDeleteWorkoutAlertDialog(BuildContext context) {
RaisedGradientButton okButton = RaisedGradientButton(
gradient: LinearGradient(
colors: <Color>[Color(0xFF34D1C2), Color(0xFF31A6DC)],
),
radius: 30,
child: Text(
"DELETE",
style: buttonTextSmall,
),
onPressed: () {
deleteWorkout(workoutData.workout);
Navigator.of(context).pop();
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => CalendarPage(
),
),
);
},
);
// set up the AlertDialog
DeleteWorkoutAlert alert = DeleteWorkoutAlert(okButton);
// show the dialog
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
To just these few lines of code
showDeleteWorkoutAlertDialog() async {
final response = await showConfirmationDialog(title: 'Are you sure you want to delete this workout?');
if(response) {
// Delete workout
// Navigate
}
}
Like this we can eliminate some then redundant classes, and greatly cleanup the code that is inside the Pages calling for AlertDialogs
Problem:
The textfield
on this page is the template name
. The textfield is enabled even when the checkbox for Save as template
is disabled. This may cause confusion to some, as the hintText
for the textfield even says name your workout
.
Suggestion:
template name
or name of template
.It would be much better if there would be a function (void doSomething() { ... }
) instead of leaving a function logic inside of a widget
// Instead of:
TextButton(
child: const Text("Click Me"),
onPressed: () { ... },
)
// Do:
// somewhere in the widget scope..
void doSomething() { ... }
// Widget body
TextButton(
child: const Text("Click Me"),
onPressed: doSomething,
)
When pressing the logout button you immediately get logged out instead of getting a "are you sure" popup first.
How are we planning to make sure, people can add others as reviewers? I can't add anyone for review. Given we have a structure in place, we should have the option to add people as reviewers.
Now there is no check to see if you entered an empty workout name. This might cause some issue later on. Also check on duplicate workout names. The dropdown button expects every dropdown menu item to have a unique value, so it break when you have multiple items of the same value. This is how it looks when I added multiple workouts with no name.
Maybe it would be a good idea to run dart format for the whole project before making every pull request, this way the formatting is the same across the app. Currently the problem is that every contributor has different formatters, line lengths etc., which makes it harder when reviewing pull requests to see what are the actual changes, and what is just the formatting changing.
I think we should put Git on the main directory where the .README
file exists. so that when users come to the repo get a gist of the project and can read the DOCS we want them to read.
so instead of going to /app/exerlog
user sees the project after cloning the project
. notice that we clone a repo it automatically will be extracted within a directory with the same name as the repo name
and also it would be great to add a explicit steps to run the app for the sake of running the app easier; so that they can follow the process of installation based on a guide.
Hey, always been lurking in your videos and took a quick look at the codebase. I think the net biggest improvement will be done by just adding lints.
There are a couple of different approaches but new projects use flutter_lints which does the job quite well. This would just be a tedius change as there will probably be a lot of small issues that needs to be resolved but should still be very simple and straight forward.
Keep making great videos 😊
We need to setup CODEOWNERS
file to properly distribute for the maintainer/s
When pressing the Google sign in button the app breaks.
This bug is fixed when signing in with Google works. Work on this in the Login branch
@KalleHallden I was thinking it would be good if we can add firebase distribution for bunch of testers/contributors. It is super simple, I am pasting a yaml file that I use for almost all my projects.
name: Android Firebase CI
'on':
push:
branches:
- stable
pull_request:
branches:
- stable
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: set up JDK v11
uses: actions/setup-java@v1
with:
java-version: 12
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v1
with:
channel: 'beta'
- run: flutter pub get
# Build apk.
- run: flutter build apk --debug #add you firebase command if it is different
- name: upload artifact to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@master
with:
appId: '${{secrets.FIREBASE_APP_ID}}'
token: '${{secrets.FIREBASE_TOKEN}}'
groups: group1 #<GROUP NAME>
file: build/app/outputs/flutter-apk/app-debug.apk
@KalleHallden It might be a good idea to implement Firebase Crashlytics and Performance monitoring. These will give you good insight about your app on the Firebase console.
Here is some sample code for implementing Crashlytics, it looks pretty simple:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Pass all uncaught errors from the framework to Crashlytics.
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
runApp(MyApp());
}
This error appears on the excercise_card.dart page-
The following assertion was thrown during a scheduler callback:
There are multiple heroes that share the same tag within a subtree.
Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), each Hero must have a unique non-null tag.
In this case, multiple heroes had the following tag: <default FloatingActionButton tag>
Here is the subtree for one of the offending heroes: Hero
tag: <default FloatingActionButton tag>
state: _HeroState#81812
When the exception was thrown, this was the stack:
#0 Hero._allHeroesFor.inviteHero.<anonymous closure> (package:flutter/src/widgets/heroes.dart:271:11)
#1 Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:282:8)
#2 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:301:11)
#3 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6202:14)
#4 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#5 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:4859:14)
#6 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#7 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6202:14)
#8 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#9 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:4859:14)
#10 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#11 SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6202:14)
#12 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#13 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:4859:14)
#14 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#15 MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6314:16)
#16 Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:316:15)
#17 ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:4859:14)
......
#61 HeroController._maybeStartHeroTransition.<anonymous closure> (package:flutter/src/widgets/heroes.dart:884:11)
#62 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1146:15)
#63 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1091:9)
#64 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:997:5)
#68 _invoke (dart:ui/hooks.dart:151:10)
#69 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#70 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
code which gives error is-
FloatingActionButton(
heroTag: null,
elevation: 0,
backgroundColor: Colors.transparent,
child: Icon(
Icons.add,
size: 50,
color: backgroundColor,
),
onPressed: addSet,
),
we need to define a unique heroTag for every exercise card.
When finishing a workout you go to the calendar page. But the problem is that you can then navigate back using the back arrow to the workout you just finished (I assume this is not intended seeing as we already finished and saved this workout at this moment).
Also when pressing the back button on the workout page, we do a pop and then push to the calendar screen. This looks visually confusing because we press back, but it looks like a new page gets pushed onto the screen.
My suggestion is to change the navigation flow so when you go from the calendar page to the workout page we do this with a push instead ( its a push replace now) this way we can just pop when pressing the back button. Same for when we save the session we can just pop back to the calendar page. This way we don't have the problem where we can navigate back to a already finished session.
noNetworkConnectionSnackBar.dart
currently contains the following code:
import 'package:exerlog/UI/global.dart';
import 'package:flutter/material.dart';
SnackBar noNetworkConnectionSnackBar() => SnackBar(
backgroundColor: redBackgroundColor,
duration: Duration(
days:
365), // set to a year so that it doesn't disappear automatically untill the user clicks on the Dismiss button
content: Text('No network connection, please check your connection'),
action: SnackBarAction(
textColor: textColorBlue,
label: 'Dismiss',
onPressed: () {},
),
);
redBackgroundColor
and textColorBlue
do not exist in global.dart
Currently when you open the workout page you show a future builder which contains a loading indicator while loading. When it is loaded you then show the actual page. The problem is that only the loaded page contains a scaffold, the error and loading states of this page do not contain a scaffold. This causes some visual problems when loading the page because it flashes black for a moment while loading. Also when an error gets shown it looks like the image below. My suggestion is to show the things we can show without the data like the background, appbar etc. And then just put the loading indicator over the part of the page that actually needs the data that is loading.
Hi,
I think it would be useful to have a discussion section, so other contributors can discuss about the project.
I would like to suggest using mergeable to enforce coding standards. In my experience, this will help in maintaining the codebase.
Logging in
Signing up
This issue is done when all of the above is completed. This feature should be worked on in the branch Login
If we have a splash screen then we can check
From the design side, I am thinking: A screen with Logo and App Name in the middle. The background color is our app's primary background color.
Just some general improvements that I thing would future proof the app.
I recently checked the project and there are so many unused imports is it necessary or can we just remove them?
I suggest to add a convention for the commit messages to ensure explicit commit messages. This makes it easier to create automated changelogs and other things.
I have used conventional commits including git hooks to validate the commit messages during every commit.
There are also other convetions for commits. The important thing is to use 1 convention consistently.
Hi @KalleHallden I know that login feedback for users were raised in that PR
but for seucrity reasons i think will be good to use OWASP recommendations for that kind of labels (ie: dont inform user that used credentials match/dont match to existing accout)
source of correct and incorrect responses
E/flutter ( 6690): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(sign_in_failed, com.google.android.gms.common.api.ApiException: 10: , null, null)
E/flutter ( 6690): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
E/flutter ( 6690): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
E/flutter ( 6690): <asynchronous suspension>
E/flutter ( 6690): #2 MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:367:43)
E/flutter ( 6690): <asynchronous suspension>
E/flutter ( 6690): #3 GoogleSignIn._callMethod (package:google_sign_in/google_sign_in.dart:248:30)
E/flutter ( 6690): <asynchronous suspension>
E/flutter ( 6690): #4 GoogleSignIn.signIn.isCanceled (package:google_sign_in/google_sign_in.dart:378:5)
E/flutter ( 6690): <asynchronous suspension>
E/flutter ( 6690):
Getting this error when trying to google sign in.
As mentioned in this stackoverflow answer, we need to add debug SHA-1 keys of developers to the firebase project. How can that be done?
Hi,
It seems that the repo doesn't have a README.md and LICENSE and .gitnore. So It would be useful to have those files for new contributors to know what the project is about and etc...
I wanted run this application for the first time, so I installed flutter from https://docs.flutter.dev/get-started/install/linux, next run all steps from Development section, then run:
flutter run
Launching lib/main.dart on Chrome in debug mode...
../../snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_riverpod-1.0.3/lib/src/framework.dart:275:26: Warning: Operand of null-aware operation '!' has
type 'SchedulerBinding' which excludes null.
- 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('../../snap/flutter/common/flutter/packages/flutter/lib/src/scheduler/binding.dart').
if (SchedulerBinding.instance!.schedulerPhase ==
^
of course Chrome with debug mode started, but stopped with error on console:
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ #0 packages/exerlog/src/utils/logger/logger.dart 29:58 info
│ #1 packages/exerlog/src/utils/logger/riverpod_logger.dart 13:9 didUpdateProvider
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ 💡 {
│ 💡 "provider": "FutureProvider<FirebaseApp>",
│ 💡 "newValue": "AsyncError<FirebaseApp>(error: Assertion failed:
file:///home/developer/snap/flutter/common/flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-1.7.1/lib/src/firebase_core_web.dart:207:11
│ 💡 options != null
│ 💡 "FirebaseOptions cannot be null when creating the default app.", stackTrace: dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_
│ 💡 dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3 assertFailed
│ 💡 packages/firebase_core_web/src/firebase_core_web.dart 207:18 initializeApp
│ 💡 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50 <fn>
│ 💡 dart-sdk/lib/async/zone.dart 1685:54 runUnary
│ 💡 dart-sdk/lib/async/future_impl.dart 147:18 handleValue
│ 💡 dart-sdk/lib/async/future_impl.dart 766:44 handleValueCallback
│ 💡 dart-sdk/lib/async/future_impl.dart 795:13 _propagateToListeners
│ 💡 dart-sdk/lib/async/future_impl.dart 566:5 [_completeWithValue]
│ 💡 dart-sdk/lib/async/future.dart 527:22 <fn>
│ 💡 dart-sdk/lib/async/zone.dart 1685:54 runUnary
│ 💡 dart-sdk/lib/async/future_impl.dart 147:18 handleValue
│ 💡 dart-sdk/lib/async/future_impl.dart 766:44 handleValueCallback
│ 💡 dart-sdk/lib/async/future_impl.dart 795:13 _propagateToListeners
│ 💡 dart-sdk/lib/async/future_impl.dart 566:5 [_completeWithValue]
│ 💡 dart-sdk/lib/async/future_impl.dart 639:7 callback
│ 💡 dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
│ 💡 dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
│ 💡 dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
│ 💡 )"
│ 💡 }
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following TypeErrorImpl was thrown building MyApp(dirty, dependencies:
[UncontrolledProviderScope], state: _ConsumerState#c34bc):
Expected a value of type 'String?', but got one of type 'AssertionErrorImpl'
The relevant error-causing widget was:
MyApp MyApp:file:///home/developer/git-repos/exer_log/lib/main.dart:44:14
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 84:3 castError
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 452:10 cast
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart 367:9 as
packages/exerlog/main.dart 87:15 <fn>
packages/riverpod/src/common.dart 265:26 <fn>
packages/riverpod/src/common.dart 391:17 [_map]
packages/riverpod/src/common.dart 263:12 AsyncValueX.when
packages/exerlog/main.dart 62:22 build
packages/flutter_riverpod/src/consumer.dart 371:19 build
packages/flutter/src/widgets/framework.dart 4919:27 build
packages/flutter_riverpod/src/consumer.dart 431:20 build
packages/flutter/src/widgets/framework.dart 4806:15 performRebuild
packages/flutter/src/widgets/framework.dart 4977:11 performRebuild
packages/flutter/src/widgets/framework.dart 4529:5 rebuild
packages/flutter/src/widgets/framework.dart 2659:18 buildScope
packages/flutter/src/widgets/binding.dart 891:9 drawFrame
packages/flutter/src/rendering/binding.dart 370:5 [_handlePersistentFrameCallback]
packages/flutter/src/scheduler/binding.dart 1146:15 [_invokeFrameCallback]
packages/flutter/src/scheduler/binding.dart 1083:9 handleDrawFrame
packages/flutter/src/scheduler/binding.dart 997:5 [_handleDrawFrame]
lib/_engine/engine/platform_dispatcher.dart 1090:13 invoke
lib/_engine/engine/platform_dispatcher.dart 160:5 invokeOnDrawFrame
lib/_engine/engine/initialization.dart 194:45 <fn>
════════════════════════════════════════════════════════════════════════════════════════════════════
Application finished.
of course this is my first run, and maybe I should install some additional libs (or make additional config) to avoid these errors
I found some article connected with initialization of firebase in app, maybe it will help: https://fluttercorner.com/firebaseoptions-cannot-be-null-when-creating-the-default-app/
I think that we should have a workflow in this repo which will automatically create new release on every pull request merged into
main branch. but we have to follow some strict steps to implement this
dev
branch and set it to defaultconventional commits
eg:- feat(login): ✨ added feedback for users
semantic release
for creating new release (this is help in automatically create release)I can implement the workflow. but asking for permission to do so
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.