Only latest gemini request is handled

Also back button cancels current requests if used while loading
This commit is contained in:
Corewala 2022-06-07 15:36:16 -04:00
parent 35352fa6f3
commit cdcbdcdb2c
4 changed files with 36 additions and 11 deletions

View File

@ -7,8 +7,9 @@ import java.net.URI
interface Datasource {
fun request(address: String, forceDownload: Boolean, clientCertPassword: String?, onUpdate: (state: GemState) -> Unit)
fun isRequesting(): Boolean
fun cancel()
fun canGoBack(): Boolean
companion object{
fun factory(context: Context, history: BuranHistory): Datasource {
return GeminiDatasource(context, history)

View File

@ -30,7 +30,7 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
private var socketFactory: SSLSocketFactory? = null
private var latestRequestAddress: String? = null
private var currentRequestAddress: String? = null
override fun request(address: String, forceDownload: Boolean, clientCertPassword: String?, onUpdate: (state: GemState) -> Unit) {
this.forceDownload = forceDownload
@ -41,13 +41,21 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
onUpdate(GemState.Requesting(uri))
latestRequestAddress = address
currentRequestAddress = address
GlobalScope.launch {
geminiRequest(uri, onUpdate, clientCertPassword)
}
}
override fun isRequesting(): Boolean{
return !currentRequestAddress.isNullOrEmpty()
}
override fun cancel(){
currentRequestAddress = null
}
private fun initSSLFactory(protocol: String, clientCertPassword: String?){
val sslContext = when (protocol) {
"TLS_ALL" -> SSLContext.getInstance("TLS")
@ -70,19 +78,19 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
println("Buran socket handshake with ${uri.host}")
socket.startHandshake()
}catch (uhe: UnknownHostException){
if(latestRequestAddress == uri.toString()) {
if(currentRequestAddress == uri.toString()) {
println("Buran socket error, unknown host: $uhe")
onUpdate(GemState.ResponseUnknownHost(uri))
}
return
}catch (ce: ConnectException){
if(latestRequestAddress == uri.toString()) {
if(currentRequestAddress == uri.toString()) {
println("Buran socket error, connect exception: $ce")
onUpdate(GemState.ResponseError(GeminiResponse.Header(-1, ce.message ?: ce.toString())))
}
return
}catch (she: SSLHandshakeException){
if(latestRequestAddress == uri.toString()) {
if(currentRequestAddress == uri.toString()) {
println("Buran socket error, ssl handshake exception: $she")
onUpdate(GemState.ResponseError(GeminiResponse.Header(-2, she.message ?: she.toString())))
}
@ -115,7 +123,7 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
println("Buran: response header: $headerLine")
if(headerLine == null){
if(latestRequestAddress == uri.toString()){
if(currentRequestAddress == uri.toString()){
onUpdate(GemState.ResponseError(GeminiResponse.Header(-2, "Server did not respond with a Gemini header: $uri")))
}
return
@ -124,7 +132,7 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
val header = GeminiResponse.parseHeader(headerLine)
when {
latestRequestAddress != uri.toString() -> {}
currentRequestAddress != uri.toString() -> {}
header.code == GeminiResponse.INPUT -> onUpdate(GemState.ResponseInput(uri, header))
header.code == GeminiResponse.REDIRECT -> onUpdate(GemState.Redirect(resolve(uri.host, header.meta)))
header.code == GeminiResponse.CLIENT_CERTIFICATE_REQUIRED -> onUpdate(GemState.ClientCertRequired(uri, header))
@ -152,6 +160,8 @@ class GeminiDatasource(private val context: Context, val history: BuranHistory):
outWriter.close()
socket.close()
currentRequestAddress = null
}
private fun getGemtext(reader: BufferedReader, uri: URI, header: GeminiResponse.Header, onUpdate: (state: GemState) -> Unit){

View File

@ -84,6 +84,8 @@ class GemActivity : AppCompatActivity() {
private var initialised: Boolean = false
private var requesting: Boolean = false
lateinit var adapter: AbstractGemtextAdapter
private val onLink: (link: URI, longTap: Boolean, adapterPosition: Int) -> Unit = { uri, longTap, _: Int ->
@ -439,7 +441,9 @@ class GemActivity : AppCompatActivity() {
}
}
is GemState.Requesting -> loadingView(true)
is GemState.Requesting -> {
loadingView(true)
}
is GemState.NotGeminiRequest -> externalProtocol(state)
is GemState.ResponseError -> {
omniTerm.reset()
@ -485,6 +489,7 @@ class GemActivity : AppCompatActivity() {
}
}
is GemState.ResponseUnknownHost -> {
omniTerm.reset()
runOnUiThread {
val searchbase = prefs.getString(
"search_base",
@ -825,7 +830,6 @@ class GemActivity : AppCompatActivity() {
if(getInternetStatus()){
if(initialised){
loadingView(true)
model.request(address, certPassword)
}else{
initialise()
@ -841,7 +845,9 @@ class GemActivity : AppCompatActivity() {
}
override fun onBackPressed() {
if (omniTerm.canGoBack()){
if(omniTerm.canGoBack() and model.isRequesting()){
model.cancel()
}else if(omniTerm.canGoBack()){
gemRequest(omniTerm.goBack())
}else{
println("Buran history is empty - exiting")

View File

@ -28,6 +28,14 @@ class GemViewModel: ViewModel() {
}
}
fun isRequesting(): Boolean{
return gemini.isRequesting()
}
fun cancel(){
gemini.cancel()
}
fun requestBinaryDownload(uri: URI, clientCertPassword: String?) {
gemini.request(uri.toString(), true, clientCertPassword){ state ->
onState(state)