Untitled
unknown
kotlin
2 years ago
4.8 kB
4
Indexable
Never
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 }