Skip to content

Commit

Permalink
Replace jsCommunicator calls with new promise class
Browse files Browse the repository at this point in the history
(benefits): allows for more concise passing of JSON back to the js side
  • Loading branch information
MarmadileManteater committed Jan 28, 2025
1 parent 802aabd commit 3a3059a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.freetubeapp.freetube.helpers

import io.freetubeapp.freetube.javascript.AsyncJSCommunicator
import java.util.UUID.randomUUID
import java.util.concurrent.ThreadPoolExecutor

class Promise<T, G> {
private val successListeners: MutableList<(T) -> Unit> = mutableListOf()
private var successResult: T? = null
private val errorListeners: MutableList<(G) -> Unit> = mutableListOf()
private var errorResult: G? = null
private val id = "${randomUUID()}"

constructor(executor: ThreadPoolExecutor, runnable: ((T) -> Unit, (G) -> Unit) -> Unit) {
executor.run {
runnable.invoke({
result ->
notifySuccess(result)
}, {
result ->
notifyError(result)
})
}
}

fun addJsCommunicator(communicator: AsyncJSCommunicator) : String {
then {
communicator.resolve(id, "$it")
}
catch {
communicator.reject(id, "$it")
}
return id
}

fun notifySuccess(result: T) {
successResult = result
successListeners.forEach {
listener ->
listener.invoke(result)
}
}

fun notifyError(result: G) {
errorResult = result
errorListeners.forEach {
listener ->
listener.invoke(result)
}
}

fun then(listener: (T) -> Unit): Promise<T, G> {
if (successResult != null) {
// assume success result won't be unset
listener(successResult!!)
} else {
successListeners.add(listener)
}
return this
}

fun catch(listener: (G) -> Unit): Promise<T, G> {
if (errorResult != null) {
// assume success result won't be unset
listener(errorResult!!)
} else {
errorListeners.add(listener)
}
return this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import androidx.documentfile.provider.DocumentFile
import io.freetubeapp.freetube.MainActivity
import io.freetubeapp.freetube.MediaControlsReceiver
import io.freetubeapp.freetube.R
import io.freetubeapp.freetube.helpers.Promise
import org.json.JSONObject
import java.io.File
import java.io.FileInputStream
import java.net.URL
Expand Down Expand Up @@ -375,24 +377,25 @@ class FreeTubeJavaScriptInterface {
*/
@JavascriptInterface
fun readFile(basedir: String, filename: String): String {
val promise = jsCommunicator.jsPromise()
context.threadPoolExecutor.execute {
val promise = Promise(context.threadPoolExecutor, {
resolve,
reject ->
try {
if (basedir.startsWith("content://")) {
val stream = context.contentResolver.openInputStream(Uri.parse(basedir))
val content = String(stream!!.readBytes())
stream!!.close()
jsCommunicator.resolve(promise, content)
resolve(content)
} else {
val path = getDirectory(basedir)
val file = File(path, filename)
jsCommunicator.resolve(promise, FileInputStream(file).bufferedReader().use { it.readText() })
resolve(FileInputStream(file).bufferedReader().use { it.readText() })
}
} catch (ex: Exception) {
jsCommunicator.reject(promise, ex.stackTraceToString())
reject(ex.stackTraceToString())
}
}
return promise
})
return promise.addJsCommunicator(jsCommunicator)
}

/**
Expand Down

0 comments on commit 3a3059a

Please sign in to comment.