Code refactor
This commit is contained in:
parent
332c2dc69b
commit
8eb7859f30
6 changed files with 104 additions and 74 deletions
|
@ -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 {
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue