Code refactor

main
Hemanth S 2020-09-06 16:33:24 +05:30
parent 332c2dc69b
commit 8eb7859f30
6 changed files with 104 additions and 74 deletions

View File

@ -55,12 +55,13 @@ private val roomModule = module {
factory {
get<RetroDatabase>().playCountDao()
}
factory {
get<RetroDatabase>().historyDao()
}
single {
RealRoomRepository(get(), get(), get())
RealRoomRepository(get(), get(), get(), get())
} bind RoomRepository::class
}
private val mainModule = module {

View File

@ -16,7 +16,7 @@ import java.util.*
private const val BASE_QUERY_ARTIST = "search/artist"
private const val BASE_URL = "https://api.deezer.com/"
interface DeezerApiService {
interface DeezerService {
@GET("$BASE_QUERY_ARTIST&limit=1")
fun getArtistImage(
@ -26,7 +26,7 @@ interface DeezerApiService {
companion object {
operator fun invoke(
client: okhttp3.Call.Factory
): DeezerApiService {
): DeezerService {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.callFactory(client)

View File

@ -104,7 +104,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
adapter = songAdapter
layoutManager = linearLayoutManager()
}
repository.historySong().observe(viewLifecycleOwner, Observer {
repository.observableHistorySongs().observe(viewLifecycleOwner, Observer {
val songs = it.map { historyEntity -> historyEntity.toSong() }
songAdapter.swapDataSet(songs)
})

View File

@ -16,7 +16,7 @@ package code.name.monkey.retromusic.glide.artistimage
import android.content.Context
import code.name.monkey.retromusic.deezer.Data
import code.name.monkey.retromusic.deezer.DeezerApiService
import code.name.monkey.retromusic.deezer.DeezerService
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Priority
@ -38,7 +38,7 @@ class ArtistImage(val artistName: String)
class ArtistImageFetcher(
private val context: Context,
private val deezerApiService: DeezerApiService,
private val deezerService: DeezerService,
val model: ArtistImage,
val urlLoader: ModelLoader<GlideUrl, InputStream>,
val width: Int,
@ -66,7 +66,7 @@ class ArtistImageFetcher(
PreferenceUtil.isAllowedToDownloadMetadata()
) {
val artists = model.artistName.split(",")
val response = deezerApiService.getArtistImage(artists[0]).execute()
val response = deezerService.getArtistImage(artists[0]).execute()
if (!response.isSuccessful) {
throw IOException("Request failed with code: " + response.code())
@ -106,7 +106,7 @@ class ArtistImageFetcher(
class ArtistImageLoader(
val context: Context,
private val deezerApiService: DeezerApiService,
private val deezerService: DeezerService,
private val urlLoader: ModelLoader<GlideUrl, InputStream>
) : StreamModelLoader<ArtistImage> {
@ -115,7 +115,7 @@ class ArtistImageLoader(
width: Int,
height: Int
): DataFetcher<InputStream> {
return ArtistImageFetcher(context, deezerApiService, model, urlLoader, width, height)
return ArtistImageFetcher(context, deezerService, model, urlLoader, width, height)
}
}
@ -123,7 +123,7 @@ class Factory(
val context: Context
) : ModelLoaderFactory<ArtistImage, InputStream> {
private var deezerApiService: DeezerApiService
private var deezerService: DeezerService
private var okHttpFactory: OkHttpUrlLoader.Factory
init {
@ -134,8 +134,8 @@ class Factory(
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.build()
)
deezerApiService = DeezerApiService.invoke(
DeezerApiService.createDefaultOkHttpClient(context)
deezerService = DeezerService.invoke(
DeezerService.createDefaultOkHttpClient(context)
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
@ -156,7 +156,7 @@ class Factory(
): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(
context!!,
deezerApiService,
deezerService,
okHttpFactory.build(context, factories)
)
}

View File

@ -1,12 +1,14 @@
package code.name.monkey.retromusic.network
import android.content.Context
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.Constants.AUDIO_SCROBBLER_URL
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.deezer.DeezerService
import com.google.gson.Gson
import okhttp3.Cache
import okhttp3.ConnectionPool
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
@ -16,50 +18,22 @@ import java.util.concurrent.TimeUnit
private const val TIMEOUT: Long = 700
val networkModule = module {
factory {
provideHttpClient(get(), get())
}
factory {
provideCacheControlInterceptor()
}
factory {
provideDefaultCache()
}
factory {
provideLastFmService(get())
provideOkHttp(get(), get())
}
single {
providerRetrofit(get())
provideLastFmRetrofit(get())
}
single {
provideDeezerRest(get())
}
single {
provideLastFmRest(get())
}
}
fun provideLastFmService(retrofit: Retrofit): LastFMService =
retrofit.create(LastFMService::class.java)
fun providerRetrofit(okHttpClient: OkHttpClient.Builder): Retrofit = Retrofit.Builder()
.baseUrl(AUDIO_SCROBBLER_URL)
.callFactory(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create(Gson()))
.build()
fun provideHttpClient(
cache: Cache,
interceptor: Interceptor
): OkHttpClient.Builder = OkHttpClient.Builder()
.connectionPool(ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
.retryOnConnectionFailure(true)
.connectTimeout(TIMEOUT, TimeUnit.MINUTES)
.writeTimeout(TIMEOUT, TimeUnit.MINUTES)
.readTimeout(TIMEOUT, TimeUnit.MINUTES)
.cache(cache)
.addInterceptor(interceptor)
fun provideCacheControlInterceptor(): Interceptor = Interceptor { chain: Interceptor.Chain ->
val modifiedRequest = chain.request().newBuilder()
.addHeader("Cache-Control", "max-age=31536000, max-stale=31536000")
.build()
chain.proceed(modifiedRequest)
}
fun provideDefaultCache(): Cache? {
@ -69,3 +43,55 @@ fun provideDefaultCache(): Cache? {
}
return null
}
fun logInterceptor(): Interceptor {
val loggingInterceptor = HttpLoggingInterceptor()
if (BuildConfig.DEBUG) {
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
} else {
// disable retrofit log on release
loggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
}
return loggingInterceptor
}
fun headerInterceptor(context: Context): Interceptor {
return Interceptor {
val original = it.request()
val request = original.newBuilder()
.header("User-Agent", context.packageName)
.addHeader("Content-Type", "application/json; charset=utf-8")
.method(original.method(), original.body())
.build()
it.proceed(request)
}
}
fun provideOkHttp(context: Context, cache: Cache): OkHttpClient {
return OkHttpClient.Builder()
.addNetworkInterceptor(logInterceptor())
.addInterceptor(headerInterceptor(context))
.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.SECONDS)
.cache(cache)
.build()
}
fun provideLastFmRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl("https://ws.audioscrobbler.com/2.0/")
.addConverterFactory(GsonConverterFactory.create(Gson()))
.callFactory { request -> client.newCall(request) }
.build()
}
fun provideLastFmRest(retrofit: Retrofit): LastFMService {
return retrofit.create(LastFMService::class.java)
}
fun provideDeezerRest(retrofit: Retrofit): DeezerService {
val newBuilder = retrofit.newBuilder()
.baseUrl("https://api.deezer.com/")
.build()
return newBuilder.create(DeezerService::class.java)
}

View File

@ -22,6 +22,7 @@ import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.model.smartplaylist.NotPlayedPlaylist
import code.name.monkey.retromusic.network.LastFMService
import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.Result.*
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.network.model.LastFmArtist
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -153,9 +154,10 @@ class RealRepository(
cache: String?
): Result<LastFmArtist> {
return try {
Result.Success(lastFMService.artistInfo(name, lang, cache))
Success(lastFMService.artistInfo(name, lang, cache))
} catch (e: Exception) {
Result.Error
println(e)
Error
}
}
@ -165,15 +167,16 @@ class RealRepository(
): Result<LastFmAlbum> {
return try {
val lastFmAlbum = lastFMService.albumInfo(artist, album)
Result.Success(lastFmAlbum)
Success(lastFmAlbum)
} catch (e: Exception) {
Result.Error
println(e)
Error
}
}
@ExperimentalCoroutinesApi
override suspend fun homeSectionsFlow(): Flow<Result<List<Home>>> {
val homes = MutableStateFlow<Result<List<Home>>>(value = Result.Loading)
val homes = MutableStateFlow<Result<List<Home>>>(value = Loading)
val homeSections = mutableListOf<Home>()
val sections = listOf(
topArtistsHome(),
@ -191,9 +194,9 @@ class RealRepository(
}
}
if (homeSections.isEmpty()) {
homes.value = Result.Error
homes.value = Error
} else {
homes.value = Result.Success(homeSections)
homes.value = Success(homeSections)
}
return homes
}
@ -350,52 +353,52 @@ class RealRepository(
}
override fun songsFlow(): Flow<Result<List<Song>>> = flow {
emit(Result.Loading)
emit(Loading)
val data = songRepository.songs()
if (data.isEmpty()) {
emit(Result.Error)
emit(Error)
} else {
emit(Result.Success(data))
emit(Success(data))
}
}
override fun albumsFlow(): Flow<Result<List<Album>>> = flow {
emit(Result.Loading)
emit(Loading)
val data = albumRepository.albums()
if (data.isEmpty()) {
emit(Result.Error)
emit(Error)
} else {
emit(Result.Success(data))
emit(Success(data))
}
}
override fun artistsFlow(): Flow<Result<List<Artist>>> = flow {
emit(Result.Loading)
emit(Loading)
val data = artistRepository.artists()
if (data.isEmpty()) {
emit(Result.Error)
emit(Error)
} else {
emit(Result.Success(data))
emit(Success(data))
}
}
override fun playlistsFlow(): Flow<Result<List<Playlist>>> = flow {
emit(Result.Loading)
emit(Loading)
val data = playlistRepository.playlists()
if (data.isEmpty()) {
emit(Result.Error)
emit(Error)
} else {
emit(Result.Success(data))
emit(Success(data))
}
}
override fun genresFlow(): Flow<Result<List<Genre>>> = flow {
emit(Result.Loading)
emit(Loading)
val data = genreRepository.genres()
if (data.isEmpty()) {
emit(Result.Error)
emit(Error)
} else {
emit(Result.Success(data))
emit(Success(data))
}
}
}