Skip to content
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

Feature/pr task #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Feature/pr task #1

wants to merge 3 commits into from

Conversation

patrykserek
Copy link
Collaborator

@patrykserek patrykserek commented Feb 18, 2025

Please review this PR at your your leisure. We expect this review to take under 30 minutes, but feel free to take as much or as little time as you want.

Focus on all the areas of code quality you feel important, treat it as a code a colleague in your project pushed to a repo you contribute to.

implementation(libs.retrofit.kotlinx.serialization.converter)
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to libs.versions.toml

@@ -4,13 +4,18 @@ import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFact
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import okhttp3.MediaType
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import

private val json = Json {
ignoreUnknownKeys = true
isLenient = true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is crucial change and it's not directly connected with "logging".
Why do we need lenient mode?

import retrofit2.Retrofit

class ApiService {

private val contentType = MediaType.get("application/json")
private val contentType = "application/json".toMediaType()
private val client = OkHttpClient.Builder().addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)).build()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interceptor logs for any build type - it shouldn't log in release build

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#out-of-pr
ApiService - there are few things we can improve here :)

  • Strings ("application/json", "https://itunes.apple.com/") could be extracted to consts
  • ApiService could be an object - there's no point to create instances of this class other than obtaining ItunesService
  • Properties like contentType, client, json are only required to initialize service property.

I'd suggest to wrap it into methods and delegate service creation, e.g.:

val service: ItunesService = createItunesService()

private fun createItunesService() = {
    val httpClient = getHttpClient()
    val retrofit = getRetrofit(httpClient)
    return retrofit.create(ItunesService::class.java)
}

OR

We should consider using DI framework in order to provide such dependencies to consumers :)

Either way we should discuss it and do it in a separate task.

var selectedSong: Song? by remember { mutableStateOf(null) }
if (!detailsClicked) {
Column(Modifier.verticalScroll(rememberScrollState())) {
songs.forEach {
Copy link

@kacpr kacpr Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming songs can contain many items - LazyColumn will be a better component than Column (performance)

} else {
Column(modifier = Modifier.fillMaxWidth()) {
selectedSong?.let {
Text("What a great detalis page!")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"What a great detalis page!" should be moved to string resources

}
}
Button(onClick = { detailsClicked = false }) { Text("Back") }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Back" should be moved to string resources

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to extract parts of the layout to separate functions, to provide more readable structure.
E.g.:

fun SongListScreen(){
if(!detailsClicked){
    SongList()
} else {
    SongDetails()
    }
}

fun SongItem(){
}

@@ -2,5 +2,6 @@ package com.tooploox.androidrecruitmenttask

data class Song(
val title: String,
val artist: String
val artist: String,
val releaseYear: Int,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it have to be Int?

@kacpr
Copy link

kacpr commented Feb 20, 2025

I will add a summary here and some information about pr itself:

PR:

  1. Please utilize commit messages to provide some context - "foo" doesn't say a lot about changes 😉
  2. It would be nice to provide minimum information in pr description, like:
  • What's the essence of this pr?
  • Is there anything requiring special attention? (e.g. lenient mode)
  • Screenshot or video of UI changes would be nice 😉

Summary:

  • I think we should consider using DI framework
  • Readme.md mentions clean architecture while currently our project doesn't have any visible structure 😃
  • Approach to ViewModels - exposing UiState and dicuss about UiModels.
  • Approach to models and their transformations between layers

@kacpr
Copy link

kacpr commented Feb 21, 2025

Oh, two more things popped up:

  1. We should reformat code before committing changes (e.g. remove unused imports) - also we can think about some tool for static analysis :)
  2. UX - SongsScreen is empty if songs are null or empty. We should add a progress indicator and an handle "empty state" case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants