Skip to content

yuriisurzhykov/Purs-Android

Repository files navigation

Android Lint Checker Tests check

About

Purs-Android is an android version of the test application which is concidered as a "Take Home Assignment"

Requirements

Requirements

Data Layer

Connection

  • The application must have connection to the internet to retrieve the working hours
  • If no connection, the error should be displayed notifying user that he has no connection to the internet
  • If connection lost during request, the error should be displayed notifying a user that connection to the endpoint failed
  • If there is no connection or the connection is lost while retrieving data from a remote computer, the cached data, if any, should be displayed

Cache

  • When application successfully retrieved the data from remote that data should be persisted on the device for further usage if needed
  • Every time user opens application the cache should be updated in order to keep data fresh

Data format

Cloud

The JSON structure contains location structure so the DTO for location should be created with the following fields

  • Location name –String
  • List of working days –Collection

The working day structure should contain the following fields:

  • Day of week –String
  • Start local time –String
  • End local time –String

Cache

The cached structure should be similar to the cloud. There should be 2 entities: location and * working hours*. The location structure should contain location id which can be an integer, and the location name which is the String.

Location

  • LocationIdInt
  • LocationNameString

Working hours

  • WorkDayNameString
  • StartTimeString
  • EndTimeString
  • LocationIdInt (a foreign key pointing a location associated with it)

Business requirements

General statements

  • The main use of this application is to show the user the operating hours of a specific business point (location).
  • The user may open application with or without internet in the local country and the application should display information for the working hours for a specific business (location)
  • User should be able to see if the location is open now, or closed, or closes within an hour
  • Different labels should be displayed for different edge cases:
    • "Open until {time}" – if the location is opened when user is viewing information
    • "Open until {time}, reopens {next time}"– if the location is open now, but it may be closed within an hour
    • "Opens again {next time}" – if the location is closed but will be opened in less than 24 hours
    • "Opens {day} {time}" – if the location is closed and will not be opened in 24 hours
  • The color indicator should be present on the location info
    • If the location is opened – 🟢
    • If the location closes within an hour – 🟡
    • If the location is closed – 🔴
  • The time format should be the local either 24h or 12h

Data format

  • All operation hours should be grouped in one day. This means that if JSON file contains same day name but different hours of work they have to be displayed in one row.
    For example, instead of displaying:
    Monday: 10am-12pm
    Monday: 5pm-9pm
    The application should display: Monday: 10am-12pm, 5pm-9pm

Edge Cases

Single time per day

If there is only one time slot for the day the only one time segment should be displayed:

{
  "day_of_week": "MON",
  "start_local_time": "09:00:00",
  "end_local_time": "17:00:00"
}

Multiple Time Segments per Day

If the JSON structure contains more than 1 section for the same date the time slots should be combined and should be displayed in a single section:

{
  "day_of_week": "MON",
  "start_local_time": "09:00:00",
  "end_local_time": "12:00:00"
},
{
"day_of_week": "MON",
"start_local_time": "13:00:00",
"end_local_time": "17:00:00"
}

For the example above the: Monday: 9am-12pm, 1pm-5pm should be displayed

Late-Night Hours

  • Open Until Midnight
{
  "day_of_week": "MON",
  "start_local_time": "09:00:00",
  "end_local_time": "24:00:00"
}

This JSON should be converted to "Open until midnight"

  • Open Until Early Morning Open until early morning means that the location opens one day and continues to operate at night the next day. The JSON would looks the following way:
{
  "day_of_week": "MON",
  "start_local_time": "09:00:00",
  "end_local_time": "24:00:00"
},
{
"day_of_week": "TUE",
"start_local_time": "00:00:00",
"end_local_time": "02:00:00"
}

[!NOTE]
This case only works if the work time is continuous, that is, there is no break between the end of one day's work and the start of another day. In this case 2am time belongs to Monday and it counts that Tuesday is not working day and should be displayed as closed the whole day unless no other working hours for this particular day.

Open 24 hours

The location may be opened 24 hours for the day if start_local_date is 00:00 and the end_local_date is 24:00. The "Open 24 hours" has to be displayed.

{
  "day_of_week": "MON",
  "start_local_time": "00:00:00",
  "end_local_time": "24:00:00"
}

Closed Entire Day

{
  "day_of_week": "MON",
  "start_local_time": "00:00:00",
  "end_local_time": "00:00:00"
}

Or no schema for the day, so that list of time slots is empty.

UI Design

UI Design

The primary source of design requirements is the Figma document

Background

The background of application screen is the image. There is no specific requirements, so it can either be used as asset or may be downloaded for user.

Decision:

In order to reduce the load on the network and avoid unnecessary calls to the network, it would be better to use an image as an asset croped for different screen sizes.

Location selection

In the example JSON structure the only one location is available and the structure of JSON at the moment does not imply that more than one location will be sent, which means at the moment, we can limit ourselve to only one location at a time. In the future if need more than one location be available for user, the location details screen remains unchanged with only few changes: the use case to fetch location details needs to be modified and the location ID has to be passed to the use case.

Location screen

Components:

  • Title: The title is the location name. Should have the Title 1 style. Aligned to the top of parent and stretched to the width of screen.
  • Working hours dropdown menu.
    • Aligned to the bottom of Title.
    • Displayes "Open ..." label based on the requirements
    • Color bullet indicator to visualise the current status of location
    • "See more hours" label to hint the user that more hours available to see

Working hours selection

  • When user clicks the dropdown menu the previous content should remain unchanged but menu must drops down.
  • Working days should be aligned the following way:
    • Name of the day aligned to the right
    • Hours aligned to the left. If more than one time slot available for the day, it should appear right under the first time occurence.
  • It's better to animate dropdown effect to make the UI smooth
Architecture design

Architecture design

Multimodule Structure

A multimodule architecture allows splitting the project into independent modules, improving maintainability, testability, and build speed. The proposed structure:

  • core: This module contains abstract components such as dispatchers, mapper interfaces and everything that can be shared between different modules.
  • app: The main application module that ties together all other modules.
  • data: The module for managing data (cloud and cache).
  • domain: The module for business logic and use cases.
  • presentation: The module for UI and ViewModel.

Module Structure

app Module

The main entry point of the application. Dependencies on other modules (data, domain, presentation). Dagger Hilt configurations for dependency injection.

data Module

Submodules:

  • cloud: Handling network requests (Ktor or Retrofit).
  • cache: Handling database operations (Room).
  • Repository: Combining data from cloud and cache (should not be a separate module, it can be located in main source set)

domain Module

Use cases

Business logic and data formatting

  • Use case to build proper workdays list
  • Use case to format date and time
  • Use case to build current working day details (have to be triggered every minute to keep the current information up to date for the user)

Entities

Business data models.

Business layour have to contain 3 structures:

  • Location
    • Location name
    • List of workdays (always 7 items length)
  • WorkDay
    • WorkingHour (might be a list of strings or Empty if no working hours fetched from cloud for the day)
  • CurrentWorkDay
    • Open status: { OpenUntil(time), ClosesWithinHour(next open time), ClosedOpensNextDay(open time), Closed(next open day, next open hours) }

presentation Module

  • ViewModel: Managing UI state.
  • UI: User interface components (SwiftUI for iOS and Jetpack Compose for Android).
Technology stack

Technology stack

Fetching data from cloud

The application must talk to the server to receive location details. The most advanced libraries for working with the network are:

When choosing between these two libraries, preference is given to Retrofit due to its simplicity and ease of configuration in a native android project.

Data persistence

For data persistence there are a bunch of libraries either SQL or NoSQL. The most popular libaries for data persistence for native android application are the following:

Choosing between these libraries the easiest and the fast-to-implement solution would be Android Room so the decision is to take Android Room to cache the cloud data

Concurrency

Taking into account that the Application is an Android app which will be written fully in Kotlin, Kotlin Coroutines will be used for the concurrency.

UI Framework

The requirements for the application is to write UI using Jetpack Compose so the Compose will be used for the UI part of application.

Build application locally

Create a keystore file

(if you want to make a debug build, you may skip this section)

First of all you need to generate a keystore file with .jks extension

Create signing.properties file in project

After you created a keystore file you have to create a signing.properties file in root folder of the project. The content of the file should be the following:

keystoreFile=purs_android_key.jks
keystorePassword=Purs2024
keyAlias=purs
keyPassword=Purs2024

NOTE: You can leave all variables empty if you just want to make a debug build

TODO Next

What TO DO next

Several enhancements are needed to finish the task:

  • Update the current location status periodically to keep information up to date for the user #44
  • Fix expand arrow animation which turns wrong angle if user clicks too fast #45
  • Blur the background when user expand the location hours section #46
  • Edge-to-edge stoped working properly, need to fix it #47
  • Fix working hours alignment on expandable section #48

Contacts

Email: yuriisurzhykov@gmail.com