MainActivity: handle redirections
This commit is contained in:
parent
12c3a9e4bb
commit
6e380290b4
|
@ -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 {
|
||||
|
|
|
@ -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]
|
||||
|
|
Reference in a new issue