Files
radiola-android/app/src/main/java/com/radiola/di/AppModule.kt
nk c0ee47b699 fix(app): таймаут 30с для запроса распознавания Shazam
Бэкенд-распознавание асинхронное (чанк аудио + поллинг ~до 18с) — точечно
поднимаем readTimeout до 30с только для пути shazam/recognize (базовый 10с мал).
Bump backend submodule (двухстадийный флоу shazam-api.com).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:45:08 +03:00

253 lines
9.3 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.radiola.di
import android.content.Context
import androidx.room.Room
import com.radiola.data.local.AppDatabase
import com.radiola.data.local.LocalStationDataSource
import com.radiola.data.local.MIGRATION_1_2
import com.radiola.data.local.MIGRATION_2_3
import com.radiola.data.local.MIGRATION_3_4
import com.radiola.data.local.MIGRATION_4_5
import com.radiola.data.local.MIGRATION_5_6
import com.radiola.data.local.MIGRATION_6_7
import com.radiola.data.local.MIGRATION_7_8
import com.radiola.data.local.dao.AlarmDao
import com.radiola.data.remote.AuthInterceptor
import com.radiola.data.remote.LrcLibApi
import com.radiola.data.remote.LoveApi
import com.radiola.data.remote.RecordApi
import com.radiola.data.remote.RadiolaApi
import com.radiola.data.repository.AuthRepositoryImpl
import com.radiola.data.repository.ChartsRepositoryImpl
import com.radiola.data.repository.FavoritesRepositoryImpl
import com.radiola.data.repository.LyricsRepositoryImpl
import com.radiola.data.repository.NowPlayingRepositoryImpl
import com.radiola.data.repository.RecordingRepositoryImpl
import com.radiola.data.repository.RegionRepositoryImpl
import com.radiola.data.repository.SettingsRepositoryImpl
import com.radiola.data.repository.StationRepositoryImpl
import com.radiola.data.repository.SyncRepositoryImpl
import com.radiola.data.repository.RecognizedTrackRepositoryImpl
import com.radiola.data.repository.ShazamRepositoryImpl
import com.radiola.data.repository.TrackHistoryRepositoryImpl
import com.radiola.domain.repository.AuthRepository
import com.radiola.domain.repository.RecognizedTrackRepository
import com.radiola.domain.repository.ShazamRepository
import com.radiola.domain.repository.ChartsRepository
import com.radiola.domain.repository.FavoritesRepository
import com.radiola.domain.repository.LyricsRepository
import com.radiola.domain.repository.SyncRepository
import com.radiola.domain.repository.NowPlayingRepository
import com.radiola.domain.repository.RecordingRepository
import com.radiola.domain.repository.RegionRepository
import com.radiola.domain.repository.SettingsRepository
import com.radiola.domain.repository.StationRepository
import com.radiola.domain.repository.TrackHistoryRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import javax.inject.Named
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideJson(): Json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
}
@Provides
@Singleton
fun provideBaseOkHttpClient(): OkHttpClient = OkHttpClient.Builder()
.connectTimeout(5, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.apply {
// Логирование каждого HTTP-запроса — только в debug. В релизе это лишний
// оверхед на каждый вызов и утечка URL/деталей в logcat.
if (com.radiola.BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BASIC
})
}
}
.build()
@Provides
@Singleton
@Named("radiolaClient")
fun provideRadiolaOkHttpClient(
baseClient: OkHttpClient,
authInterceptor: AuthInterceptor
): OkHttpClient = baseClient.newBuilder()
.addInterceptor(authInterceptor)
// Распознавание Shazam на бэкенде асинхронное (тянет аудио из потока +
// поллит результат ~до 18с) — базового readTimeout 10с не хватает.
// Поднимаем таймаут точечно только для этого пути.
.addInterceptor { chain ->
val req = chain.request()
if (req.url.encodedPath.contains("shazam/recognize")) {
chain.withReadTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.withConnectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.proceed(req)
} else {
chain.proceed(req)
}
}
.build()
@Provides
@Singleton
@Named("record")
fun provideRecordRetrofit(okHttpClient: OkHttpClient, json: Json): Retrofit = Retrofit.Builder()
.baseUrl("https://www.radiorecord.ru/")
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Provides
@Singleton
@Named("radiola")
fun provideRadiolaRetrofit(
@Named("radiolaClient") okHttpClient: OkHttpClient,
json: Json
): Retrofit = Retrofit.Builder()
.baseUrl("http://121.127.37.212:3000/")
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Provides
@Singleton
@Named("itunes")
fun provideItunesRetrofit(okHttpClient: OkHttpClient, json: Json): Retrofit = Retrofit.Builder()
.baseUrl("https://itunes.apple.com/")
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Provides
@Singleton
fun provideItunesApi(@Named("itunes") retrofit: Retrofit): com.radiola.data.remote.ItunesApi =
retrofit.create(com.radiola.data.remote.ItunesApi::class.java)
@Provides
@Singleton
@Named("lrclib")
fun provideLrcLibRetrofit(okHttpClient: OkHttpClient, json: Json): Retrofit = Retrofit.Builder()
.baseUrl("https://lrclib.net/")
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Provides
@Singleton
@Named("love")
fun provideLoveRetrofit(okHttpClient: OkHttpClient, json: Json): Retrofit = Retrofit.Builder()
.baseUrl("https://api.loveradio.ru/api/v1/love-radio/")
.client(okHttpClient)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.build()
@Provides
@Singleton
fun provideLoveApi(@Named("love") retrofit: Retrofit): LoveApi = retrofit.create(LoveApi::class.java)
@Provides
@Singleton
fun provideLrcLibApi(@Named("lrclib") retrofit: Retrofit): LrcLibApi = retrofit.create(LrcLibApi::class.java)
@Provides
@Singleton
fun provideRecordApi(@Named("record") retrofit: Retrofit): RecordApi = retrofit.create(RecordApi::class.java)
@Provides
@Singleton
fun provideRadiolaApi(@Named("radiola") retrofit: Retrofit): RadiolaApi = retrofit.create(RadiolaApi::class.java)
@Provides
@Singleton
fun provideDatabase(@ApplicationContext context: Context): AppDatabase =
Room.databaseBuilder(context, AppDatabase::class.java, "radiola.db")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8)
.build()
@Provides
@Singleton
fun provideAlarmDao(db: AppDatabase): AlarmDao = db.alarmDao()
@Provides
@Singleton
fun provideStationDao(db: AppDatabase): com.radiola.data.local.dao.StationDao = db.stationDao()
@Provides
@Singleton
fun provideLocalStationDataSource(
@ApplicationContext context: Context,
json: Json
): LocalStationDataSource = LocalStationDataSource(context, json)
@Provides
@Singleton
fun provideStationRepository(impl: StationRepositoryImpl): StationRepository = impl
@Provides
@Singleton
fun provideNowPlayingRepository(impl: NowPlayingRepositoryImpl): NowPlayingRepository = impl
@Provides
@Singleton
fun provideFavoritesRepository(impl: FavoritesRepositoryImpl): FavoritesRepository = impl
@Provides
@Singleton
fun provideTrackHistoryRepository(impl: TrackHistoryRepositoryImpl): TrackHistoryRepository = impl
@Provides
@Singleton
fun provideSettingsRepository(impl: SettingsRepositoryImpl): SettingsRepository = impl
@Provides
@Singleton
fun provideRegionRepository(impl: RegionRepositoryImpl): RegionRepository = impl
@Provides
@Singleton
fun provideRecordingRepository(impl: RecordingRepositoryImpl): RecordingRepository = impl
@Provides
@Singleton
fun provideAuthRepository(impl: AuthRepositoryImpl): AuthRepository = impl
@Provides
@Singleton
fun provideSyncRepository(impl: SyncRepositoryImpl): SyncRepository = impl
@Provides
@Singleton
fun provideChartsRepository(impl: ChartsRepositoryImpl): ChartsRepository = impl
@Provides
@Singleton
fun provideLyricsRepository(impl: LyricsRepositoryImpl): LyricsRepository = impl
@Provides
@Singleton
fun provideRecognizedTrackRepository(impl: RecognizedTrackRepositoryImpl): RecognizedTrackRepository = impl
@Provides
@Singleton
fun provideShazamRepository(impl: ShazamRepositoryImpl): ShazamRepository = impl
}