Untitled

mail@pastecode.io avatar
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
}