MainActivity: handle redirections
This commit is contained in:
parent
f8cfe2ad09
commit
a6e910c3fa
|
@ -80,7 +80,12 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
openUrl(url, base = if (currentUrl.isNotEmpty()) currentUrl else null)
|
openUrl(url, base = if (currentUrl.isNotEmpty()) currentUrl else null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openUrl(url: String, base: String? = null) {
|
private fun openUrl(url: String, base: String? = null, redirections: Int = 0) {
|
||||||
|
if (redirections >= 5) {
|
||||||
|
alert("Too many redirections.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var uri = Uri.parse(url)
|
var uri = Uri.parse(url)
|
||||||
if (!uri.isAbsolute) {
|
if (!uri.isAbsolute) {
|
||||||
uri = if (!base.isNullOrEmpty()) joinUrls(base, url) else toGeminiUri(uri)
|
uri = if (!base.isNullOrEmpty()) joinUrls(base, url) else toGeminiUri(uri)
|
||||||
|
@ -120,24 +125,17 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
Log.d(TAG, "handleEvent: $event")
|
Log.d(TAG, "handleEvent: $event")
|
||||||
if (!event.handled) {
|
if (!event.handled) {
|
||||||
when (event) {
|
when (event) {
|
||||||
is PageViewModel.SuccessEvent -> {
|
is PageViewModel.SuccessEvent -> visitedUrls.add(event.uri)
|
||||||
visitedUrls.add(event.uri)
|
is PageViewModel.RedirectEvent -> openUrl(event.uri, redirections = event.redirects)
|
||||||
}
|
is PageViewModel.FailureEvent -> alert(event.message)
|
||||||
is PageViewModel.FailureEvent -> {
|
|
||||||
alert(event.message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
event.handled = true
|
event.handled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun alert(message: String, title: String? = null) {
|
private fun alert(message: String) {
|
||||||
val builder = AlertDialog.Builder(this)
|
AlertDialog.Builder(this)
|
||||||
if (title != null)
|
.setTitle(R.string.error_alert_title)
|
||||||
builder.setTitle(title)
|
|
||||||
else
|
|
||||||
builder.setTitle(title ?: R.string.alert_title)
|
|
||||||
builder
|
|
||||||
.setMessage(message)
|
.setMessage(message)
|
||||||
.create()
|
.create()
|
||||||
.show()
|
.show()
|
||||||
|
@ -164,6 +162,7 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
|
|
||||||
abstract class Event(var handled: Boolean = false)
|
abstract class Event(var handled: Boolean = false)
|
||||||
data class SuccessEvent(val uri: String) : Event()
|
data class SuccessEvent(val uri: String) : Event()
|
||||||
|
data class RedirectEvent(val uri: String, val redirects: Int) : Event()
|
||||||
data class FailureEvent(val message: String) : Event()
|
data class FailureEvent(val message: String) : Event()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,7 +170,7 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
*
|
*
|
||||||
* The URI must be valid, absolute and with a gemini scheme.
|
* The URI must be valid, absolute and with a gemini scheme.
|
||||||
*/
|
*/
|
||||||
fun sendGeminiRequest(uri: Uri) {
|
fun sendGeminiRequest(uri: Uri, redirects: Int = 0) {
|
||||||
Log.d(TAG, "sendRequest: URI \"$uri\"")
|
Log.d(TAG, "sendRequest: URI \"$uri\"")
|
||||||
state.postValue(State.CONNECTING)
|
state.postValue(State.CONNECTING)
|
||||||
requestJob?.apply { if (isActive) cancel() }
|
requestJob?.apply { if (isActive) cancel() }
|
||||||
|
@ -203,8 +202,9 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(TAG, "sendRequest: got ${response.code} with meta \"${response.meta}\"")
|
Log.i(TAG, "sendRequest: got ${response.code} with meta \"${response.meta}\"")
|
||||||
when (response.code) {
|
when (response.code.getCategory()) {
|
||||||
Response.Code.SUCCESS -> handleRequestSuccess(response, uri)
|
Response.Code.Category.SUCCESS -> handleRequestSuccess(response, uri)
|
||||||
|
Response.Code.Category.REDIRECT -> handleRedirect(response, redirects = redirects + 1)
|
||||||
else -> signalError("Can't handle code ${response.code}.")
|
else -> signalError("Can't handle code ${response.code}.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,6 +241,10 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
|
||||||
event.postValue(SuccessEvent(uri.toString()))
|
event.postValue(SuccessEvent(uri.toString()))
|
||||||
state.postValue(State.IDLE)
|
state.postValue(State.IDLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleRedirect(response: Response, redirects: Int) {
|
||||||
|
event.postValue(RedirectEvent(response.meta, redirects))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -31,6 +31,18 @@ class Response(val code: Code, val meta: String, val data: Channel<ByteArray>) {
|
||||||
CERTIFICATE_NOT_AUTHORISED(61),
|
CERTIFICATE_NOT_AUTHORISED(61),
|
||||||
CERTIFICATE_NOT_VALID(62);
|
CERTIFICATE_NOT_VALID(62);
|
||||||
|
|
||||||
|
enum class Category(val value: Int) {
|
||||||
|
UNKNOWN(0),
|
||||||
|
INPUT(1),
|
||||||
|
SUCCESS(2),
|
||||||
|
REDIRECT(3),
|
||||||
|
SERVER_ERROR(4),
|
||||||
|
CLIENT_ERROR(5),
|
||||||
|
CERTIFICATE(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCategory(): Category? = Category.values().associateBy(Category::value)[value / 10]
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val MAP = values().associateBy(Code::value)
|
private val MAP = values().associateBy(Code::value)
|
||||||
fun fromInt(type: Int) = MAP[type]
|
fun fromInt(type: Int) = MAP[type]
|
||||||
|
|
Reference in a new issue