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.

GitHub

View Github