mirror of
https://github.com/Corewala/Buran
synced 2025-03-11 22:53:08 +00:00
Only latest gemini request is handled
Also back button cancels current requests if used while loading
This commit is contained in:
parent
35352fa6f3
commit
cdcbdcdb2c
4 changed files with 36 additions and 11 deletions
|
@ -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)
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue