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

Fixed the selection bug in the account selector

parent 91429f1b
No related branches found
No related tags found
No related merge requests found
package de.kuschku.quasseldroid_ng.persistence package de.kuschku.quasseldroid_ng.persistence
import android.arch.paging.DataSource import android.arch.lifecycle.LiveData
import android.arch.persistence.room.* import android.arch.persistence.room.*
import android.content.Context import android.content.Context
...@@ -32,7 +32,7 @@ abstract class AccountDatabase : RoomDatabase() { ...@@ -32,7 +32,7 @@ abstract class AccountDatabase : RoomDatabase() {
fun findById(id: Long): AccountDatabase.Account? fun findById(id: Long): AccountDatabase.Account?
@Query("SELECT * FROM account ORDER BY lastUsed DESC") @Query("SELECT * FROM account ORDER BY lastUsed DESC")
fun all(): DataSource.Factory<Int, Account> fun all(): LiveData<List<Account>>
@Delete @Delete
fun delete(account: AccountDatabase.Account) fun delete(account: AccountDatabase.Account)
......
package de.kuschku.quasseldroid_ng.ui.setup.accounts package de.kuschku.quasseldroid_ng.ui.setup.accounts
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.arch.paging.PagedListAdapter import android.arch.lifecycle.LifecycleOwner
import android.support.v7.recyclerview.extensions.DiffCallback import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.Observer
import android.support.v7.util.DiffUtil
import android.support.v7.widget.AppCompatImageButton import android.support.v7.widget.AppCompatImageButton
import android.support.v7.widget.AppCompatRadioButton import android.support.v7.widget.AppCompatRadioButton
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
...@@ -14,16 +17,19 @@ import butterknife.BindView ...@@ -14,16 +17,19 @@ import butterknife.BindView
import butterknife.ButterKnife import butterknife.ButterKnife
import de.kuschku.quasseldroid_ng.R import de.kuschku.quasseldroid_ng.R
import de.kuschku.quasseldroid_ng.persistence.AccountDatabase import de.kuschku.quasseldroid_ng.persistence.AccountDatabase
import de.kuschku.quasseldroid_ng.util.helper.zip
class AccountAdapter : class AccountAdapter(
PagedListAdapter<AccountDatabase.Account, AccountAdapter.AccountViewHolder>(DIFF_CALLBACK) { owner: LifecycleOwner,
val liveData: LiveData<List<AccountDatabase.Account>>,
val selectedItem: MutableLiveData<Pair<Long, Long>>
) : RecyclerView.Adapter<AccountAdapter.AccountViewHolder>() {
private val actionListeners = mutableSetOf<(Long) -> Unit>() private val actionListeners = mutableSetOf<(Long) -> Unit>()
private val addListeners = mutableSetOf<() -> Unit>() private val addListeners = mutableSetOf<() -> Unit>()
private val selectionListeners = mutableSetOf<(Long) -> Unit>() private val selectionListeners = mutableSetOf<(Long) -> Unit>()
private val clickListener = object : ItemListener { private val clickListener = object : ItemListener {
override fun onAction(id: Long, pos: Int) { override fun onAction(id: Long, pos: Int) {
notifySelectionChanged(selectedItemView, pos)
selectionListener.invoke(id) selectionListener.invoke(id)
} }
} }
...@@ -36,16 +42,65 @@ class AccountAdapter : ...@@ -36,16 +42,65 @@ class AccountAdapter :
} }
} }
private fun updateSelection(id: Long) {
selectedItem.value = Pair(selectedItem.value?.second ?: -1, id)
}
private val selectionListener = { id: Long -> private val selectionListener = { id: Long ->
selectedItemId = id updateSelection(id)
for (selectionListener in selectionListeners) { for (selectionListener in selectionListeners) {
selectionListener.invoke(id) selectionListener.invoke(id)
} }
} }
private var selectedItemView = -1 val selectedItemId
var selectedItemId = -1L get() = selectedItem.value?.second
private set
private var list: List<Pair<Boolean, AccountDatabase.Account>> = emptyList()
init {
selectedItem.value = Pair(-1, -1)
liveData.zip(selectedItem).observe(owner, Observer { it ->
val list = it?.first
val oldSelected = it?.second?.first ?: -1
val selected = it?.second?.second ?: -1
val oldList = this.list
val newList: List<Pair<Boolean, AccountDatabase.Account>> = list.orEmpty().map {
Pair(selected == it.id, it)
}
this.list = newList
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldList[oldItemPosition].second
val newItem = newList[newItemPosition].second
return oldItem.id == newItem.id
}
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldList[oldItemPosition].second
val newItem = newList[newItemPosition].second
return oldItem == newItem &&
oldItem.id != selected &&
newItem.id != selected &&
oldItem.id != oldSelected &&
newItem.id != oldSelected
}
}).dispatchUpdatesTo(this)
})
}
private val addListener = { private val addListener = {
for (addListener in addListeners) { for (addListener in addListeners) {
...@@ -81,16 +136,8 @@ class AccountAdapter : ...@@ -81,16 +136,8 @@ class AccountAdapter :
@SuppressLint("RecyclerView") position: Int) { @SuppressLint("RecyclerView") position: Int) {
when (holder) { when (holder) {
is AccountViewHolder.Item -> { is AccountViewHolder.Item -> {
val account = getItem(position) val item = list[position]
if (account == null) { holder.bind(item.second, item.first)
holder.clear()
} else {
val selected = account.id == selectedItemId
if (selected) {
selectedItemView = position
}
holder.bind(account, selected)
}
} }
is AccountViewHolder.Add -> { is AccountViewHolder.Add -> {
} }
...@@ -98,7 +145,7 @@ class AccountAdapter : ...@@ -98,7 +145,7 @@ class AccountAdapter :
} }
override fun getItemViewType(position: Int) = when (position) { override fun getItemViewType(position: Int) = when (position) {
super.getItemCount() -> TYPE_ADD list.size -> TYPE_ADD
else -> TYPE_ACCOUNT else -> TYPE_ACCOUNT
} }
...@@ -117,44 +164,18 @@ class AccountAdapter : ...@@ -117,44 +164,18 @@ class AccountAdapter :
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return super.getItemCount() + 1 return list.size + 1
} }
companion object { companion object {
private const val TYPE_ACCOUNT = 0 private const val TYPE_ACCOUNT = 0
private const val TYPE_ADD = 1 private const val TYPE_ADD = 1
private val DIFF_CALLBACK = object : DiffCallback<AccountDatabase.Account>() {
override fun areContentsTheSame(oldItem: AccountDatabase.Account,
newItem: AccountDatabase.Account): Boolean {
return oldItem == newItem
}
override fun areItemsTheSame(oldItem: AccountDatabase.Account,
newItem: AccountDatabase.Account): Boolean {
return oldItem.id == newItem.id
}
}
} }
fun selectAccount(id: Long) { fun selectAccount(id: Long) {
selectedItemView = -1
selectionListener(id) selectionListener(id)
} }
fun notifySelectionChanged(from: Int?, to: Int?) {
val _from = from ?: -1
val _to = to ?: -1
if (_from != -1)
notifyItemChanged(_from)
selectedItemView = _to
if (_to != -1)
notifyItemChanged(_to)
}
interface ItemListener { interface ItemListener {
fun onAction(id: Long, pos: Int) fun onAction(id: Long, pos: Int)
} }
......
...@@ -27,7 +27,9 @@ class AccountSelectionActivity : SetupActivity() { ...@@ -27,7 +27,9 @@ class AccountSelectionActivity : SetupActivity() {
putLong(Keys.Status.selectedAccount, data.getLong(Keys.Status.selectedAccount, -1)) putLong(Keys.Status.selectedAccount, data.getLong(Keys.Status.selectedAccount, -1))
putBoolean(Keys.Status.reconnect, true) putBoolean(Keys.Status.reconnect, true)
} }
startActivityForResult(Intent(this, ChatActivity::class.java), REQUEST_CHAT) val intent = Intent(this, ChatActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
startActivityForResult(intent, REQUEST_CHAT)
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
...@@ -39,7 +41,9 @@ class AccountSelectionActivity : SetupActivity() { ...@@ -39,7 +41,9 @@ class AccountSelectionActivity : SetupActivity() {
setInitData(data) setInitData(data)
if (statusPreferences.getBoolean(Keys.Status.reconnect, false) && selectedAccount != -1L) { if (statusPreferences.getBoolean(Keys.Status.reconnect, false) && selectedAccount != -1L) {
startActivityForResult(Intent(this, ChatActivity::class.java), REQUEST_CHAT) val intent = Intent(this, ChatActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
startActivityForResult(intent, REQUEST_CHAT)
} }
} }
......
...@@ -3,7 +3,6 @@ package de.kuschku.quasseldroid_ng.ui.setup.accounts ...@@ -3,7 +3,6 @@ package de.kuschku.quasseldroid_ng.ui.setup.accounts
import android.app.Activity import android.app.Activity
import android.arch.lifecycle.Observer import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders import android.arch.lifecycle.ViewModelProviders
import android.arch.paging.PagedList
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v7.widget.DefaultItemAnimator import android.support.v7.widget.DefaultItemAnimator
...@@ -24,21 +23,21 @@ class AccountSelectionSlide : SlideFragment() { ...@@ -24,21 +23,21 @@ class AccountSelectionSlide : SlideFragment() {
@BindView(R.id.account_list) @BindView(R.id.account_list)
lateinit var accountList: RecyclerView lateinit var accountList: RecyclerView
override fun isValid() = adapter.selectedItemId != -1L override fun isValid() = adapter?.selectedItemId ?: -1L != -1L
override val title = R.string.slideAccountSelectTitle override val title = R.string.slideAccountSelectTitle
override val description = R.string.slideAccountSelectDescription override val description = R.string.slideAccountSelectDescription
override fun setData(data: Bundle) { override fun setData(data: Bundle) {
if (data.containsKey("selectedAccount")) if (data.containsKey("selectedAccount"))
adapter.selectAccount(data.getLong("selectedAccount")) adapter?.selectAccount(data.getLong("selectedAccount"))
} }
override fun getData(data: Bundle) { override fun getData(data: Bundle) {
data.putLong("selectedAccount", adapter.selectedItemId) data.putLong("selectedAccount", adapter?.selectedItemId ?: -1L)
} }
private val adapter = AccountAdapter() private var adapter: AccountAdapter? = null
override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateContent(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View { savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.setup_select_account, container, false) val view = inflater.inflate(R.layout.setup_select_account, container, false)
...@@ -46,8 +45,8 @@ class AccountSelectionSlide : SlideFragment() { ...@@ -46,8 +45,8 @@ class AccountSelectionSlide : SlideFragment() {
val accountViewModel = ViewModelProviders.of(this).get( val accountViewModel = ViewModelProviders.of(this).get(
AccountViewModel::class.java AccountViewModel::class.java
) )
val firstObserver = object : Observer<PagedList<AccountDatabase.Account>?> { val firstObserver = object : Observer<List<AccountDatabase.Account>?> {
override fun onChanged(t: PagedList<AccountDatabase.Account>?) { override fun onChanged(t: List<AccountDatabase.Account>?) {
if (t?.isEmpty() != false) if (t?.isEmpty() != false)
startActivityForResult( startActivityForResult(
Intent(context, AccountSetupActivity::class.java), Intent(context, AccountSetupActivity::class.java),
...@@ -57,10 +56,12 @@ class AccountSelectionSlide : SlideFragment() { ...@@ -57,10 +56,12 @@ class AccountSelectionSlide : SlideFragment() {
} }
} }
accountViewModel.accounts.observe(this, firstObserver) accountViewModel.accounts.observe(this, firstObserver)
accountViewModel.accounts.observe(this, Observer(adapter::setList))
accountList.layoutManager = LinearLayoutManager(context) accountList.layoutManager = LinearLayoutManager(context)
accountList.itemAnimator = DefaultItemAnimator() accountList.itemAnimator = DefaultItemAnimator()
val adapter = AccountAdapter(this, accountViewModel.accounts, accountViewModel.selectedItem)
this.adapter = adapter
accountList.adapter = adapter accountList.adapter = adapter
adapter.addAddListener { adapter.addAddListener {
startActivityForResult(Intent(context, AccountSetupActivity::class.java), -1) startActivityForResult(Intent(context, AccountSetupActivity::class.java), -1)
} }
......
...@@ -3,14 +3,13 @@ package de.kuschku.quasseldroid_ng.ui.setup.accounts ...@@ -3,14 +3,13 @@ package de.kuschku.quasseldroid_ng.ui.setup.accounts
import android.app.Application import android.app.Application
import android.arch.lifecycle.AndroidViewModel import android.arch.lifecycle.AndroidViewModel
import android.arch.lifecycle.LiveData import android.arch.lifecycle.LiveData
import android.arch.paging.LivePagedListBuilder import android.arch.lifecycle.MutableLiveData
import android.arch.paging.PagedList
import de.kuschku.quasseldroid_ng.persistence.AccountDatabase import de.kuschku.quasseldroid_ng.persistence.AccountDatabase
class AccountViewModel(application: Application) : AndroidViewModel(application) { class AccountViewModel(application: Application) : AndroidViewModel(application) {
private val database: AccountDatabase = AccountDatabase.Creator.init( private val database: AccountDatabase = AccountDatabase.Creator.init(
getApplication() getApplication()
) )
val accounts: LiveData<PagedList<AccountDatabase.Account>> val accounts: LiveData<List<AccountDatabase.Account>> = database.accounts().all()
= LivePagedListBuilder(database.accounts().all(), 20).build() val selectedItem = MutableLiveData<Pair<Long, Long>>()
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment