This commit is contained in:
2026-05-20 19:47:33 +10:00
commit dbb6302bd1
313 changed files with 17869 additions and 0 deletions
@@ -0,0 +1,34 @@
package com.meowarex.rlmobile.di
import android.app.Activity
import android.app.Application
import android.os.Bundle
import java.util.Objects
class ActivityProvider(application: Application) {
private var activeActivity: Activity? = null
/**
* Gets the current active activity as a specific activity or errors otherwise.
*/
@Suppress("UNCHECKED_CAST")
fun <T : Activity> get(): T = Objects.requireNonNull(activeActivity, "No active activity cached!") as T
init {
application.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {
activeActivity = activity
}
override fun onActivityDestroyed(activity: Activity) {
activeActivity = null
}
})
}
}
@@ -0,0 +1,109 @@
package com.meowarex.rlmobile.di
import android.app.Application
import com.meowarex.rlmobile.BuildConfig
import io.ktor.client.HttpClient
import io.ktor.client.call.HttpClientCall
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.cache.HttpCache
import io.ktor.client.plugins.cache.storage.FileStorage
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.cookies.HttpCookies
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.header
import io.ktor.client.statement.HttpReceivePipeline
import io.ktor.client.statement.HttpResponse
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.json
import io.ktor.util.AttributeKey
import io.ktor.util.date.GMTDate
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.InternalAPI
import kotlinx.serialization.json.Json
import okhttp3.Dns
import org.koin.core.scope.Scope
import java.net.Inet4Address
import java.net.InetAddress
import kotlin.coroutines.CoroutineContext
@Suppress("UnusedReceiverParameter")
fun Scope.provideJson() = Json {
ignoreUnknownKeys = true
}
fun Scope.provideHttpClient() = HttpClient(OkHttp) {
val json: Json = get()
val application: Application = get()
defaultRequest {
header(HttpHeaders.UserAgent, "Radiant Lyrics Manager/${BuildConfig.VERSION_NAME}")
}
engine {
config {
dns(object : Dns {
override fun lookup(hostname: String): List<InetAddress> {
val addresses = Dns.SYSTEM.lookup(hostname)
// Github's nameservers do not respond to IPv6 requests for raw.githubusercontent.com,
// which causes CIO, Android and OkHTTP to all hang
return if (hostname == "raw.githubusercontent.com") {
addresses.filterIsInstance<Inet4Address>()
} else {
addresses
}
}
})
}
}
install(ContentNegotiation) {
json(json)
}
install(HttpTimeout) {
socketTimeoutMillis = 30000
connectTimeoutMillis = 30000
}
install(HttpCache) {
val dir = application.cacheDir.resolve("ktor")
publicStorage(FileStorage(dir))
}
install(HttpCookies) {
// Default storage is in-memory
}
// Custom plugin to allow overriding response cache headers, and force caching
install("OverrideCacheControl") {
receivePipeline.intercept(HttpReceivePipeline.Before) { response ->
val customCacheControl = response.call.attributes.getOrNull(CustomCacheControl)
?: return@intercept
proceedWith(object : HttpResponse() {
@InternalAPI
override val rawContent: ByteReadChannel = response.rawContent
override val call: HttpClientCall = response.call
override val coroutineContext: CoroutineContext = response.coroutineContext
override val requestTime: GMTDate = response.requestTime
override val responseTime: GMTDate = response.responseTime
override val status: HttpStatusCode = response.status
override val version: HttpProtocolVersion = response.version
override val headers: Headers = headers {
appendAll(response.headers)
set(HttpHeaders.CacheControl, customCacheControl.toString())
}
})
}
}
}
private val CustomCacheControl: AttributeKey<CacheControl> = AttributeKey("CustomCacheControl")
fun HttpRequestBuilder.cacheControl(cacheControl: CacheControl) {
attributes.put(CustomCacheControl, cacheControl)
}
@@ -0,0 +1,10 @@
package com.meowarex.rlmobile.di
import android.content.Context
import com.meowarex.rlmobile.manager.PreferencesManager
import org.koin.core.scope.Scope
fun Scope.providePreferences(): PreferencesManager {
val ctx: Context = get()
return PreferencesManager(ctx.getSharedPreferences("preferences", Context.MODE_PRIVATE))
}