Untitled
unknown
kotlin
3 years ago
4.8 kB
10
Indexable
interface SearchAPI {
@Headers(
"accept:*/*",
"accept-language: tr-TR,tr;q=0.9",
"content-type: application/json",
"sec-ch-ua: Opera;v=95, Chromium;v=109, Not;A=Brand;v=24",
"sec-ch-ua-mobile: ?0",
"sec-ch-ua-platform: Windows",
"sec-fetch-dest: empty",
"sec-fetch-mode: same-origin",
"sec-fetch-site: same-origin",
"x-goog-visitor-id: CgtxYnpLN0dGTE9BNCjbn92fBg%3D%3D",
"x-youtube-bootstrap-logged-in: false",
"x-youtube-client-name: 67",
"x-youtube-client-version: 1.20230220.01.00",
"origin: https://music.youtube.com",
"referer: https://music.youtube.com/"
)
@POST("youtubei/v1/music/get_search_suggestions")
suspend fun searchSong(
@Query("key") key: String,
@Query("prettyPrint") prettyPrint: Boolean,
@Body searchBody : SearchBody
): SearchEntity
}
----
class SearchRepositoryImp @Inject constructor(private val searchAPI: SearchAPI){
suspend fun getSearchApi(query : String) = searchAPI.searchSong(Utils.searchKey,Utils.prettyPrint, SearchBody(input = query))
}
----
class SearchMusicRepository @Inject constructor(private val searchAPI: SearchAPI) {
suspend fun getSearchMusic(query : String): SearchEntity {
return searchAPI.searchSong(Utils.searchKey,Utils.prettyPrint, SearchBody(input = query))
}
}
---
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
fun providesLoggingInterceptor( ): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
@Singleton
fun providesOkHttpClient(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient{
return OkHttpClient.Builder()
.connectTimeout(15,TimeUnit.SECONDS)
.readTimeout(15,TimeUnit.SECONDS)
.writeTimeout(15,TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
.followRedirects(false)
.followSslRedirects(false)
.addInterceptor(RedirectInterceptor())
.build()
}
@Provides
@Singleton
fun providesSongContentApi(okHttpClient: OkHttpClient = providesOkHttpClient(providesLoggingInterceptor()), baseUrl : String): Retrofit {
return Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
@Provides
@Singleton
fun searchSongRetrofit() : SearchAPI = providesSongContentApi(baseUrl = SEARCH_BASE_URL).create(SearchAPI::class.java)
}
---
@Module
@InstallIn(SingletonComponent::class)
object DataRepositoryModule {
@Provides
@Singleton
fun providesSearchMusicRepository(searchAPI: SearchAPI) : SearchMusicRepository = SearchMusicRepository(searchAPI)
}
----
@HiltViewModel
class SearchListFragmentViewModel @Inject constructor(private val searchRepository: SearchMusicRepository,
application: Application) : BaseViewModel(application) {
private val _searchResultSongList = MutableLiveData<Resource<SearchResultEntity>>()
val searchResultSongList: LiveData<Resource<SearchResultEntity>> get() = _searchResultSongList
fun fetchSearchResultSongData(query: String) = viewModelScope.launch {
_searchResultSongList.postValue(Resource.loading(null))
try {
val searchResultSongList = withContext(Dispatchers.IO){
remoteMusicRepository.getSearchResultMusic(query)
}
_searchResultSongList.postValue(Resource.success(searchResultSongList))
} catch (e: Exception) {
_searchResultSongList.postValue(Resource.error(e.message ?: "Unknown Error", null))
}
}
}
---
data class Resource<out T>(val status:Status, val data: T?,val message:String?) {
companion object {
fun<T> success(data: T?): Resource<T> {
return Resource(Status.SUCCESS,data,null)
}
fun<T> error(message: String, data:T?): Resource<T> {
return Resource(Status.ERROR,data,message)
}
fun<T> loading(data: T?) : Resource<T> {
return Resource(Status.LOADING,data,null)
}
}
}
---
enum class Status {
SUCCESS,
ERROR,
LOADING
}Editor is loading...