MainActivity: handle redirections

This commit is contained in:
dece 2021-12-13 16:14:41 +01:00
parent 12c3a9e4bb
commit 6e380290b4
2 changed files with 33 additions and 17 deletions

View file

@ -80,7 +80,12 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
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)
if (!uri.isAbsolute) {
uri = if (!base.isNullOrEmpty()) joinUrls(base, url) else toGeminiUri(uri)
@ -120,24 +125,17 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
Log.d(TAG, "handleEvent: $event")
if (!event.handled) {
when (event) {
is PageViewModel.SuccessEvent -> {
visitedUrls.add(event.uri)
}
is PageViewModel.FailureEvent -> {
alert(event.message)
}
is PageViewModel.SuccessEvent -> visitedUrls.add(event.uri)
is PageViewModel.RedirectEvent -> openUrl(event.uri, redirections = event.redirects)
is PageViewModel.FailureEvent -> alert(event.message)
}
event.handled = true
}
}
private fun alert(message: String, title: String? = null) {
val builder = AlertDialog.Builder(this)
if (title != null)
builder.setTitle(title)
else
builder.setTitle(title ?: R.string.alert_title)
builder
private fun alert(message: String) {
AlertDialog.Builder(this)
.setTitle(R.string.error_alert_title)
.setMessage(message)
.create()
.show()
@ -164,6 +162,7 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
abstract class Event(var handled: Boolean = false)
data class SuccessEvent(val uri: String) : Event()
data class RedirectEvent(val uri: String, val redirects: Int) : 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.
*/
fun sendGeminiRequest(uri: Uri) {
fun sendGeminiRequest(uri: Uri, redirects: Int = 0) {
Log.d(TAG, "sendRequest: URI \"$uri\"")
state.postValue(State.CONNECTING)
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}\"")
when (response.code) {
Response.Code.SUCCESS -> handleRequestSuccess(response, uri)
when (response.code.getCategory()) {
Response.Code.Category.SUCCESS -> handleRequestSuccess(response, uri)
Response.Code.Category.REDIRECT -> handleRedirect(response, redirects = redirects + 1)
else -> signalError("Can't handle code ${response.code}.")
}
}
@ -241,6 +241,10 @@ class MainActivity : AppCompatActivity(), ContentAdapter.ContentAdapterListen {
event.postValue(SuccessEvent(uri.toString()))
state.postValue(State.IDLE)
}
private fun handleRedirect(response: Response, redirects: Int) {
event.postValue(RedirectEvent(response.meta, redirects))
}
}
companion object {

View file

@ -31,6 +31,18 @@ class Response(val code: Code, val meta: String, val data: Channel<ByteArray>) {
CERTIFICATE_NOT_AUTHORISED(61),
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 {
private val MAP = values().associateBy(Code::value)
fun fromInt(type: Int) = MAP[type]