Foodie
Foodie is a simple application displaying restaurants nearby the user.
Screenshots
Features
Restaurants page view
Package com.example.foodie.pages.restaurantspage
RestaurantsPageView
displays restaurants page with a vertical list of restaurants.
RestaurantsPageViewModel
controls this view by exposing UI state and UI event callbacks.
Fetching new restaurants page
Each time CurrentLocationProvider
provides a new location, the view model sends a request
for new restaurants using RestaurantsPageRepository
. On retry click the same request is made.
Saving restaurants in favorites
A restaurant can be added to favorites by pressing the heart button. The view model calls
FavoritesRepository
to change favorites state and read it.
Global application timer
Package com.example.foodie.timer
AppTimer
is global timer for the application that is started for the first time when the
application is initialized in onCreate
in MainActivity
. Since that moment every second
it emits tics in a SharedFlow
with strategy SharingStarted.Eagerly
so all observers
will get only the most recent tic.
Timer is paused and resumed by MainActivity
when the application is backgrounded and
foregrounded to prevent the application from running processes in the background.
Other components can listen to this flow to perform actions that need to be performed repeatedly in some interval. Example can be found here: Current location provider.
Testing
Turbine was used for testing Flow
.
Current location provider
Package com.example.foodie.location
CurrentLocationProvider
is global provider for the current location of the device.
It listens to AppTimer
‘s tics and transforms this flow to a flow of locations. New location
is fetched from LocationRepository
and emitted only every 10 seconds.
Similarly to AppTimer
it exposes SharedFlow
of locations which is shared with
the SharingStarted.Eagerly
strategy. It also replays the latest value for each new
subscriber, so they don’t need to wait until a new location is emitted.
Location repository
Currently implementation of this repository is mocked to fixed list of 10 predefined locations.
Splash screen to app bar transition
Package com.example.foodie.pages.shared
SplashAppBar
can be both the splash screen and the application top bar. When shown as the
splash screen it displays the initial enter animation created using AnimatedVisibility
.
When the data is loaded for the first time and the application is initialized then the splash
screen transforms to the app bar using MotionLayout
.
Retry view animations
Package com.example.foodie.pages.shared
RetryView
displays an animation transforming the Foodie logo to a broken one. It uses
animate*AsState
to move elements and Crossfade
to create smooth transition
between the icons.
Dark theme
Foodie is also adjusted to work in dark mode. Different color palettes for light and dark mode
are defined in the Theme.kt
file.
Application config
Package com.example.foodie.model
The behaviour of the application can be adjusted by modifying AppConfig
.
Currently it’s hardcoded but ideally it should be received from backend when the application is launching.
Detekt
The whole project has detect configured in detekt.yml
. It also uses wrapper over
ktlint provided by detekt as a formatting
rule set.
Contributions
Restaurant data is provided by Wolt API.
Foodie logo icon was created by Freepik – Flaticon.
Restaurant placeholder was created by Ali Inay.