aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/injectors
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2019-01-03 23:10:53 -0500
committerGitHub <noreply@github.com>2019-01-03 23:10:53 -0500
commit82f79a7d368caad4068d97051ad8deddd05b4f7e (patch)
treebfaca5c42f0ffb878c58b21b72731610f4da879a /app/src/main/kotlin/com/pitchedapps/frost/injectors
parentbc6566bc92d073e64a8c51a681ff01ba973d7ee7 (diff)
downloadfrost-82f79a7d368caad4068d97051ad8deddd05b4f7e.tar.gz
frost-82f79a7d368caad4068d97051ad8deddd05b4f7e.tar.bz2
frost-82f79a7d368caad4068d97051ad8deddd05b4f7e.zip
Add asset preloader (#1311)
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/injectors')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt33
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt5
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt4
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt43
5 files changed, 53 insertions, 51 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
index de19f99c..77cb4de1 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt
@@ -16,6 +16,7 @@
*/
package com.pitchedapps.frost.injectors
+import android.content.Context
import android.graphics.Color
import android.webkit.WebView
import ca.allanwang.kau.kotlin.lazyContext
@@ -27,6 +28,8 @@ import ca.allanwang.kau.utils.use
import ca.allanwang.kau.utils.withAlpha
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.FileNotFoundException
import java.util.Locale
@@ -36,12 +39,16 @@ import java.util.Locale
* Mapping of the available assets
* The enum name must match the css file name
*/
-enum class CssAssets(val folder: String = "themes") : InjectorContract {
+enum class CssAssets(val folder: String = THEME_FOLDER) : InjectorContract {
MATERIAL_LIGHT, MATERIAL_DARK, MATERIAL_AMOLED, MATERIAL_GLASS, CUSTOM, ROUND_ICONS("components")
;
- var file = "${name.toLowerCase(Locale.CANADA)}.css"
- var injector = lazyContext {
+ private val file = "${name.toLowerCase(Locale.CANADA)}.css"
+
+ /**
+ * Note that while this can be loaded from any thread, it is typically done through [load]
+ */
+ private val injector = lazyContext {
try {
var content = it.assets.open("css/$folder/$file").bufferedReader().use(BufferedReader::readText)
if (this == CUSTOM) {
@@ -72,11 +79,25 @@ enum class CssAssets(val folder: String = "themes") : InjectorContract {
}
}
- override fun inject(webView: WebView, callback: (() -> Unit)?) {
- injector(webView.context).inject(webView, callback)
- }
+ override fun inject(webView: WebView) =
+ injector(webView.context).inject(webView)
fun reset() {
injector.invalidate()
}
+
+ companion object {
+ // Ensures that all non themes and the selected theme are loaded
+ suspend fun load(context: Context) {
+ withContext(Dispatchers.IO) {
+ val currentTheme = Prefs.t.injector as? CssAssets
+ val (themes, others) = CssAssets.values().partition { it.folder == THEME_FOLDER }
+ themes.filter { it != currentTheme }.forEach { it.reset() }
+ currentTheme?.injector?.invoke(context)
+ others.forEach { it.injector.invoke(context) }
+ }
+ }
+ }
}
+
+private const val THEME_FOLDER = "themes"
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
index 7da6295f..4fd46ae4 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssHider.kt
@@ -45,7 +45,6 @@ enum class CssHider(vararg val items: String) : InjectorContract {
.single(name).build()
}
- override fun inject(webView: WebView, callback: (() -> Unit)?) {
- injector.inject(webView, callback)
- }
+ override fun inject(webView: WebView) =
+ injector.inject(webView)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
index e64d4faa..44fd01da 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
@@ -42,8 +42,8 @@ enum class JsActions(body: String) : InjectorContract {
val function = "(function(){$body})();"
- override fun inject(webView: WebView, callback: (() -> Unit)?) =
- JsInjector(function).inject(webView, callback)
+ override fun inject(webView: WebView) =
+ JsInjector(function).inject(webView)
}
@Suppress("NOTHING_TO_INLINE")
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
index 0dccc751..4b1bde43 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsAssets.kt
@@ -16,9 +16,12 @@
*/
package com.pitchedapps.frost.injectors
+import android.content.Context
import android.webkit.WebView
import ca.allanwang.kau.kotlin.lazyContext
import com.pitchedapps.frost.utils.L
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.FileNotFoundException
import java.util.Locale
@@ -33,8 +36,8 @@ enum class JsAssets : InjectorContract {
DOCUMENT_WATCHER
;
- var file = "${name.toLowerCase(Locale.CANADA)}.js"
- var injector = lazyContext {
+ private val file = "${name.toLowerCase(Locale.CANADA)}.js"
+ private val injector = lazyContext {
try {
val content = it.assets.open("js/$file").bufferedReader().use(BufferedReader::readText)
JsBuilder().js(content).single(name).build()
@@ -44,7 +47,15 @@ enum class JsAssets : InjectorContract {
}
}
- override fun inject(webView: WebView, callback: (() -> Unit)?) {
- injector(webView.context).inject(webView, callback)
+ override fun inject(webView: WebView) =
+ injector(webView.context).inject(webView)
+
+ companion object {
+ // Ensures that all non themes and the selected theme are loaded
+ suspend fun load(context: Context) {
+ withContext(Dispatchers.IO) {
+ JsAssets.values().forEach { it.injector.invoke(context) }
+ }
+ }
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
index 8ae3a2f4..00c7bcfc 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -17,12 +17,7 @@
package com.pitchedapps.frost.injectors
import android.webkit.WebView
-import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.web.FrostWebViewClient
-import io.reactivex.Single
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.disposables.Disposable
-import io.reactivex.subjects.SingleSubject
import org.apache.commons.text.StringEscapeUtils
import java.util.Locale
@@ -81,8 +76,7 @@ class JsBuilder {
* Contract for all injectors to allow it to interact properly with a webview
*/
interface InjectorContract {
- fun inject(webView: WebView) = inject(webView, null)
- fun inject(webView: WebView, callback: (() -> Unit)?)
+ fun inject(webView: WebView)
/**
* Toggle the injector (usually through Prefs
* If false, will fallback to an empty action
@@ -93,41 +87,18 @@ interface InjectorContract {
/**
* Helper method to inject multiple functions simultaneously with a single callback
*/
-fun WebView.jsInject(vararg injectors: InjectorContract, callback: ((Int) -> Unit)? = null): Disposable? {
- val validInjectors = injectors.filter { it != JsActions.EMPTY }
- if (validInjectors.isEmpty()) {
- callback?.invoke(0)
- return null
+fun WebView.jsInject(vararg injectors: InjectorContract) {
+ injectors.filter { it != JsActions.EMPTY }.forEach {
+ it.inject(this)
}
- L.d { "Injecting ${validInjectors.size} items" }
- if (callback == null) {
- validInjectors.forEach { it.inject(this) }
- return null
- }
- val observables = Array(validInjectors.size) { SingleSubject.create<Unit>() }
- val disposable = Single.zip<Unit, Int>(observables.asList()) { it.size }
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { res, _ ->
- callback(res)
- }
- (0 until validInjectors.size).forEach { i ->
- validInjectors[i].inject(this) {
- observables[i].onSuccess(Unit)
- }
- }
- return disposable
}
-fun FrostWebViewClient.jsInject(
- vararg injectors: InjectorContract,
- callback: ((Int) -> Unit)? = null
-) = web.jsInject(*injectors, callback = callback)
+fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract) = web.jsInject(*injectors)
/**
* Wrapper class to convert a function into an injector
*/
class JsInjector(val function: String) : InjectorContract {
- override fun inject(webView: WebView, callback: (() -> Unit)?) {
- webView.evaluateJavascript(function) { callback?.invoke() }
- }
+ override fun inject(webView: WebView) =
+ webView.evaluateJavascript(function, null)
}