From cdcbdcdb2cf7a2c039cacf354100cced5c7ea1ca Mon Sep 17 00:00:00 2001 From: Corewala Date: Tue, 7 Jun 2022 15:36:16 -0400 Subject: [PATCH] Only latest gemini request is handled Also back button cancels current requests if used while loading --- .../corewala/buran/io/gemini/Datasource.kt | 3 ++- .../buran/io/gemini/GeminiDatasource.kt | 24 +++++++++++++------ .../java/corewala/buran/ui/GemActivity.kt | 12 +++++++--- .../java/corewala/buran/ui/GemViewModel.kt | 8 +++++++ 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/corewala/buran/io/gemini/Datasource.kt b/app/src/main/java/corewala/buran/io/gemini/Datasource.kt index bbb8742..a69c04f 100644 --- a/app/src/main/java/corewala/buran/io/gemini/Datasource.kt +++ b/app/src/main/java/corewala/buran/io/gemini/Datasource.kt @@ -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) diff --git a/app/src/main/java/corewala/buran/io/gemini/GeminiDatasource.kt b/app/src/main/java/corewala/buran/io/gemini/GeminiDatasource.kt index 6918aa1..8bd29f6 100644 --- a/app/src/main/java/corewala/buran/io/gemini/GeminiDatasource.kt +++ b/app/src/main/java/corewala/buran/io/gemini/GeminiDatasource.kt @@ -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){ diff --git a/app/src/main/java/corewala/buran/ui/GemActivity.kt b/app/src/main/java/corewala/buran/ui/GemActivity.kt index 70e104c..5c8c44e 100644 --- a/app/src/main/java/corewala/buran/ui/GemActivity.kt +++ b/app/src/main/java/corewala/buran/ui/GemActivity.kt @@ -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") diff --git a/app/src/main/java/corewala/buran/ui/GemViewModel.kt b/app/src/main/java/corewala/buran/ui/GemViewModel.kt index 2b02fad..8fa921b 100644 --- a/app/src/main/java/corewala/buran/ui/GemViewModel.kt +++ b/app/src/main/java/corewala/buran/ui/GemViewModel.kt @@ -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)