Use 'FoldersLiveData' in 'ManageFoldersActivity'

This commit is contained in:
cketti 2019-12-10 13:29:35 +01:00
parent bdb244badf
commit b793f48afe
4 changed files with 89 additions and 177 deletions

View file

@ -6,6 +6,7 @@ import com.fsck.k9.autodiscovery.autodiscoveryModule
import com.fsck.k9.contacts.contactsModule
import com.fsck.k9.fragment.fragmentModule
import com.fsck.k9.ui.endtoend.endToEndUiModule
import com.fsck.k9.ui.managefolders.manageFoldersUiModule
import com.fsck.k9.ui.messagelist.messageListUiModule
import com.fsck.k9.ui.settings.settingsUiModule
import com.fsck.k9.ui.uiModule
@ -17,6 +18,7 @@ val uiModules = listOf(
settingsUiModule,
endToEndUiModule,
messageListUiModule,
manageFoldersUiModule,
fragmentModule,
contactsModule,
accountModule,

View file

@ -0,0 +1,8 @@
package com.fsck.k9.ui.managefolders
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module
val manageFoldersUiModule = module {
viewModel { ManageFoldersViewModel(get()) }
}

View file

@ -3,7 +3,6 @@ package com.fsck.k9.ui.managefolders
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.text.TextUtils.TruncateAt
import android.view.KeyEvent
import android.view.LayoutInflater
@ -28,78 +27,32 @@ import com.fsck.k9.DI
import com.fsck.k9.K9
import com.fsck.k9.Preferences
import com.fsck.k9.activity.ActivityListener
import com.fsck.k9.activity.FolderInfoHolder
import com.fsck.k9.activity.K9ListActivity
import com.fsck.k9.activity.setup.FolderSettings
import com.fsck.k9.controller.MessagingController
import com.fsck.k9.job.K9JobManager
import com.fsck.k9.mail.Folder.FolderClass
import com.fsck.k9.mailstore.LocalFolder
import com.fsck.k9.mailstore.DisplayFolder
import com.fsck.k9.ui.R
import com.fsck.k9.ui.folders.FolderIconProvider
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.fsck.k9.ui.helper.SizeFormatter
import java.util.Collections
import java.util.LinkedList
import com.fsck.k9.ui.observeNotNull
import java.util.Locale
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
import timber.log.Timber
class ManageFoldersActivity : K9ListActivity() {
private val viewModel: ManageFoldersViewModel by viewModel()
private val folderNameFormatter: FolderNameFormatter by inject()
private val jobManager = DI.get(K9JobManager::class.java)
private var folderListAdapter: FolderListAdapter? = null
private var inflater: LayoutInflater? = null
private var account: Account? = null
private val handler = FolderListHandler()
private val fontSizes = K9.fontSizes
private var context: Context? = null
private var actionBar: ActionBar? = null
internal inner class FolderListHandler : Handler() {
fun refreshTitle() {
runOnUiThread {
actionBar!!.setTitle(R.string.folders_action)
val operation = folderListAdapter!!.activityListener.getOperation(this@ManageFoldersActivity)
if (operation.length < 1) {
actionBar!!.subtitle = account!!.email
} else {
actionBar!!.subtitle = operation
}
}
}
fun newFolders(newFolders: List<FolderInfoHolder>?) {
runOnUiThread {
folderListAdapter!!.folders.clear()
folderListAdapter!!.folders.addAll(newFolders!!)
folderListAdapter!!.filteredFolders = folderListAdapter!!.folders
handler.dataChanged()
}
}
fun workingAccount(res: Int) {
runOnUiThread {
val toastText = getString(res, account!!.description)
val toast = Toast.makeText(application, toastText, Toast.LENGTH_SHORT)
toast.show()
}
}
fun accountSizeChanged(oldSize: Long, newSize: Long) {
runOnUiThread {
val toastText =
getString(R.string.account_size_changed, account!!.description, SizeFormatter.formatSize(application, oldSize), SizeFormatter.formatSize(application, newSize))
val toast = Toast.makeText(application, toastText, Toast.LENGTH_LONG)
toast.show()
}
}
fun progress(progress: Boolean) { // TODO: Display progress indicator
}
fun dataChanged() {
runOnUiThread { folderListAdapter!!.notifyDataSetChanged() }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setLayout(R.layout.folder_list)
@ -109,20 +62,36 @@ class ManageFoldersActivity : K9ListActivity() {
listView.scrollBarStyle = View.SCROLLBARS_INSIDE_OVERLAY
listView.isFastScrollEnabled = true
listView.isScrollingCacheEnabled = false
listView.onItemClickListener =
OnItemClickListener { parent, view, position, id -> FolderSettings.actionSettings(this@ManageFoldersActivity, account, (folderListAdapter!!.getItem(position) as FolderInfoHolder).serverId) }
listView.onItemClickListener = OnItemClickListener { _, _, position, _ ->
val folderServerId = (folderListAdapter!!.getItem(position) as DisplayFolder).folder.serverId
FolderSettings.actionSettings(this@ManageFoldersActivity, account, folderServerId)
}
listView.isSaveEnabled = true
inflater = layoutInflater
context = this
val accountUuid = intent.getStringExtra(EXTRA_ACCOUNT)
account = Preferences.getPreferences(this).getAccount(accountUuid)
val account = Preferences.getPreferences(this).getAccount(accountUuid)
if (account == null) {
finish()
return
}
this.account = account
initializeActivityView()
viewModel.getFolders(account).observeNotNull(this) { folders ->
updateFolderList(folders)
}
}
private fun updateFolderList(displayFolders: List<DisplayFolder>) {
folderListAdapter!!.apply {
folders.clear()
folders.addAll(displayFolders)
filteredFolders = folders
notifyDataSetChanged()
}
}
private fun initializeActionBar() {
@ -132,49 +101,19 @@ class ManageFoldersActivity : K9ListActivity() {
private fun initializeActivityView() {
folderListAdapter = FolderListAdapter()
restorePreviousData()
setListAdapter(folderListAdapter)
listView.isTextFilterEnabled =
folderListAdapter!!.filter != null // should never be false but better safe then sorry
}
private fun restorePreviousData() {
val previousData = lastCustomNonConfigurationInstance
if (previousData != null) {
folderListAdapter!!.folders = previousData as ArrayList<FolderInfoHolder>
folderListAdapter!!.filteredFolders = Collections.unmodifiableList(folderListAdapter!!.folders)
}
}
override fun onRetainCustomNonConfigurationInstance(): Any? {
return if (folderListAdapter == null) null else folderListAdapter!!.folders
}
public override fun onPause() {
super.onPause()
MessagingController.getInstance(application).removeListener(folderListAdapter!!.activityListener)
folderListAdapter!!.activityListener.onPause(this)
super.onPause()
}
/**
* On resume we refresh the folder list (in the background) and we refresh the
* messages for any folder that is currently open. This guarantees that things
* like unread message count and read status are updated.
*/
public override fun onResume() {
super.onResume()
if (!account!!.isAvailable(this)) {
Timber.i("Account is unavailable right now: $account")
finish()
return
}
if (folderListAdapter == null) initializeActivityView()
handler.refreshTitle()
MessagingController.getInstance(application).addListener(folderListAdapter!!.activityListener)
// account.refresh(Preferences.getPreferences(this));
onRefresh(!REFRESH_REMOTE)
MessagingController.getInstance(application).cancelNotificationsForAccount(account)
folderListAdapter!!.activityListener.onResume(this)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { // Shortcuts that work no matter what is selected
@ -211,7 +150,6 @@ class ManageFoldersActivity : K9ListActivity() {
jobManager.schedulePusherRefresh()
}
folderListAdapter!!.filter.filter(null)
onRefresh(false)
}
private fun onRefresh(forceRemote: Boolean) {
@ -247,7 +185,10 @@ class ManageFoldersActivity : K9ListActivity() {
}
private fun onCompact(account: Account?) {
handler.workingAccount(R.string.compacting_account)
val toastText = getString(R.string.compacting_account, account!!.description)
val toast = Toast.makeText(application, toastText, Toast.LENGTH_SHORT)
toast.show()
MessagingController.getInstance(application).compact(account, null)
}
@ -281,8 +222,8 @@ class ManageFoldersActivity : K9ListActivity() {
}
internal inner class FolderListAdapter : BaseAdapter(), Filterable {
var folders: MutableList<FolderInfoHolder> = ArrayList()
var filteredFolders = Collections.unmodifiableList(folders)
var folders: MutableList<DisplayFolder> = mutableListOf()
var filteredFolders = folders.toList()
private val filter: Filter = FolderListFilter()
private val folderIconProvider = FolderIconProvider(theme)
override fun getItem(position: Int): Any {
@ -290,7 +231,7 @@ class ManageFoldersActivity : K9ListActivity() {
}
override fun getItemId(position: Int): Long {
return filteredFolders[position].folder.databaseId
return filteredFolders[position].folder.id
}
override fun getCount(): Int {
@ -298,79 +239,22 @@ class ManageFoldersActivity : K9ListActivity() {
}
val activityListener: ActivityListener = object : ActivityListener() {
override fun listFoldersStarted(account: Account) {
if (account == this@ManageFoldersActivity.account) {
handler.progress(true)
}
super.listFoldersStarted(account)
}
override fun listFoldersFailed(account: Account, message: String) {
if (account == this@ManageFoldersActivity.account) {
handler.progress(false)
runOnUiThread { Toast.makeText(context, R.string.fetching_folders_failed, Toast.LENGTH_SHORT).show() }
}
super.listFoldersFailed(account, message)
}
override fun listFoldersFinished(account: Account) {
if (account == this@ManageFoldersActivity.account) {
handler.progress(false)
MessagingController.getInstance(application).refreshListener(this)
handler.dataChanged()
}
super.listFoldersFinished(account)
}
override fun listFolders(account: Account, folders: List<LocalFolder>) {
if (account == this@ManageFoldersActivity.account) {
val newFolders: MutableList<FolderInfoHolder> = LinkedList()
val topFolders: MutableList<FolderInfoHolder> = LinkedList()
val aMode = account.folderDisplayMode
for (folder in folders) {
val fMode = folder.displayClass
if (aMode == FolderMode.FIRST_CLASS && fMode != FolderClass.FIRST_CLASS ||
aMode == FolderMode.FIRST_AND_SECOND_CLASS && fMode != FolderClass.FIRST_CLASS && fMode != FolderClass.SECOND_CLASS ||
aMode == FolderMode.NOT_SECOND_CLASS && fMode == FolderClass.SECOND_CLASS) {
continue
}
var holder: FolderInfoHolder? = null
val folderIndex = getFolderIndex(folder.serverId)
if (folderIndex >= 0) {
holder = getItem(folderIndex) as FolderInfoHolder
}
if (holder == null) {
holder = FolderInfoHolder(folder, this@ManageFoldersActivity.account, -1)
} else {
holder.populate(folder, this@ManageFoldersActivity.account, -1)
}
if (folder.isInTopGroup) {
topFolders.add(holder)
} else {
newFolders.add(holder)
}
}
Collections.sort(newFolders)
Collections.sort(topFolders)
topFolders.addAll(newFolders)
handler.newFolders(topFolders)
}
super.listFolders(account, folders)
}
override fun accountSizeChanged(account: Account, oldSize: Long, newSize: Long) {
if (account == this@ManageFoldersActivity.account) {
handler.accountSizeChanged(oldSize, newSize)
runOnUiThread {
val toastText = getString(
R.string.account_size_changed,
account.description,
SizeFormatter.formatSize(application, oldSize),
SizeFormatter.formatSize(application, newSize)
)
val toast = Toast.makeText(application, toastText, Toast.LENGTH_LONG)
toast.show()
}
}
}
}
fun getFolderIndex(folder: String?): Int {
val searchHolder = FolderInfoHolder()
searchHolder.serverId = folder
return filteredFolders.indexOf(searchHolder)
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View? {
return if (position <= count) {
getItemView(position, convertView, parent)
@ -381,7 +265,7 @@ class ManageFoldersActivity : K9ListActivity() {
}
fun getItemView(itemPosition: Int, convertView: View?, parent: ViewGroup?): View {
val folder = getItem(itemPosition) as? FolderInfoHolder
val displayFolder = getItem(itemPosition) as DisplayFolder
val view: View
view = convertView ?: inflater!!.inflate(R.layout.folder_list_item, parent, false)
var holder = view.tag as? FolderViewHolder
@ -390,14 +274,12 @@ class ManageFoldersActivity : K9ListActivity() {
holder.folderName = view.findViewById(R.id.folder_name)
holder.folderIcon = view.findViewById(R.id.folder_icon)
holder.folderListItemLayout = view.findViewById(R.id.folder_list_item_layout)
holder.folderServerId = folder!!.serverId
holder.folderServerId = displayFolder.folder.serverId
view.tag = holder
}
if (folder == null) {
return view
}
holder.folderName!!.text = folder.displayName
holder.folderIcon!!.setImageResource(folderIconProvider.getFolderIcon(folder.folder.type))
holder.folderName!!.text = folderNameFormatter.displayName(displayFolder.folder)
holder.folderIcon!!.setImageResource(folderIconProvider.getFolderIcon(displayFolder.folder.type))
fontSizes.setViewTextSize(holder.folderName, fontSizes.folderName)
if (K9.isWrapFolderNames) {
holder.folderName!!.ellipsize = null
@ -426,34 +308,33 @@ class ManageFoldersActivity : K9ListActivity() {
val results = FilterResults()
val locale = Locale.getDefault()
if (searchTerm == null || searchTerm.length == 0) {
val list: List<FolderInfoHolder> = ArrayList(folders)
val list: List<DisplayFolder> = folders.toList()
results.values = list
results.count = list.size
} else {
val searchTermString = searchTerm.toString().toLowerCase(locale)
val words = searchTermString.split(" ").toTypedArray()
val wordCount = words.size
val newValues: MutableList<FolderInfoHolder> = ArrayList()
for (value in folders) {
if (value.displayName == null) {
continue
}
val valueText = value.displayName.toLowerCase(locale)
val newValues: MutableList<DisplayFolder> = mutableListOf()
for (displayFolder in folders) {
val displayName = folderNameFormatter.displayName(displayFolder.folder)
val valueText = displayName.toLowerCase(locale)
for (k in 0 until wordCount) {
if (valueText.contains(words[k])) {
newValues.add(value)
newValues.add(displayFolder)
break
}
}
}
results.values = newValues
results.values = newValues.toList()
results.count = newValues.size
}
return results
}
override fun publishResults(constraint: CharSequence?, results: FilterResults) {
filteredFolders = Collections.unmodifiableList(results.values as ArrayList<FolderInfoHolder?>)
@Suppress("UNCHECKED_CAST")
filteredFolders = results.values as List<DisplayFolder>
// Send notification that the data set changed now
notifyDataSetChanged()
}

View file

@ -0,0 +1,21 @@
package com.fsck.k9.ui.managefolders
import androidx.lifecycle.ViewModel
import com.fsck.k9.Account
import com.fsck.k9.ui.folders.FoldersLiveData
import com.fsck.k9.ui.folders.FoldersLiveDataFactory
class ManageFoldersViewModel(private val foldersLiveDataFactory: FoldersLiveDataFactory) : ViewModel() {
private var foldersLiveData: FoldersLiveData? = null
fun getFolders(account: Account): FoldersLiveData {
val liveData = foldersLiveData
if (liveData != null && liveData.accountUuid == account.uuid) {
return liveData
}
return foldersLiveDataFactory.create(account).also {
foldersLiveData = it
}
}
}