From 0765d85e52c92e09d995c0dbb3d4be490ec990f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96ppen?= Date: Mon, 17 Aug 2020 21:25:39 +0100 Subject: [PATCH] untested tab management --- app/src/main/java/oppen/tva/io/TvaState.kt | 2 + app/src/main/java/oppen/tva/ui/NewTabPopup.kt | 6 ++- app/src/main/java/oppen/tva/ui/TvaActivity.kt | 23 +++++++--- .../main/java/oppen/tva/ui/TvaViewModel.kt | 45 +++++++++++++++++-- .../java/oppen/tva/ui/tabs/TabsAdapter.kt | 35 +++++++++++++++ .../main/java/oppen/tva/ui/tabs/TabsDialog.kt | 34 ++++++++++++++ app/src/main/res/drawable/vector_cancel.xml | 10 +++++ app/src/main/res/drawable/vector_close.xml | 10 +++++ app/src/main/res/layout/dialog_tabs.xml | 43 ++++++++++++++++++ app/src/main/res/layout/grid_cell_tab.xml | 31 +++++++++++++ 10 files changed, 229 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/oppen/tva/ui/tabs/TabsAdapter.kt create mode 100644 app/src/main/java/oppen/tva/ui/tabs/TabsDialog.kt create mode 100644 app/src/main/res/drawable/vector_cancel.xml create mode 100644 app/src/main/res/drawable/vector_close.xml create mode 100644 app/src/main/res/layout/dialog_tabs.xml create mode 100644 app/src/main/res/layout/grid_cell_tab.xml diff --git a/app/src/main/java/oppen/tva/io/TvaState.kt b/app/src/main/java/oppen/tva/io/TvaState.kt index 9c1ff9d..8875faf 100644 --- a/app/src/main/java/oppen/tva/io/TvaState.kt +++ b/app/src/main/java/oppen/tva/io/TvaState.kt @@ -7,5 +7,7 @@ sealed class TvaState { data class Requesting(val uri: URI): TvaState() data class NotGeminiRequest(val uri: URI) : TvaState() data class GeminiResponse(val uri: URI, val header: String, val lines: List) : TvaState() + data class TabChange(val count: Int) : TvaState() + object Blank: TvaState() object GeminiPrintWriterError : TvaState() } \ No newline at end of file diff --git a/app/src/main/java/oppen/tva/ui/NewTabPopup.kt b/app/src/main/java/oppen/tva/ui/NewTabPopup.kt index 84a9c7a..2196dfe 100644 --- a/app/src/main/java/oppen/tva/ui/NewTabPopup.kt +++ b/app/src/main/java/oppen/tva/ui/NewTabPopup.kt @@ -9,11 +9,15 @@ import java.net.URI object NewTabPopup { - fun show(uri: URI, view: View?, onMenuOption: (menuId: Int) -> Unit){ + fun show(view: View?, onMenuOption: (menuId: Int) -> Unit){ if(view != null) { val popup = PopupMenu(view.context, view) val inflater: MenuInflater = popup.menuInflater inflater.inflate(R.menu.link_menu, popup.menu) + popup.setOnMenuItemClickListener { menuItem -> + onMenuOption(menuItem.itemId) + true + } popup.show() } } diff --git a/app/src/main/java/oppen/tva/ui/TvaActivity.kt b/app/src/main/java/oppen/tva/ui/TvaActivity.kt index 96ff9ef..18048ad 100644 --- a/app/src/main/java/oppen/tva/ui/TvaActivity.kt +++ b/app/src/main/java/oppen/tva/ui/TvaActivity.kt @@ -3,18 +3,17 @@ package oppen.tva.ui import android.content.Intent import android.net.Uri import android.os.Bundle -import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil import androidx.recyclerview.widget.LinearLayoutManager -import com.google.android.material.badge.BadgeDrawable import oppen.alert import oppen.tva.R import oppen.tva.databinding.ActivityTvaBinding import oppen.tva.io.TvaState import oppen.tva.io.history.CacheInterface +import oppen.tva.ui.tabs.TabsDialog import oppen.visibleRetainingSpace @@ -24,8 +23,13 @@ class TvaActivity : AppCompatActivity() { private lateinit var binding: ActivityTvaBinding private val adapter = GemtextAdapter { uri, longTap, view -> if(longTap){ - NewTabPopup.show(uri, view){ menuId -> - + NewTabPopup.show(view){ menuId -> + when (menuId) { + R.id.link_menu_open_in_new_tab -> { + model.newTab(uri) + } + R.id.link_menu_copy -> "Not implemented yet".alert(this) + } } }else{ model.request(uri) @@ -48,7 +52,12 @@ class TvaActivity : AppCompatActivity() { is TvaState.Requesting -> loadingView(true) is TvaState.NotGeminiRequest -> externalProtocol(state) is TvaState.GeminiResponse -> renderGemtext(state) - TvaState.GeminiPrintWriterError -> TODO() + 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) } } @@ -64,7 +73,9 @@ class TvaActivity : AppCompatActivity() { binding.more.setOnClickListener { "Not implemented yet".alert(this) } binding.home.setOnClickListener { "Not implemented yet".alert(this) } - binding.tabs.setOnClickListener { "Not implemented yet".alert(this) } + binding.tabs.setOnClickListener { + TabsDialog().show(this, model) + } } private fun externalProtocol(state: TvaState.NotGeminiRequest) { diff --git a/app/src/main/java/oppen/tva/ui/TvaViewModel.kt b/app/src/main/java/oppen/tva/ui/TvaViewModel.kt index 9e2d3ef..0a31620 100644 --- a/app/src/main/java/oppen/tva/ui/TvaViewModel.kt +++ b/app/src/main/java/oppen/tva/ui/TvaViewModel.kt @@ -14,26 +14,35 @@ class TvaViewModel: ViewModel() { private var activeTab = 0 private lateinit var cache: CacheInterface - private var tabs = mutableListOf() + var tabs = mutableListOf() fun initialise(cache: CacheInterface, onState: (state: TvaState) -> Unit){ this.cache = cache this.onState = onState - cache.getTabs { tabs, activeIndex -> this.tabs.addAll(tabs) if(tabs.isEmpty()){ this.tabs.add(Tab(0)) activeTab = 0 request(URI.create("gemini://gemini.circumlunar.space/")) + onState(TvaState.TabChange(1)) }else{ activeTab = activeIndex request(tabs[activeTab].history.last()) + onState(TvaState.TabChange(tabs.size)) } } } + fun newTab(uri: URI) { + val newTab = Tab(tabs.size) + tabs.add(newTab) + activeTab = newTab.index + onState(TvaState.TabChange(tabs.size)) + request(uri) + } + fun request(address: String) { request(URI.create(address)) } @@ -56,7 +65,6 @@ class TvaViewModel: ViewModel() { } onState(state) - } fun canGoBack(): Boolean { @@ -82,4 +90,35 @@ class TvaViewModel: ViewModel() { fun persistTabState() = cache.update(tabs, activeTab) + + fun changeTab(changeIndex: Int) { + activeTab = changeIndex + request(tabs[activeTab].history.last()) + } + + fun deleteTab(deleteIndex: Int) { + + if(deleteIndex > activeTab){ + tabs.removeAt(deleteIndex) + onState(TvaState.TabChange(tabs.size)) + }else if(deleteIndex < activeTab){ + tabs.removeAt(deleteIndex) + activeTab-- + onState(TvaState.TabChange(tabs.size)) + }else if(deleteIndex == activeTab){ + if(tabs.size > 1){ + tabs.removeAt(deleteIndex) + if(activeTab < tabs.size - 1){ + activeTab-- + }else{ + activeTab = tabs.size -1 + } + request(tabs[activeTab].history.last()) + }else{ + //Only one tab - we want a fresh state + tabs.first().history.clear() + onState(TvaState.Blank) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/oppen/tva/ui/tabs/TabsAdapter.kt b/app/src/main/java/oppen/tva/ui/tabs/TabsAdapter.kt new file mode 100644 index 0000000..ef2547f --- /dev/null +++ b/app/src/main/java/oppen/tva/ui/tabs/TabsAdapter.kt @@ -0,0 +1,35 @@ +package oppen.tva.ui.tabs + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import kotlinx.android.synthetic.main.grid_cell_tab.view.* +import oppen.tva.R +import oppen.tva.io.history.Tab + +class TabsAdapter( + private val tabs: List, + val onTabDelete: (index: Int) -> Unit, + val onTabChange: (index: Int) -> Unit): RecyclerView.Adapter() { + + class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.grid_cell_tab, parent, false)) + } + + override fun getItemCount(): Int = tabs.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + val tab = tabs[position] + + holder.itemView.tab_last_uri.text = "${tab.history.last()}" + holder.itemView.remove_tab.setOnClickListener { + onTabDelete(holder.adapterPosition) + } + holder.itemView.tab_cell.setOnClickListener { + onTabChange(holder.adapterPosition) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/oppen/tva/ui/tabs/TabsDialog.kt b/app/src/main/java/oppen/tva/ui/tabs/TabsDialog.kt new file mode 100644 index 0000000..5df69d8 --- /dev/null +++ b/app/src/main/java/oppen/tva/ui/tabs/TabsDialog.kt @@ -0,0 +1,34 @@ +package oppen.tva.ui.tabs + +import android.content.Context +import android.view.View +import androidx.appcompat.app.AppCompatDialog +import androidx.recyclerview.widget.GridLayoutManager +import kotlinx.android.synthetic.main.dialog_tabs.view.* +import oppen.tva.R +import oppen.tva.ui.TvaViewModel + +class TabsDialog { + + fun show(context: Context, model: TvaViewModel){ + val dialog = AppCompatDialog(context, R.style.AppTheme) + + val view = View.inflate(context, R.layout.dialog_tabs, null) + dialog.setContentView(view) + + view.close_tab_dialog.setOnClickListener { + dialog.dismiss() + } + + view.tab_dialog_recycler.layoutManager = GridLayoutManager(context, 2) + view.tab_dialog_recycler.adapter = TabsAdapter(model.tabs, { deleteIndex -> + model.deleteTab(deleteIndex) + dialog.dismiss() + }){ changeIndex -> + model.changeTab(changeIndex) + dialog.dismiss() + } + + dialog.show() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/vector_cancel.xml b/app/src/main/res/drawable/vector_cancel.xml new file mode 100644 index 0000000..1ab7bac --- /dev/null +++ b/app/src/main/res/drawable/vector_cancel.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/vector_close.xml b/app/src/main/res/drawable/vector_close.xml new file mode 100644 index 0000000..16d6d37 --- /dev/null +++ b/app/src/main/res/drawable/vector_close.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/dialog_tabs.xml b/app/src/main/res/layout/dialog_tabs.xml new file mode 100644 index 0000000..2bb7069 --- /dev/null +++ b/app/src/main/res/layout/dialog_tabs.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/grid_cell_tab.xml b/app/src/main/res/layout/grid_cell_tab.xml new file mode 100644 index 0000000..2af76c0 --- /dev/null +++ b/app/src/main/res/layout/grid_cell_tab.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file