Skip to content
Snippets Groups Projects
Commit c2382f04 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Buffers can be hidden or made visible

parent bb9a0538
No related branches found
No related tags found
No related merge requests found
...@@ -29,6 +29,7 @@ class BufferListAdapter( ...@@ -29,6 +29,7 @@ class BufferListAdapter(
lifecycleOwner: LifecycleOwner, lifecycleOwner: LifecycleOwner,
liveData: LiveData<List<BufferProps>?>, liveData: LiveData<List<BufferProps>?>,
private val selectedBuffer: MutableLiveData<BufferId>, private val selectedBuffer: MutableLiveData<BufferId>,
private val collapsedNetworks: MutableLiveData<Set<NetworkId>>,
runInBackground: (() -> Unit) -> Any, runInBackground: (() -> Unit) -> Any,
runOnUiThread: (Runnable) -> Any, runOnUiThread: (Runnable) -> Any,
private val clickListener: ((BufferId) -> Unit)? = null, private val clickListener: ((BufferId) -> Unit)? = null,
...@@ -36,8 +37,6 @@ class BufferListAdapter( ...@@ -36,8 +37,6 @@ class BufferListAdapter(
) : RecyclerView.Adapter<BufferListAdapter.BufferViewHolder>() { ) : RecyclerView.Adapter<BufferListAdapter.BufferViewHolder>() {
var data = mutableListOf<BufferListItem>() var data = mutableListOf<BufferListItem>()
private val collapsedNetworks = MutableLiveData<Set<NetworkId>>()
fun expandListener(networkId: NetworkId) { fun expandListener(networkId: NetworkId) {
if (collapsedNetworks.value.orEmpty().contains(networkId)) if (collapsedNetworks.value.orEmpty().contains(networkId))
collapsedNetworks.postValue(collapsedNetworks.value.orEmpty() - networkId) collapsedNetworks.postValue(collapsedNetworks.value.orEmpty() - networkId)
...@@ -58,9 +57,6 @@ class BufferListAdapter( ...@@ -58,9 +57,6 @@ class BufferListAdapter(
} }
init { init {
collapsedNetworks.value = emptySet()
selectedBuffer.value = -1
liveData.zip(collapsedNetworks, selectedBuffer).observe( liveData.zip(collapsedNetworks, selectedBuffer).observe(
lifecycleOwner, Observer { it: Triple<List<BufferProps>?, Set<NetworkId>, BufferId>? -> lifecycleOwner, Observer { it: Triple<List<BufferProps>?, Set<NetworkId>, BufferId>? ->
runInBackground { runInBackground {
...@@ -163,9 +159,16 @@ class BufferListAdapter( ...@@ -163,9 +159,16 @@ class BufferListAdapter(
val description: CharSequence, val description: CharSequence,
val activity: Message_Types, val activity: Message_Types,
val highlights: Int = 0, val highlights: Int = 0,
val bufferActivity: Buffer_Activities = Buffer_Activity.of(Buffer_Activity.NoActivity) val bufferActivity: Buffer_Activities = Buffer_Activity.of(Buffer_Activity.NoActivity),
val hiddenState: HiddenState
) )
enum class HiddenState {
VISIBLE,
HIDDEN_TEMPORARY,
HIDDEN_PERMANENT
}
data class BufferState( data class BufferState(
val networkExpanded: Boolean, val networkExpanded: Boolean,
val selected: Boolean val selected: Boolean
......
...@@ -53,7 +53,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -53,7 +53,9 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
val selected = viewModel.selectedBuffer.value val selected = viewModel.selectedBuffer.value
val info = selected?.info val info = selected?.info
val session = viewModel.session.value val session = viewModel.session.value
val bufferSyncer = session?.bufferSyncer
val network = session?.networks?.get(selected?.info?.networkId) val network = session?.networks?.get(selected?.info?.networkId)
val bufferViewConfig = viewModel.getBufferViewConfig().value
return if (info != null && session != null) { return if (info != null && session != null) {
when (item?.itemId) { when (item?.itemId) {
...@@ -93,6 +95,20 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -93,6 +95,20 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
actionMode?.finish() actionMode?.finish()
true true
} }
R.id.action_unhide -> {
bufferSyncer?.let {
bufferViewConfig?.requestAddBuffer(info, bufferSyncer)
}
true
}
R.id.action_hide_temp -> {
bufferViewConfig?.requestRemoveBuffer(info.bufferId)
true
}
R.id.action_hide_perm -> {
bufferViewConfig?.requestRemoveBufferPermanently(info.bufferId)
true
}
else -> false else -> false
} }
} else { } else {
...@@ -180,6 +196,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -180,6 +196,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
} }
}, },
viewModel.selectedBufferId, viewModel.selectedBufferId,
viewModel.collapsedNetworks,
handlerThread::post, handlerThread::post,
activity!!::runOnUiThread, activity!!::runOnUiThread,
clickListener, clickListener,
...@@ -196,9 +213,27 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -196,9 +213,27 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
R.id.action_disconnect, R.id.action_disconnect,
R.id.action_join, R.id.action_join,
R.id.action_part, R.id.action_part,
R.id.action_delete R.id.action_delete,
R.id.action_unhide,
R.id.action_hide_temp,
R.id.action_hide_perm
) )
val visibilityActions = when (buffer.hiddenState) {
BufferListAdapter.HiddenState.VISIBLE -> setOf(
R.id.action_hide_temp,
R.id.action_hide_perm
)
BufferListAdapter.HiddenState.HIDDEN_TEMPORARY -> setOf(
R.id.action_unhide,
R.id.action_hide_perm
)
BufferListAdapter.HiddenState.HIDDEN_PERMANENT -> setOf(
R.id.action_unhide,
R.id.action_hide_temp
)
}
val availableActions = when (buffer.info?.type?.enabledValues()?.firstOrNull()) { val availableActions = when (buffer.info?.type?.enabledValues()?.firstOrNull()) {
Buffer_Type.StatusBuffer -> { Buffer_Type.StatusBuffer -> {
when (buffer.connectionState) { when (buffer.connectionState) {
...@@ -214,12 +249,12 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -214,12 +249,12 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
setOf(R.id.action_part) setOf(R.id.action_part)
} else { } else {
setOf(R.id.action_join, R.id.action_delete) setOf(R.id.action_join, R.id.action_delete)
} } + visibilityActions
} }
Buffer_Type.QueryBuffer -> { Buffer_Type.QueryBuffer -> {
setOf(R.id.action_delete) setOf(R.id.action_delete) + visibilityActions
} }
else -> emptySet() else -> visibilityActions
} }
val unavailableActions = allActions - availableActions val unavailableActions = allActions - availableActions
...@@ -236,7 +271,17 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -236,7 +271,17 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
} }
}) })
chatListToolbar.startActionMode(actionModeCallback) chatListToolbar.inflateMenu(R.menu.context_bufferlist)
chatListToolbar.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.action_show_hidden -> {
item.isChecked = !item.isChecked
viewModel.showHidden.value = item.isChecked
true
}
else -> false
}
}
chatList.layoutManager = LinearLayoutManager(context) chatList.layoutManager = LinearLayoutManager(context)
chatList.itemAnimator = DefaultItemAnimator() chatList.itemAnimator = DefaultItemAnimator()
chatList.setItemViewCacheSize(10) chatList.setItemViewCacheSize(10)
...@@ -266,6 +311,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() { ...@@ -266,6 +311,7 @@ class BufferViewConfigFragment : ServiceBoundFragment() {
data class SelectedItem( data class SelectedItem(
val info: BufferInfo? = null, val info: BufferInfo? = null,
val connectionState: INetwork.ConnectionState = INetwork.ConnectionState.Disconnected, val connectionState: INetwork.ConnectionState = INetwork.ConnectionState.Disconnected,
val joined: Boolean = false val joined: Boolean = false,
val hiddenState: BufferListAdapter.HiddenState = BufferListAdapter.HiddenState.VISIBLE
) )
} }
...@@ -5,10 +5,12 @@ import android.arch.lifecycle.MutableLiveData ...@@ -5,10 +5,12 @@ import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel import android.arch.lifecycle.ViewModel
import de.kuschku.libquassel.protocol.BufferId import de.kuschku.libquassel.protocol.BufferId
import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.protocol.Buffer_Type
import de.kuschku.libquassel.protocol.NetworkId
import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.BufferInfo
import de.kuschku.libquassel.quassel.syncables.BufferViewConfig import de.kuschku.libquassel.quassel.syncables.BufferViewConfig
import de.kuschku.libquassel.quassel.syncables.IrcChannel import de.kuschku.libquassel.quassel.syncables.IrcChannel
import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.quassel.syncables.IrcUser
import de.kuschku.libquassel.quassel.syncables.Network
import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.Backend
import de.kuschku.libquassel.session.ISession import de.kuschku.libquassel.session.ISession
import de.kuschku.libquassel.session.SessionManager import de.kuschku.libquassel.session.SessionManager
...@@ -192,10 +194,23 @@ class QuasselViewModel : ViewModel() { ...@@ -192,10 +194,23 @@ class QuasselViewModel : ViewModel() {
} }
} }
val showHidden = MutableLiveData<Boolean>()
val collapsedNetworks = MutableLiveData<Set<NetworkId>>()
val selectedBufferId = MutableLiveData<BufferId>() val selectedBufferId = MutableLiveData<BufferId>()
val selectedBuffer = session.zip(selectedBufferId).switchMapRx { (session, buffer) -> val selectedBuffer = session.zip(
selectedBufferId, bufferViewConfig
).switchMapRx { (session, buffer, bufferViewConfig) ->
val bufferSyncer = session?.bufferSyncer val bufferSyncer = session?.bufferSyncer
if (bufferSyncer != null) { if (bufferSyncer != null && bufferViewConfig != null) {
val hiddenState = when {
bufferViewConfig.removedBuffers().contains(buffer) ->
BufferListAdapter.HiddenState.HIDDEN_PERMANENT
bufferViewConfig.temporarilyRemovedBuffers().contains(buffer) ->
BufferListAdapter.HiddenState.HIDDEN_TEMPORARY
else ->
BufferListAdapter.HiddenState.VISIBLE
}
val info = bufferSyncer.bufferInfo(buffer) val info = bufferSyncer.bufferInfo(buffer)
if (info != null) { if (info != null) {
val network = session.networks[info.networkId] val network = session.networks[info.networkId]
...@@ -204,7 +219,8 @@ class QuasselViewModel : ViewModel() { ...@@ -204,7 +219,8 @@ class QuasselViewModel : ViewModel() {
network?.liveConnectionState?.map { network?.liveConnectionState?.map {
BufferViewConfigFragment.SelectedItem( BufferViewConfigFragment.SelectedItem(
info, info,
connectionState = it connectionState = it,
hiddenState = hiddenState
) )
} }
} }
...@@ -212,14 +228,16 @@ class QuasselViewModel : ViewModel() { ...@@ -212,14 +228,16 @@ class QuasselViewModel : ViewModel() {
network?.liveIrcChannel(info.bufferName)?.map { network?.liveIrcChannel(info.bufferName)?.map {
BufferViewConfigFragment.SelectedItem( BufferViewConfigFragment.SelectedItem(
info, info,
joined = it != IrcChannel.NULL joined = it != IrcChannel.NULL,
hiddenState = hiddenState
) )
} }
} }
else -> Observable.just(BufferViewConfigFragment.SelectedItem(info)) else ->
Observable.just(BufferViewConfigFragment.SelectedItem(info, hiddenState = hiddenState))
} }
} else { } else {
Observable.just(BufferViewConfigFragment.SelectedItem(info)) Observable.just(BufferViewConfigFragment.SelectedItem(info, hiddenState = hiddenState))
} }
} else { } else {
Observable.just(BufferViewConfigFragment.SelectedItem()) Observable.just(BufferViewConfigFragment.SelectedItem())
...@@ -227,14 +245,25 @@ class QuasselViewModel : ViewModel() { ...@@ -227,14 +245,25 @@ class QuasselViewModel : ViewModel() {
} }
val bufferList: LiveData<Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>?> = session.zip( val bufferList: LiveData<Pair<BufferViewConfig?, List<BufferListAdapter.BufferProps>>?> = session.zip(
bufferViewConfig bufferViewConfig, showHidden
).switchMapRx { (session, config) -> ).switchMapRx { (session, config, showHiddenRaw) ->
val bufferSyncer = session?.bufferSyncer val bufferSyncer = session?.bufferSyncer
val showHidden = showHiddenRaw ?: false
if (bufferSyncer != null && config != null) { if (bufferSyncer != null && config != null) {
config.live_config.debounce(16, TimeUnit.MILLISECONDS).switchMap { currentConfig -> config.live_config.debounce(16, TimeUnit.MILLISECONDS).switchMap { currentConfig ->
config.live_buffers.switchMap { ids ->
bufferSyncer.liveBufferInfos().switchMap {
Observable.combineLatest( Observable.combineLatest(
listOf(
config.live_buffers,
config.live_temporarilyRemovedBuffers,
config.live_removedBuffers
),
object : Function<Array<Any>, List<Collection<BufferId>>> {
override fun apply(objects: Array<Any>): List<Collection<BufferId>> {
return objects.toList() as List<Collection<BufferId>>
}
}
).switchMap { (ids, temp, perm) ->
fun transformIds(ids: Collection<BufferId>, state: BufferListAdapter.HiddenState) =
ids.mapNotNull { id -> ids.mapNotNull { id ->
bufferSyncer.bufferInfo(id) bufferSyncer.bufferInfo(id)
}.filter { }.filter {
...@@ -249,7 +278,7 @@ class QuasselViewModel : ViewModel() { ...@@ -249,7 +278,7 @@ class QuasselViewModel : ViewModel() {
} else { } else {
it to network it to network
} }
}.map { (info, network) -> }.map<Pair<BufferInfo, Network>, Observable<BufferListAdapter.BufferProps>?> { (info, network) ->
bufferSyncer.liveActivity(info.bufferId).switchMap { activity -> bufferSyncer.liveActivity(info.bufferId).switchMap { activity ->
bufferSyncer.liveHighlightCount(info.bufferId).map { highlights -> bufferSyncer.liveHighlightCount(info.bufferId).map { highlights ->
activity to highlights activity to highlights
...@@ -270,7 +299,8 @@ class QuasselViewModel : ViewModel() { ...@@ -270,7 +299,8 @@ class QuasselViewModel : ViewModel() {
}, },
description = realName, description = realName,
activity = activity, activity = activity,
highlights = highlights highlights = highlights,
hiddenState = state
) )
} }
} }
...@@ -290,7 +320,8 @@ class QuasselViewModel : ViewModel() { ...@@ -290,7 +320,8 @@ class QuasselViewModel : ViewModel() {
}, },
description = topic, description = topic,
activity = activity, activity = activity,
highlights = highlights highlights = highlights,
hiddenState = state
) )
} }
} }
...@@ -303,7 +334,8 @@ class QuasselViewModel : ViewModel() { ...@@ -303,7 +334,8 @@ class QuasselViewModel : ViewModel() {
bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
description = "", description = "",
activity = activity, activity = activity,
highlights = highlights highlights = highlights,
hiddenState = state
) )
} }
} }
...@@ -314,12 +346,26 @@ class QuasselViewModel : ViewModel() { ...@@ -314,12 +346,26 @@ class QuasselViewModel : ViewModel() {
bufferStatus = BufferListAdapter.BufferStatus.OFFLINE, bufferStatus = BufferListAdapter.BufferStatus.OFFLINE,
description = "", description = "",
activity = activity, activity = activity,
highlights = highlights highlights = highlights,
hiddenState = state
) )
) )
} }
} }
}, object : Function<Array<Any>, List<BufferListAdapter.BufferProps>> { }
bufferSyncer.liveBufferInfos().switchMap {
val buffers = if (showHidden) {
transformIds(ids, BufferListAdapter.HiddenState.VISIBLE) +
transformIds(temp, BufferListAdapter.HiddenState.HIDDEN_TEMPORARY) +
transformIds(perm, BufferListAdapter.HiddenState.HIDDEN_PERMANENT)
} else {
transformIds(ids, BufferListAdapter.HiddenState.VISIBLE)
}
Observable.combineLatest(
buffers,
object : Function<Array<Any>, List<BufferListAdapter.BufferProps>> {
override fun apply(objects: Array<Any>): List<BufferListAdapter.BufferProps> { override fun apply(objects: Array<Any>): List<BufferListAdapter.BufferProps> {
return objects.toList() as List<BufferListAdapter.BufferProps> return objects.toList() as List<BufferListAdapter.BufferProps>
} }
...@@ -342,4 +388,10 @@ class QuasselViewModel : ViewModel() { ...@@ -342,4 +388,10 @@ class QuasselViewModel : ViewModel() {
) )
} }
} }
init {
showHidden.postValue(false)
selectedBufferId.postValue(-1)
collapsedNetworks.value = emptySet()
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item <item
android:id="@+id/action_connect" android:id="@+id/action_connect"
android:title="@string/label_connect" /> android:title="@string/label_connect" />
...@@ -15,5 +16,16 @@ ...@@ -15,5 +16,16 @@
<item <item
android:id="@+id/action_delete" android:id="@+id/action_delete"
android:title="@string/label_delete" /> android:title="@string/label_delete" />
<!--<item android:title="Merge" />--> <item
android:id="@+id/action_unhide"
android:title="@string/label_unhide"
app:showAsAction="never" />
<item
android:id="@+id/action_hide_temp"
android:title="@string/label_hide_temp"
app:showAsAction="never" />
<item
android:id="@+id/action_hide_perm"
android:title="@string/label_hide_perm"
app:showAsAction="never" />
</menu> </menu>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_show_hidden"
android:checkable="true"
android:title="@string/label_show_hidden" />
</menu>
\ No newline at end of file
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
<string name="label_delete">Delete</string> <string name="label_delete">Delete</string>
<string name="label_disconnect">Disconnect</string> <string name="label_disconnect">Disconnect</string>
<string name="label_filter_messages">Filter Messages</string> <string name="label_filter_messages">Filter Messages</string>
<string name="label_hide_perm">Hide Permanently</string>
<string name="label_hide_temp">Hide Temporarily</string>
<string name="label_input_history">Input History</string> <string name="label_input_history">Input History</string>
<string name="label_join">Join</string> <string name="label_join">Join</string>
<string name="label_open">Open</string> <string name="label_open">Open</string>
...@@ -19,6 +21,8 @@ ...@@ -19,6 +21,8 @@
<string name="label_save">Save</string> <string name="label_save">Save</string>
<string name="label_select_multiple">Select</string> <string name="label_select_multiple">Select</string>
<string name="label_settings">Settings</string> <string name="label_settings">Settings</string>
<string name="label_show_hidden">Show Hidden</string>
<string name="label_unhide">Make Visible</string>
<string name="label_status_disconnected">Disconnected</string> <string name="label_status_disconnected">Disconnected</string>
<string name="label_status_connecting">Connecting</string> <string name="label_status_connecting">Connecting</string>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment