-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Compass App: Activities screen, error handling and logs #2371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…2359) This PR introduces two new subprojects: - `compass_server` under `compass_app/server`. - `compass_model` under `compass_app/model`. **`compass_server`** - Dart server implemented using `shelf`. - Created with the `dart create -t server-shelf` template. - Implements two REST endpoints: - `GET /continent`: Returns the list of `Continent` as JSON. - `GET /destination`: Returns the list of `Destination` as JSON. - Generated Docker files have been removed. - Implemented tests. - TODO: Implement some basic auth. **`compass_model`** - Dart package to share data model classes between the `server` and `app`. - Contains the data model classes (`Continent`, `Destination`). - Generated JSON from/To methods and data classes using `freezed`. - The sole purpose of this package is to host the data model. Other shared code should go in a different package. **Other changes** - Created an API Client to connect to the local dart server. - Created "remote" repositories, which also implement a basic in-memory caching strategy. - Created two dependency configurations, one with local repositories and one with remote repos. - Created two application main targets to select configuration: - `lib/main_development.dart` which starts the app with the "local" data configuration. - `lib/main_staging.dart` which starts the app with the "remove" (local dart server) configuration. - `lib/main.dart` still works as default entry point. - Implemented tests for remote repositories. - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. <!-- Links --> [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md WIP implement activity repository local wip activity repository updates and iOS stuff implement navigation logic to activities implement tests fixing navigation with query parameters refactor search queries cleanup and comments cleanup add ItineraryConfig, refactor SearchScreen to use it fix tests refactor with Commands refactor commands add progress indicator to commands simplify command command tests cleanup simplify activity repository cleanup cleanup cleanup fix comment should be Command0 refactor assets, server, and add activities endpoint fix assets refactor wip activities screen add error state to commands Added comments handle errors in Command add comments WIP error indicator widget lifecycle wip activities and error handling Add random errors to repositories to simulate recovering from errors implement activites WIP tests create test activities screen finish Activities UI
compass_app/app/lib/data/repositories/continent/continent_repository_local.dart
Outdated
Show resolved
Hide resolved
compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart
Outdated
Show resolved
Hide resolved
List<Activity> get daytimeActivities => _daytimeActivities; | ||
|
||
/// List of evening [Activity] per destination. | ||
List<Activity> get eveningActivities => _eveningActivities; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit / nonblocking comment:
I've recently learned about UnmodifiableListView, and I think this is the perfect place to use it :)
/// List of daytime [Activity] per destination.
UnmodifiableListView<Activity> get daytimeActivities => UnmodifiableListView(_daytimeActivities);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will give it a try!
compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart
Outdated
Show resolved
Hide resolved
compass_app/app/lib/ui/activities/widgets/activities_header.dart
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One higher level consideration for the future: Should String's that are displayed in UI be put in a class somewhere as constants?
All my comments are nits, and otherwise it looks good to me.
Agreed, I will do that for the next PR |
I have created an Maybe I missed a String or two, but works as a base for future localizations if we want to ;) |
LGTM, feel free to merge at your leisure! |
This PR introduces the Activities screen, handling of errors in view models and commands, and logs using the dart
logging
package.Activities
/destination/<id>/activitity
which was missing before.Screencast provided:
Screencast.from.2024-07-29.16-29-02.webm
Error handling
UI Error handling:
In the screencast you can see a
SnackBar
appearing, since the "Confirm" button is not yet implemented.The
saveActivities
Command returns an errorResult.error()
, then the error state is exposed by the Command and consumed by the listener in theActivityScreen
, which displays aSnackBar
and consumes the state.Functionality is similar to the one found in UI events - Consuming events can trigger state updates from the Android architecture guide, as the command state is "consumed" and cleared.
The Snackbar also includes an action to "try again". Tapping on it calls to the failed Command
execute()
so users can run the action again.For example, here the
saveActivities
command failed, soerror
istrue
. Then we call toclearResult()
to remove the failed status, and show aSnackBar
, with theSnackBarAction
that runssaveActivities
again when tapped.Since commands expose
running
,error
andcompleted
, it is easy to implement loading and error indicator widgets:Screencast.from.2024-07-29.16-55-42.webm
As side node, we can easily simulate that state by adding these lines in any of the repository implementations:
In-code error handling:
The project introduces the
logging
package.In the entry point
main_development.dart
the log level is configured. Then in code, aLogger
is creaded in each View Model with the name of the class. Then the log calls are used depending on theResult
response, some finer traces are also added.By default, they are printed to the IDE debug console, for example:
Other changes
app/assets/
folders, and the server is querying those files instead of their own copy. This is done to avoid file duplication but we can make a copy of those assets files for the server if we decide to.TODO Next
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-devrel channel on Discord.