Twidere-App-Android-Twitter.../twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AccountsManagerFragment.kt

250 lines
10 KiB
Kotlin
Raw Normal View History

2016-07-08 09:52:32 +02:00
package org.mariotaku.twidere.fragment
import android.accounts.Account
2016-12-03 16:45:13 +01:00
import android.accounts.AccountManager
2016-07-08 09:52:32 +02:00
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
2016-12-15 07:47:06 +01:00
import android.content.ContentResolver
import android.content.ContentValues
2016-07-08 09:52:32 +02:00
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
2016-12-05 01:52:02 +01:00
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
2016-07-08 09:52:32 +02:00
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.*
2016-12-15 07:47:06 +01:00
import nl.komponents.kovenant.task
2016-12-09 03:02:41 +01:00
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set
2016-07-08 09:52:32 +02:00
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R
2016-12-15 02:33:47 +01:00
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_AUTH_TOKEN_TYPE
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
2016-12-03 16:45:13 +01:00
import org.mariotaku.twidere.adapter.AccountDetailsAdapter
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.annotation.Referral
2016-12-09 03:02:41 +01:00
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NEW_DOCUMENT_API
import org.mariotaku.twidere.extension.getAccountKey
2016-12-05 01:52:02 +01:00
import org.mariotaku.twidere.extension.setActivated
2016-12-03 16:45:13 +01:00
import org.mariotaku.twidere.extension.setColor
2016-12-05 01:52:02 +01:00
import org.mariotaku.twidere.extension.setPosition
import org.mariotaku.twidere.loader.AccountDetailsLoader
2016-12-03 16:45:13 +01:00
import org.mariotaku.twidere.model.AccountDetails
2016-12-09 03:02:41 +01:00
import org.mariotaku.twidere.model.UserKey
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.provider.TwidereDataStore.*
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Inbox
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.Outbox
2016-12-15 07:47:06 +01:00
import org.mariotaku.twidere.util.DataStoreUtils
2016-07-08 09:52:32 +02:00
import org.mariotaku.twidere.util.IntentUtils
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.support.removeAccountSupport
2016-07-08 09:52:32 +02:00
/**
2016-12-05 03:00:48 +01:00
* Sort and toggle account availability
2016-07-08 09:52:32 +02:00
* Created by mariotaku on 14/10/26.
*/
2016-12-05 01:52:02 +01:00
class AccountsManagerFragment : BaseSupportFragment(), LoaderManager.LoaderCallbacks<List<AccountDetails>>,
2016-12-05 03:00:48 +01:00
AdapterView.OnItemClickListener {
2016-07-08 09:52:32 +02:00
private lateinit var adapter: AccountDetailsAdapter
2016-07-08 09:52:32 +02:00
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
val am = AccountManager.get(context)
adapter = AccountDetailsAdapter(context).apply {
Utils.configBaseAdapter(context, this)
2016-12-05 01:52:02 +01:00
setSortEnabled(true)
setSwitchEnabled(true)
accountToggleListener = { pos, checked ->
val item = getItem(pos)
item.activated = checked
item.account.setActivated(am, checked)
2016-12-05 01:52:02 +01:00
}
}
2016-07-08 09:52:32 +02:00
listView.adapter = adapter
listView.isDragEnabled = true
listView.onItemClickListener = this
2016-12-05 01:52:02 +01:00
listView.setDropListener { from, to ->
adapter.drop(from, to)
for (i in 0 until adapter.count) {
val item = adapter.getItem(i)
item.account.setActivated(am, item.activated)
item.account.setPosition(am, i)
}
2016-12-05 01:52:02 +01:00
}
2016-07-08 09:52:32 +02:00
listView.setOnCreateContextMenuListener(this)
listView.emptyView = emptyView
emptyText.setText(R.string.no_account)
emptyIcon.setImageResource(R.drawable.ic_info_error_generic)
setListShown(false)
2016-12-05 01:52:02 +01:00
loaderManager.initLoader(0, null, this)
2016-07-08 09:52:32 +02:00
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_SET_COLOR -> {
2016-12-09 03:02:41 +01:00
if (resultCode != Activity.RESULT_OK || data == null)
2016-07-08 09:52:32 +02:00
return
2016-12-03 16:45:13 +01:00
val am = AccountManager.get(context)
2016-12-09 03:02:41 +01:00
val accountKey: UserKey = data.getBundleExtra(EXTRA_EXTRAS).getParcelable(EXTRA_ACCOUNT_KEY) ?: return
val color = data.getIntExtra(EXTRA_COLOR, Color.WHITE)
val details = adapter.findItem(accountKey) ?: return
details.color = color
details.account.setColor(am, color)
2016-12-15 07:47:06 +01:00
val resolver = context.contentResolver
task {
updateContentsColor(resolver, details)
}
2016-12-09 03:02:41 +01:00
adapter.notifyDataSetChanged()
2016-07-08 09:52:32 +02:00
return
}
}
super.onActivityResult(requestCode, resultCode, data)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.add_account -> {
2016-12-15 02:33:47 +01:00
AccountManager.get(context).addAccount(ACCOUNT_TYPE, ACCOUNT_AUTH_TOKEN_TYPE,
null, null, activity, null, null)
2016-07-08 09:52:32 +02:00
}
}
return super.onOptionsItemSelected(item)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_accounts_manager, menu)
}
2016-12-15 02:33:47 +01:00
override fun onContextItemSelected(item: MenuItem): Boolean {
val menuInfo = item.menuInfo as? AdapterContextMenuInfo ?: return false
val details = adapter.getItem(menuInfo.position) ?: return false
2016-07-08 09:52:32 +02:00
when (item.itemId) {
R.id.set_color -> {
val intent = Intent(activity, ColorPickerDialogActivity::class.java)
2016-12-03 16:45:13 +01:00
intent.putExtra(EXTRA_COLOR, details.color)
2016-12-09 03:02:41 +01:00
intent.putExtra(EXTRA_EXTRAS, Bundle {
this[EXTRA_ACCOUNT_KEY] = details.key
})
2016-07-08 09:52:32 +02:00
intent.putExtra(EXTRA_ALPHA_SLIDER, false)
startActivityForResult(intent, REQUEST_SET_COLOR)
}
R.id.delete -> {
val f = AccountDeletionDialogFragment()
val args = Bundle()
2016-12-03 16:45:13 +01:00
args.putParcelable(EXTRA_ACCOUNT, details.account)
2016-07-08 09:52:32 +02:00
f.arguments = args
f.show(childFragmentManager, FRAGMENT_TAG_ACCOUNT_DELETION)
}
}
return false
}
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val account = adapter.getItem(position)
IntentUtils.openUserProfile(context, account.user, null, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
2016-12-03 16:45:13 +01:00
Referral.SELF_PROFILE)
2016-07-08 09:52:32 +02:00
}
2016-12-05 01:52:02 +01:00
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 {
2016-12-05 01:52:02 +01:00
clear()
addAll(data)
2016-07-08 09:52:32 +02:00
}
2016-12-05 01:52:02 +01:00
setListShown(true)
2016-07-08 09:52:32 +02:00
}
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo) {
if (menuInfo !is AdapterContextMenuInfo) return
val account = adapter.getItem(menuInfo.position)!!
menu.setHeaderTitle(account.user.name)
2016-07-08 09:52:32 +02:00
val inflater = MenuInflater(v.context)
inflater.inflate(R.menu.action_manager_account, menu)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.layout_draggable_list_with_empty_view, container, false)
}
private fun setListShown(shown: Boolean) {
listContainer.visibility = if (shown) View.VISIBLE else View.GONE
progressContainer.visibility = if (shown) View.GONE else View.VISIBLE
}
2016-12-15 07:47:06 +01:00
private fun updateContentsColor(resolver: ContentResolver, details: AccountDetails) {
val statusValues = ContentValues().apply {
put(Statuses.ACCOUNT_COLOR, details.color)
}
val activityValues = ContentValues().apply {
put(Activities.ACCOUNT_COLOR, details.color)
}
val statusesWhere = Expression.equalsArgs(Statuses.ACCOUNT_KEY)
val statusesWhereArgs = arrayOf(details.key.toString())
val activitiesWhere = Expression.equalsArgs(Activities.ACCOUNT_KEY)
val activitiesWhereArgs = arrayOf(details.key.toString())
DataStoreUtils.STATUSES_URIS.forEach { uri ->
resolver.update(uri, statusValues, statusesWhere.sql, statusesWhereArgs)
}
DataStoreUtils.ACTIVITIES_URIS.forEach { uri ->
resolver.update(uri, activityValues, activitiesWhere.sql, activitiesWhereArgs)
}
}
2016-07-08 09:52:32 +02:00
class AccountDeletionDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, which: Int) {
2016-12-09 03:02:41 +01:00
val account: Account = arguments.getParcelable(EXTRA_ACCOUNT)
2016-11-30 08:18:43 +01:00
val resolver = context.contentResolver
val am = AccountManager.get(context)
2016-07-08 09:52:32 +02:00
when (which) {
DialogInterface.BUTTON_POSITIVE -> {
val accountKey = account.getAccountKey(am)
am.removeAccountSupport(account)
val where = Expression.equalsArgs(AccountSupportColumns.ACCOUNT_KEY).sql
val whereArgs = arrayOf(accountKey.toString())
2016-07-08 09:52:32 +02:00
// Also delete tweets related to the account we previously
// deleted.
resolver.delete(Statuses.CONTENT_URI, where, whereArgs)
resolver.delete(Mentions.CONTENT_URI, where, whereArgs)
resolver.delete(Inbox.CONTENT_URI, where, whereArgs)
resolver.delete(Outbox.CONTENT_URI, where, whereArgs)
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val context = context
val builder = AlertDialog.Builder(context)
builder.setNegativeButton(android.R.string.cancel, null)
builder.setPositiveButton(android.R.string.ok, this)
builder.setTitle(R.string.account_delete_confirm_title)
builder.setMessage(R.string.account_delete_confirm_message)
return builder.create()
}
}
companion object {
private val FRAGMENT_TAG_ACCOUNT_DELETION = "account_deletion"
}
}