2020-08-15 14:52:27 +00:00
|
|
|
package oppen.tva.ui
|
|
|
|
|
2020-08-18 10:40:10 +00:00
|
|
|
import android.R.attr.label
|
|
|
|
import android.content.ClipData
|
|
|
|
import android.content.ClipboardManager
|
2020-08-15 20:33:44 +00:00
|
|
|
import android.content.Intent
|
|
|
|
import android.net.Uri
|
2020-08-15 14:52:27 +00:00
|
|
|
import android.os.Bundle
|
|
|
|
import android.view.inputmethod.EditorInfo
|
|
|
|
import androidx.activity.viewModels
|
2020-08-15 20:33:44 +00:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
2020-08-15 14:52:27 +00:00
|
|
|
import androidx.databinding.DataBindingUtil
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
2020-08-18 10:40:10 +00:00
|
|
|
import com.google.android.material.snackbar.Snackbar
|
2020-08-15 21:12:17 +00:00
|
|
|
import oppen.alert
|
2020-08-15 14:52:27 +00:00
|
|
|
import oppen.tva.R
|
|
|
|
import oppen.tva.databinding.ActivityTvaBinding
|
|
|
|
import oppen.tva.io.TvaState
|
|
|
|
import oppen.tva.io.history.CacheInterface
|
2020-08-18 10:40:10 +00:00
|
|
|
import oppen.tva.ui.tabs.NewTabPopup
|
2020-08-17 20:25:39 +00:00
|
|
|
import oppen.tva.ui.tabs.TabsDialog
|
2020-08-16 21:30:24 +00:00
|
|
|
import oppen.visibleRetainingSpace
|
2020-08-15 14:52:27 +00:00
|
|
|
|
2020-08-15 20:33:44 +00:00
|
|
|
|
2020-08-15 14:52:27 +00:00
|
|
|
class TvaActivity : AppCompatActivity() {
|
|
|
|
|
|
|
|
private val model by viewModels<TvaViewModel>()
|
|
|
|
private lateinit var binding: ActivityTvaBinding
|
2020-08-16 22:21:25 +00:00
|
|
|
private val adapter = GemtextAdapter { uri, longTap, view ->
|
|
|
|
if(longTap){
|
2020-08-17 20:25:39 +00:00
|
|
|
NewTabPopup.show(view){ menuId ->
|
|
|
|
when (menuId) {
|
|
|
|
R.id.link_menu_open_in_new_tab -> {
|
|
|
|
model.newTab(uri)
|
|
|
|
}
|
2020-08-18 10:40:10 +00:00
|
|
|
R.id.link_menu_copy -> {
|
|
|
|
val clipboard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
|
|
|
val clip = ClipData.newPlainText(getString(R.string.gemini_address), uri.toString())
|
|
|
|
clipboard.setPrimaryClip(clip)
|
|
|
|
Snackbar.make(binding.root, getString(R.string.address_copied_to_clipboard), Snackbar.LENGTH_SHORT).setAction(R.string.share) {
|
|
|
|
Intent().apply {
|
|
|
|
action = Intent.ACTION_SEND
|
|
|
|
putExtra(Intent.EXTRA_TEXT, uri.toString())
|
|
|
|
type = "text/plain"
|
|
|
|
startActivity(Intent.createChooser(this, null))
|
|
|
|
}
|
|
|
|
}.show()
|
|
|
|
}
|
2020-08-17 20:25:39 +00:00
|
|
|
}
|
2020-08-16 22:21:25 +00:00
|
|
|
}
|
|
|
|
}else{
|
|
|
|
model.request(uri)
|
|
|
|
}
|
|
|
|
|
2020-08-15 14:52:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
binding = DataBindingUtil.setContentView(this, R.layout.activity_tva)
|
|
|
|
binding.viewmodel = model
|
|
|
|
binding.lifecycleOwner = this
|
|
|
|
|
|
|
|
binding.gemtextRecycler.layoutManager = LinearLayoutManager(this)
|
|
|
|
binding.gemtextRecycler.adapter = adapter
|
|
|
|
|
|
|
|
model.initialise(CacheInterface.default(this)){ state ->
|
|
|
|
when(state){
|
|
|
|
is TvaState.AppQuery -> TODO()
|
2020-08-16 21:30:24 +00:00
|
|
|
is TvaState.Requesting -> loadingView(true)
|
2020-08-15 20:33:44 +00:00
|
|
|
is TvaState.NotGeminiRequest -> externalProtocol(state)
|
2020-08-15 14:52:27 +00:00
|
|
|
is TvaState.GeminiResponse -> renderGemtext(state)
|
2020-08-17 20:25:39 +00:00
|
|
|
is TvaState.TabChange -> binding.tabCount.text = "${state.count}"
|
|
|
|
is TvaState.Blank -> {
|
|
|
|
binding.addressEdit.setText("")
|
|
|
|
adapter.render(arrayListOf())
|
|
|
|
}
|
|
|
|
TvaState.GeminiPrintWriterError -> "Error with socket writer".alert(this)
|
2020-08-15 14:52:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
binding.addressEdit.setOnEditorActionListener { _, actionId, _ ->
|
|
|
|
when (actionId) {
|
|
|
|
EditorInfo.IME_ACTION_GO -> {
|
|
|
|
model.request(binding.addressEdit.text.toString())
|
|
|
|
return@setOnEditorActionListener true
|
|
|
|
}
|
|
|
|
else -> return@setOnEditorActionListener false
|
|
|
|
}
|
|
|
|
}
|
2020-08-15 21:12:17 +00:00
|
|
|
|
|
|
|
binding.more.setOnClickListener { "Not implemented yet".alert(this) }
|
|
|
|
binding.home.setOnClickListener { "Not implemented yet".alert(this) }
|
2020-08-17 20:25:39 +00:00
|
|
|
binding.tabs.setOnClickListener {
|
|
|
|
TabsDialog().show(this, model)
|
|
|
|
}
|
2020-08-15 14:52:27 +00:00
|
|
|
}
|
|
|
|
|
2020-08-15 20:33:44 +00:00
|
|
|
private fun externalProtocol(state: TvaState.NotGeminiRequest) {
|
2020-08-16 21:30:24 +00:00
|
|
|
loadingView(false)
|
2020-08-15 20:33:44 +00:00
|
|
|
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(state.uri.toString()))
|
|
|
|
startActivity(browserIntent)
|
|
|
|
}
|
|
|
|
|
2020-08-15 14:52:27 +00:00
|
|
|
private fun renderGemtext(state: TvaState.GeminiResponse) = runOnUiThread {
|
2020-08-16 21:30:24 +00:00
|
|
|
loadingView(false)
|
2020-08-15 20:44:57 +00:00
|
|
|
if(state.header.startsWith("2") && state.header.contains("text/gemini")) {
|
|
|
|
binding.addressEdit.setText(state.uri.toString())
|
|
|
|
adapter.render(state.lines)
|
|
|
|
}else{
|
2020-08-16 21:30:24 +00:00
|
|
|
"Server returned an error - or non gemtext mimetype not implemented yet: ${state.header}".alert(this)
|
2020-08-15 20:44:57 +00:00
|
|
|
}
|
2020-08-15 14:52:27 +00:00
|
|
|
}
|
2020-08-15 20:20:15 +00:00
|
|
|
|
2020-08-16 21:30:24 +00:00
|
|
|
private fun loadingView(visible: Boolean) = runOnUiThread {
|
|
|
|
binding.progressBar.visibleRetainingSpace(visible)
|
|
|
|
if(visible) binding.appBar.setExpanded(true)
|
|
|
|
}
|
|
|
|
|
2020-08-15 20:20:15 +00:00
|
|
|
@ExperimentalStdlibApi
|
|
|
|
override fun onBackPressed() {
|
|
|
|
if(model.canGoBack()){
|
|
|
|
model.goBack()
|
|
|
|
}else{
|
|
|
|
super.onBackPressed()
|
|
|
|
}
|
|
|
|
}
|
2020-08-16 20:06:11 +00:00
|
|
|
|
|
|
|
override fun onDestroy() {
|
|
|
|
super.onDestroy()
|
|
|
|
model.persistTabState()
|
|
|
|
}
|
2020-08-15 14:52:27 +00:00
|
|
|
}
|