Last active
November 8, 2023 04:35
-
-
Save yongjhih/4e0db6b044b7595026779c1514eb0779 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ``` | |
* val giphyRepository = Retrofit.Builder() | |
* .baseUrl("https://api.giphy.com/") | |
* .addConverterFactory(Json { | |
* ignoreUnknownKeys = true | |
* }.asConverterFactory(contentType)) | |
* .build() | |
* .create<GiphyRepository>() | |
* | |
* for (req in giphyRepository.searchSequence("cat").take(3)) { | |
* try { | |
* val res = req() | |
* Timber.v("${res}") | |
* } catch (e: Exception) { | |
* Timber.e(e) | |
* } | |
* delay(3.seconds) | |
* } | |
* ``` | |
*/ | |
interface GiphyRepository { | |
@GET("v1/gifs/trending") | |
suspend fun getTrending( | |
@Query("api_key") apiKey: String = API_KEY, | |
): GiphyData | |
@GET("v1/gifs/search") | |
suspend fun search( | |
@Query("q") query: String, | |
@Query("offset") offset: Int? = null, | |
@Query("limit") limit: Int? = null, | |
@Query("api_key") api_key: String = API_KEY, | |
@Query("lang") lang: String? = null, | |
@Query("bundle") bundle: String? = null, | |
): GiphyData | |
} | |
fun GiphyRepository.searchFlow(query: String, offset: Int? = null): Flow<List<Giphy>> = flow { | |
var offset = offset ?: 0 | |
while (true) { | |
val res = search(query, offset = offset) | |
val data = res.data | |
if (data.isNullOrEmpty()) break | |
emit(data) | |
offset = res.pagination?.offset ?: (offset + data.size) | |
} | |
} | |
fun GiphyRepository.searchSequence(query: String, offset: Int? = null): Sequence<suspend () -> List<Giphy>?> = sequence { | |
var offset = offset | |
while (true) { | |
var isEnd = false | |
yield(suspend { | |
val res = search(query, offset) | |
val data = res.data | |
val newOffset = (res.pagination?.offset ?: offset ?: 0) + (res.pagination?.count ?: data?.size ?: 0) | |
isEnd = data.isNullOrEmpty() || (offset ?: 0) == newOffset | |
offset = newOffset | |
data | |
}) | |
if (isEnd) break | |
} | |
} | |
fun GiphyRepository.searchUrlImageFlow(query: String, offset: Int? = null): Flow<List<UrlImage>> = | |
searchFlow(query, offset).map { data -> data.map { it.images?.values?.toList() ?: emptyList() }.flatten() } | |
inline fun <reified T> Retrofit.create(): T = create(T::class.java) | |
val contentType = "application/json".toMediaType() | |
@Serializable | |
data class Giphy ( | |
var id: String? = null, | |
var type: String? = null, | |
var images: Map<String, UrlImage>? = null, | |
) | |
@Serializable | |
data class GiphyImage ( | |
var url: String? = null, | |
var width: Int? = null, | |
var height: Int? = null, | |
var size: Int = 0, | |
var mp4: String? = null, | |
var mp4_size: Int = 0, | |
var webp: String? = null, | |
var webp_size: Int = 0, | |
) | |
@Serializable | |
data class UrlImage ( | |
var url: String? = null, | |
var width: Int? = null, | |
var height: Int? = null, | |
) | |
@Serializable | |
data class GiphyData( | |
var data: List<Giphy>? = null, | |
var meta: Meta? = null, | |
var pagination: Pagination? = null, | |
) | |
@Serializable | |
data class Meta( | |
var status: Int = 0, | |
var msg: String? = null, | |
var response_id: String? = null, | |
) | |
@Serializable | |
data class Pagination( | |
var total_count: Int = 0, | |
var count: Int = 0, | |
var offset: Int = 0, | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment