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

247 lines
9.7 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.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
2020-01-26 08:35:15 +01:00
import androidx.loader.app.LoaderManager
import androidx.loader.content.Loader
import androidx.appcompat.app.AlertDialog
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
2017-04-17 15:10:14 +02:00
import org.mariotaku.kpreferences.get
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-12-09 03:02:41 +01:00
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
2017-04-17 15:10:14 +02:00
import org.mariotaku.twidere.constant.newDocumentApiKey
2017-02-05 14:42:20 +01:00
import org.mariotaku.twidere.extension.applyTheme
2016-12-29 06:50:18 +01:00
import org.mariotaku.twidere.extension.model.getAccountKey
import org.mariotaku.twidere.extension.model.setActivated
import org.mariotaku.twidere.extension.model.setColor
import org.mariotaku.twidere.extension.model.setPosition
2017-06-19 15:45:41 +02:00
import org.mariotaku.twidere.extension.onShow
2016-12-05 01:52:02 +01:00
import org.mariotaku.twidere.loader.AccountDetailsLoader
2016-12-03 16:45:13 +01:00
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.AccountPreferences
2016-12-09 03:02:41 +01:00
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
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.deleteAccountData
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.
*/
2017-01-12 17:26:44 +01:00
class AccountsManagerFragment : BaseFragment(), 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(requireContext(), requestManager).apply {
sortEnabled = true
switchEnabled = true
2016-12-05 01:52:02 +01:00
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
2017-01-26 14:28:43 +01:00
emptyText.setText(R.string.message_toast_no_account)
2016-07-08 09:52:32 +02:00
emptyIcon.setImageResource(R.drawable.ic_info_error_generic)
setListShown(false)
2016-12-05 01:52:02 +01:00
LoaderManager.getInstance(this).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)
val accountKey: UserKey = data.getBundleExtra(EXTRA_EXTRAS)?.getParcelable(EXTRA_ACCOUNT_KEY) ?: return
2016-12-09 03:02:41 +01:00
val color = data.getIntExtra(EXTRA_COLOR, Color.WHITE)
val details = adapter.findItem(accountKey) ?: return
details.color = color
details.account.setColor(am, color)
2020-01-26 08:35:15 +01:00
val resolver = context?.contentResolver
2016-12-15 07:47:06 +01:00
task {
2020-01-26 08:35:15 +01:00
resolver?.let { updateContentsColor(it, details) }
2016-12-15 07:47:06 +01:00
}
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)
2020-01-26 08:35:15 +01:00
context?.let {
IntentUtils.openUserProfile(it, account.user, preferences[newDocumentApiKey],
2017-08-28 06:31:19 +02:00
null)
2020-01-26 08:35:15 +01:00
}
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(requireContext())
2016-12-05 01:52:02 +01:00
}
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
}
2020-01-26 08:35:15 +01:00
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo?) {
2016-07-08 09:52:32 +02:00
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 statusesWhere = Expression.equalsArgs(Statuses.ACCOUNT_KEY)
val statusesWhereArgs = arrayOf(details.key.toString())
2017-04-29 18:34:26 +02:00
DataStoreUtils.STATUSES_ACTIVITIES_URIS.forEach { uri ->
2016-12-15 07:47:06 +01:00
resolver.update(uri, statusValues, statusesWhere.sql, statusesWhereArgs)
}
}
/**
* DELETE YOUR ACCOUNT
*/
2016-07-08 09:52:32 +02:00
class AccountDeletionDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, which: Int) {
2020-01-26 08:35:15 +01:00
val account: Account = arguments?.getParcelable(EXTRA_ACCOUNT)!!
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)
2020-01-26 08:35:15 +01:00
resolver?.deleteAccountData(accountKey)
context?.let {
AccountPreferences.getSharedPreferencesForAccount(it, accountKey).edit()
.clear().apply()
}
am.removeAccountSupport(account)
2016-07-08 09:52:32 +02:00
}
}
}
2016-07-08 09:52:32 +02:00
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val context = context
val builder = AlertDialog.Builder(requireContext())
2016-07-08 09:52:32 +02:00
builder.setNegativeButton(android.R.string.cancel, null)
builder.setPositiveButton(android.R.string.ok, this)
2017-03-29 08:40:32 +02:00
builder.setTitle(R.string.title_account_delete_confirm)
builder.setMessage(R.string.message_account_delete_confirm)
2017-02-05 14:42:20 +01:00
val dialog = builder.create()
2017-06-19 15:45:41 +02:00
dialog.onShow { it.applyTheme() }
2017-02-05 14:42:20 +01:00
return dialog
2016-07-08 09:52:32 +02:00
}
}
companion object {
2020-06-08 23:11:06 +02:00
private const val FRAGMENT_TAG_ACCOUNT_DELETION = "account_deletion"
2016-07-08 09:52:32 +02:00
}
}