implemented accounts manager fragment

This commit is contained in:
Mariotaku Lee 2016-12-05 08:52:02 +08:00
parent c09ee57472
commit 277b99b0c1
6 changed files with 114 additions and 57 deletions

View File

@ -77,7 +77,7 @@ public class AccountUtils {
details.position = AccountExtensionsKt.getPosition(account, am);
details.credentials = AccountExtensionsKt.getCredentials(account, am);
details.user = AccountExtensionsKt.getAccountUser(account, am);
details.activated = AccountExtensionsKt.isAccountActivated(account, am);
details.activated = AccountExtensionsKt.isActivated(account, am);
details.type = AccountExtensionsKt.getAccountType(account, am);
details.credentials_type = AccountExtensionsKt.getCredentialsType(account, am);
return details;

View File

@ -409,7 +409,7 @@ public class DataStoreUtils implements Constants {
AccountManager am = AccountManager.get(context);
List<UserKey> keys = new ArrayList<>();
for (Account account : AccountUtils.getAccounts(am)) {
if (AccountExtensionsKt.isAccountActivated(account, am)) {
if (AccountExtensionsKt.isActivated(account, am)) {
keys.add(AccountExtensionsKt.getAccountKey(account, am));
}
}

View File

@ -41,12 +41,11 @@ class AccountDetailsAdapter(context: Context) : ArrayAdapter<AccountDetails>(con
override var isProfileImageDisplayed: Boolean = false
private var sortEnabled: Boolean = false
private var switchEnabled: Boolean = false
private var onAccountToggleListener: OnAccountToggleListener? = null
var accountToggleListener: ((Int, Boolean) -> Unit)? = null
private val checkedChangeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
val tag = buttonView.tag as? String ?: return@OnCheckedChangeListener
val accountKey = UserKey.valueOf(tag) ?: return@OnCheckedChangeListener
onAccountToggleListener?.onAccountToggle(accountKey, isChecked)
val position = buttonView.tag as? Int ?: return@OnCheckedChangeListener
accountToggleListener?.invoke(position, isChecked)
}
init {
@ -61,6 +60,7 @@ class AccountDetailsAdapter(context: Context) : ArrayAdapter<AccountDetails>(con
return@run h
}
val details = getItem(position)
holder.name.text = details.user.name
holder.screenName.text = String.format("@%s", details.user.screen_name)
holder.setAccountColor(details.color)
if (isProfileImageDisplayed) {
@ -72,7 +72,7 @@ class AccountDetailsAdapter(context: Context) : ArrayAdapter<AccountDetails>(con
holder.accountType.setImageResource(AccountUtils.getAccountTypeIcon(accountType))
holder.toggle.isChecked = details.activated
holder.toggle.setOnCheckedChangeListener(checkedChangeListener)
holder.toggle.tag = details.user.key
holder.toggle.tag = position
holder.toggleContainer.visibility = if (switchEnabled) View.VISIBLE else View.GONE
holder.setSortEnabled(sortEnabled)
return view
@ -103,23 +103,30 @@ class AccountDetailsAdapter(context: Context) : ArrayAdapter<AccountDetails>(con
}
override fun hasStableIds(): Boolean {
return true
}
override fun getItemId(position: Int): Long {
return getItem(position).key.hashCode().toLong()
}
fun setSwitchEnabled(enabled: Boolean) {
if (switchEnabled == enabled) return
switchEnabled = enabled
notifyDataSetChanged()
}
fun setOnAccountToggleListener(listener: OnAccountToggleListener) {
onAccountToggleListener = listener
}
fun setSortEnabled(sortEnabled: Boolean) {
if (this.sortEnabled == sortEnabled) return
this.sortEnabled = sortEnabled
notifyDataSetChanged()
}
interface OnAccountToggleListener {
fun onAccountToggle(accountId: UserKey, state: Boolean)
fun drop(from: Int, to: Int) {
val fromItem = getItem(from)
removeAt(from)
insert(fromItem, to)
}
}

View File

@ -66,14 +66,22 @@ fun Account.getAccountType(am: AccountManager): String {
return am.getUserData(this, ACCOUNT_USER_DATA_TYPE) ?: AccountType.TWITTER
}
fun Account.isAccountActivated(am: AccountManager): Boolean {
fun Account.isActivated(am: AccountManager): Boolean {
return am.getUserData(this, ACCOUNT_USER_DATA_ACTIVATED).orEmpty().toBoolean()
}
fun Account.setActivated(am: AccountManager, activated: Boolean) {
am.setUserData(this, ACCOUNT_USER_DATA_ACTIVATED, activated.toString())
}
fun Account.setColor(am: AccountManager, color: Int) {
am.setUserData(this, ACCOUNT_USER_DATA_COLOR, toHexColor(color))
}
fun Account.setPosition(am: AccountManager, position: Int) {
am.setUserData(this, ACCOUNT_USER_DATA_POSITION, position.toString())
}
private fun parseCredentials(authToken: String, @Credentials.Type authType: String): Credentials {
when (authType) {

View File

@ -4,21 +4,19 @@ import android.accounts.AccountManager
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.ContentValues
import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.graphics.Color
import android.os.Bundle
import android.support.v4.util.SimpleArrayMap
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.view.*
import android.view.ContextMenu.ContextMenuInfo
import android.widget.AdapterView
import android.widget.AdapterView.AdapterContextMenuInfo
import kotlinx.android.synthetic.main.layout_draggable_list_with_empty_view.*
import org.mariotaku.sqliteqb.library.ArgsArray
import org.mariotaku.sqliteqb.library.Columns
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R
@ -27,46 +25,53 @@ import org.mariotaku.twidere.activity.SignInActivity
import org.mariotaku.twidere.adapter.AccountDetailsAdapter
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.extension.setActivated
import org.mariotaku.twidere.extension.setColor
import org.mariotaku.twidere.extension.setPosition
import org.mariotaku.twidere.loader.AccountDetailsLoader
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Inbox
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Outbox
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.TwidereCollectionUtils
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.collection.CompactHashSet
/**
* Created by mariotaku on 14/10/26.
*/
class AccountsManagerFragment : BaseSupportFragment(), OnSharedPreferenceChangeListener,
AdapterView.OnItemClickListener, AccountDetailsAdapter.OnAccountToggleListener {
class AccountsManagerFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<List<AccountDetails>>,
OnSharedPreferenceChangeListener, AdapterView.OnItemClickListener {
private var adapter: AccountDetailsAdapter? = null
private var selectedAccount: AccountDetails? = null
private val activatedState = SimpleArrayMap<UserKey, Boolean>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
val activity = activity
preferences.registerOnSharedPreferenceChangeListener(this)
adapter = AccountDetailsAdapter(activity)
Utils.configBaseAdapter(activity, adapter)
adapter!!.setSortEnabled(true)
adapter!!.setSwitchEnabled(true)
adapter!!.setOnAccountToggleListener(this)
adapter = AccountDetailsAdapter(activity).apply {
Utils.configBaseAdapter(activity, this)
setSortEnabled(true)
setSwitchEnabled(true)
accountToggleListener = { pos, checked ->
getItem(pos).activated = checked
}
}
listView.adapter = adapter
listView.isDragEnabled = true
listView.onItemClickListener = this
listView.setDropListener { from, to ->
adapter?.drop(from, to)
// TODO sort list
}
listView.setOnCreateContextMenuListener(this)
listView.emptyView = emptyView
emptyText.setText(R.string.no_account)
emptyIcon.setImageResource(R.drawable.ic_info_error_generic)
setListShown(false)
loaderManager.initLoader(0, null, this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -130,32 +135,38 @@ class AccountsManagerFragment : BaseSupportFragment(), OnSharedPreferenceChangeL
override fun onStop() {
super.onStop()
saveActivatedState()
saveAccountPositions()
}
override fun onDestroyView() {
preferences.unregisterOnSharedPreferenceChangeListener(this)
super.onDestroyView()
}
override fun onCreateLoader(id: Int, args: Bundle?): Loader<List<AccountDetails>> {
return AccountDetailsLoader(context)
}
override fun onLoaderReset(loader: Loader<List<AccountDetails>>) {
}
override fun onLoadFinished(loader: Loader<List<AccountDetails>>, data: List<AccountDetails>) {
adapter?.apply {
clear()
addAll(data)
}
setListShown(true)
}
private fun saveActivatedState() {
val trueIds = CompactHashSet<UserKey>()
val falseIds = CompactHashSet<UserKey>()
for (i in 0 until activatedState.size()) {
if (activatedState.valueAt(i)) {
trueIds.add(activatedState.keyAt(i))
} else {
falseIds.add(activatedState.keyAt(i))
val am = AccountManager.get(context)
adapter?.let { adapter ->
for (i in 0 until adapter.count) {
val item = adapter.getItem(i)
item.account.setActivated(am, item.activated)
}
}
val cr = contentResolver
val values = ContentValues()
values.put(Accounts.IS_ACTIVATED, true)
var where = Expression.`in`(Columns.Column(Accounts.ACCOUNT_KEY), ArgsArray(trueIds.size))
var whereArgs = TwidereCollectionUtils.toStringArray(trueIds)
cr.update(Accounts.CONTENT_URI, values, where.sql, whereArgs)
values.put(Accounts.IS_ACTIVATED, false)
where = Expression.`in`(Columns.Column(Accounts.ACCOUNT_KEY), ArgsArray(falseIds.size))
whereArgs = TwidereCollectionUtils.toStringArray(falseIds)
cr.update(Accounts.CONTENT_URI, values, where.sql, whereArgs)
}
override fun onAccountToggle(accountId: UserKey, state: Boolean) {
activatedState.put(accountId, state)
}
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo) {
@ -166,11 +177,6 @@ class AccountsManagerFragment : BaseSupportFragment(), OnSharedPreferenceChangeL
inflater.inflate(R.menu.action_manager_account, menu)
}
override fun onDestroyView() {
preferences.unregisterOnSharedPreferenceChangeListener(this)
super.onDestroyView()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.layout_draggable_list_with_empty_view, container, false)
}
@ -181,7 +187,12 @@ class AccountsManagerFragment : BaseSupportFragment(), OnSharedPreferenceChangeL
}
private fun saveAccountPositions() {
val am = AccountManager.get(context)
adapter?.let { adapter ->
for (i in 0 until adapter.count) {
adapter.getItem(i).account.setPosition(am, i)
}
}
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {

View File

@ -0,0 +1,31 @@
package org.mariotaku.twidere.loader
import android.accounts.AccountManager
import android.content.Context
import android.support.v4.content.AsyncTaskLoader
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.util.AccountUtils
/**
* Created by mariotaku on 2016/12/4.
*/
class AccountDetailsLoader(
context: Context,
val filter: (AccountDetails.() -> Boolean)? = null
) : AsyncTaskLoader<List<AccountDetails>>(context) {
private val am: AccountManager
init {
am = AccountManager.get(context)
}
override fun loadInBackground(): List<AccountDetails> {
return AccountUtils.getAllAccountDetails(am).filter {
filter?.invoke(it) ?: true
}.sortedBy(AccountDetails::position)
}
override fun onStartLoading() {
forceLoad()
}
}