mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 18:12:27 +00:00
rewrite the app in native kotlin with compose
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package com.illusionman1212.lyricsgrabbr.utils
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import okhttp3.Call
|
||||
import okhttp3.Response
|
||||
import okhttp3.Callback
|
||||
import okio.IOException
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private suspend fun Call.await(callStack: Array<StackTraceElement>): Response {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
val callback =
|
||||
object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
continuation.resume(response) {
|
||||
response.body?.close()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
// Don't bother with resuming the continuation if it is already cancelled.
|
||||
if (continuation.isCancelled) return
|
||||
val exception = IOException(e.message, e).apply { stackTrace = callStack }
|
||||
continuation.resumeWithException(exception)
|
||||
}
|
||||
}
|
||||
|
||||
enqueue(callback)
|
||||
|
||||
continuation.invokeOnCancellation {
|
||||
try {
|
||||
cancel()
|
||||
} catch (ex: Throwable) {
|
||||
// Ignore cancel exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun Call.await(): Response {
|
||||
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
|
||||
return await(callStack)
|
||||
}
|
||||
|
||||
suspend fun Call.awaitSuccess(): Response {
|
||||
val callStack = Exception().stackTrace.run { copyOfRange(1, size) }
|
||||
val response = await(callStack)
|
||||
if (!response.isSuccessful) {
|
||||
response.close()
|
||||
throw HttpException(response.code).apply { stackTrace = callStack }
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
class HttpException(code: Int) : IllegalStateException("HTTP error $code")
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.illusionman1212.lyricsgrabbr.utils
|
||||
|
||||
import android.text.Annotation
|
||||
import android.text.SpannedString
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
|
||||
// Native stylization is coming soon
|
||||
// https://issuetracker.google.com/issues/139320238
|
||||
@Composable
|
||||
fun annotatedStringResource(
|
||||
@StringRes id: Int,
|
||||
spanStyles: (Annotation) -> SpanStyle? = { null }
|
||||
): AnnotatedString {
|
||||
val resources = LocalContext.current.resources
|
||||
val spannedString = SpannedString(resources.getText(id))
|
||||
val resultBuilder = AnnotatedString.Builder()
|
||||
resultBuilder.append(spannedString.toString())
|
||||
spannedString.getSpans<Annotation>(0, spannedString.length, Annotation::class.java).forEach { annotation ->
|
||||
val spanStart = spannedString.getSpanStart(annotation)
|
||||
val spanEnd = spannedString.getSpanEnd(annotation)
|
||||
resultBuilder.addStringAnnotation(
|
||||
tag = annotation.key,
|
||||
annotation = annotation.value,
|
||||
start = spanStart,
|
||||
end = spanEnd
|
||||
)
|
||||
spanStyles(annotation)?.let { resultBuilder.addStyle(it, spanStart, spanEnd) }
|
||||
}
|
||||
return resultBuilder.toAnnotatedString()
|
||||
}
|
||||
Reference in New Issue
Block a user