package oppen.tva.ui import androidx.lifecycle.ViewModel import oppen.tva.io.Datasource import oppen.tva.io.TvaState import oppen.tva.io.history.CacheInterface import oppen.tva.io.history.Tab import java.net.URI class TvaViewModel: ViewModel() { private val gemini = Datasource.factory() private var onState: (state: TvaState) -> Unit = {} private var activeTab = 0 private lateinit var cache: CacheInterface 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)) } fun request(uri: URI){ gemini.request(uri){ state -> when(state){ is TvaState.AppQuery -> {} is TvaState.ResponseGemtext -> renderGemini(state) is TvaState.Requesting -> onState(state) is TvaState.ResponseError -> onState(state) is TvaState.NotGeminiRequest -> onState(state) is TvaState.ResponseText -> onState(state) } } } private fun renderGemini(state: TvaState.ResponseGemtext) { if(tabs[activeTab].history.isEmpty() || tabs[activeTab].history.last() != state.uri){ tabs[activeTab].add(state.uri) } onState(state) } fun canGoBack(): Boolean { println("canGoBack()...") tabs[activeTab].history.forEachIndexed{ index, uri -> println("canGoBack history $index: $uri") } return tabs[activeTab].history.size > 1 } @ExperimentalStdlibApi fun goBack(){ val previous = tabs[activeTab].getPrevious() if(previous == null){ println("Previous history URI is null") return } tabs[activeTab].history.removeLast() request(previous) } 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) }else if(deleteIndex < activeTab){ tabs.removeAt(deleteIndex) activeTab-- }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) } } onState(TvaState.TabChange(tabs.size)) } }