implemented twitter retweet/favorite intent handling

This commit is contained in:
Mariotaku Lee 2017-04-12 19:25:10 +08:00
parent f1bafacfd4
commit fbaf4dd0da
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
11 changed files with 415 additions and 247 deletions

View File

@ -1 +1 @@
e996a88227d4a77ebe6739b7286d744f2023e398
ea793d047ce90d44b4d0d8b67cb69c0b99ca173e

View File

@ -8,6 +8,8 @@ import android.text.TextUtils
import org.mariotaku.ktextension.toLongOr
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.content.FavoriteConfirmDialogActivity
import org.mariotaku.twidere.activity.content.RetweetQuoteDialogActivity
import org.mariotaku.twidere.app.TwidereApplication
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.Analyzer
@ -276,14 +278,27 @@ class WebLinkHandlerActivity : Activity() {
handledIntent.putExtra(Intent.EXTRA_TEXT, sb.toString())
return Pair(handledIntent, true)
}
"favorite", "retweet" -> {
"retweet" -> {
val tweetId = uri.getQueryParameter("tweet_id") ?: return Pair(null, false)
return Pair(IntentUtils.status(null, tweetId), true)
val accountHost = USER_TYPE_TWITTER_COM
val intent = Intent(this, RetweetQuoteDialogActivity::class.java)
intent.putExtra(EXTRA_STATUS_ID, tweetId)
intent.putExtra(EXTRA_ACCOUNT_HOST, accountHost)
return Pair(intent, true)
}
"favorite", "like" -> {
val tweetId = uri.getQueryParameter("tweet_id") ?: return Pair(null, false)
val accountHost = USER_TYPE_TWITTER_COM
val intent = Intent(this, FavoriteConfirmDialogActivity::class.java)
intent.putExtra(EXTRA_STATUS_ID, tweetId)
intent.putExtra(EXTRA_ACCOUNT_HOST, accountHost)
return Pair(intent, true)
}
"user", "follow" -> {
val userKey = uri.getQueryParameter("user_id")?.let { UserKey(it, "twitter.com") }
val screenName = uri.getQueryParameter("screen_name")
return Pair(IntentUtils.userProfile(null, userKey, screenName), true)
return Pair(IntentUtils.userProfile(null, userKey, screenName,
accountHost = USER_TYPE_TWITTER_COM), true)
}
}
return Pair(null, false)

View File

@ -0,0 +1,76 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.activity.content
import android.content.Intent
import android.os.Bundle
import org.mariotaku.twidere.TwidereConstants.REQUEST_SELECT_ACCOUNT
import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
abstract class AbsStatusDialogActivity : BaseActivity() {
private val statusId: String
get() = intent.getStringExtra(EXTRA_STATUS_ID)
private val accountKey: UserKey?
get() = intent.getParcelableExtra(EXTRA_ACCOUNT_KEY)
private val accountHost: String?
get() = intent.getStringExtra(EXTRA_ACCOUNT_HOST)
private val status: ParcelableStatus?
get() = intent.getParcelableExtra(EXTRA_STATUS)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
val accountKey = this.accountKey
if (accountKey != null) {
showDialogFragment(accountKey, statusId, status)
} else {
val intent = Intent(this, AccountSelectorActivity::class.java)
intent.putExtra(EXTRA_SINGLE_SELECTION, true)
intent.putExtra(EXTRA_SELECT_ONLY_ITEM_AUTOMATICALLY, true)
intent.putExtra(EXTRA_ACCOUNT_HOST, accountHost)
startActivityForResult(intent, REQUEST_SELECT_ACCOUNT)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQUEST_SELECT_ACCOUNT -> {
if (resultCode == RESULT_OK && data != null) {
val accountKey = data.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
showDialogFragment(accountKey, statusId, status)
return
}
}
}
finish()
}
protected abstract fun showDialogFragment(accountKey: UserKey, statusId: String,
status: ParcelableStatus?)
}

View File

@ -19,9 +19,6 @@
package org.mariotaku.twidere.activity.content
import android.os.Bundle
import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.fragment.content.FavoriteConfirmDialogFragment
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
@ -31,21 +28,12 @@ import org.mariotaku.twidere.model.UserKey
*
* Created by mariotaku on 2017/4/12.
*/
class FavoriteConfirmDialogActivity : BaseActivity() {
class FavoriteConfirmDialogActivity : AbsStatusDialogActivity() {
private val status: ParcelableStatus
get() = intent.getParcelableExtra(EXTRA_STATUS)
private val statusId: String
get() = intent.getStringExtra(EXTRA_STATUS_ID)
private val accountKey: UserKey?
get() = intent.getParcelableExtra(EXTRA_ACCOUNT_KEY)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
FavoriteConfirmDialogFragment.show(supportFragmentManager, accountKey, statusId, status)
override fun showDialogFragment(accountKey: UserKey, statusId: String, status: ParcelableStatus?) {
executeAfterFragmentResumed {
FavoriteConfirmDialogFragment.show(it.supportFragmentManager, accountKey, statusId, status)
}
}
}

View File

@ -19,9 +19,7 @@
package org.mariotaku.twidere.activity.content
import android.os.Bundle
import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_TEXT
import org.mariotaku.twidere.fragment.content.RetweetQuoteDialogFragment
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
@ -31,25 +29,17 @@ import org.mariotaku.twidere.model.UserKey
*
* Created by mariotaku on 2017/4/8.
*/
class RetweetQuoteDialogActivity : BaseActivity() {
private val status: ParcelableStatus
get() = intent.getParcelableExtra(EXTRA_STATUS)
private val statusId: String
get() = intent.getStringExtra(EXTRA_STATUS_ID)
private val accountKey: UserKey?
get() = intent.getParcelableExtra(EXTRA_ACCOUNT_KEY)
class RetweetQuoteDialogActivity : AbsStatusDialogActivity() {
private val text: String?
get() = intent.getStringExtra(EXTRA_TEXT)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
RetweetQuoteDialogFragment.show(supportFragmentManager, accountKey, statusId, status,
text)
override fun showDialogFragment(accountKey: UserKey, statusId: String, status: ParcelableStatus?) {
val text = this.text
executeAfterFragmentResumed {
RetweetQuoteDialogFragment.show(it.supportFragmentManager, accountKey, statusId,
status, text)
}
}
}

View File

@ -0,0 +1,145 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.fragment.content
import android.accounts.AccountManager
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.support.v7.app.AlertDialog
import android.view.View
import android.widget.Toast
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.list_item_status.view.*
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.combine.and
import nl.komponents.kovenant.task
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.promiseOnUi
import nl.komponents.kovenant.ui.successUi
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.DummyItemAdapter
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.view.holder.StatusViewHolder
import java.lang.ref.WeakReference
abstract class AbsStatusDialogFragment : BaseDialogFragment() {
protected abstract val Dialog.loadProgress: View
protected abstract val Dialog.itemContent: View
protected val status: ParcelableStatus?
get() = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS)
protected val statusId: String
get() = arguments.getString(EXTRA_STATUS_ID)
protected val accountKey: UserKey
get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY)
override final fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context)
val accountKey = this.accountKey
builder.setupAlertDialog()
val dialog = builder.create()
dialog.setOnShowListener { dialog ->
dialog as AlertDialog
dialog.applyTheme()
val am = AccountManager.get(context)
val details = AccountUtils.getAccountDetails(am, accountKey, true) ?: run {
dismiss()
return@setOnShowListener
}
val weakThis = WeakReference(this)
promiseOnUi {
val currentDialog = weakThis.get()?.dialog as? AlertDialog ?: return@promiseOnUi
currentDialog.loadProgress.visibility = View.VISIBLE
currentDialog.itemContent.visibility = View.GONE
currentDialog.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = false
currentDialog.getButton(DialogInterface.BUTTON_NEUTRAL)?.isEnabled = false
} and showStatus(context, details, statusId, status).successUi { status ->
val fragment = weakThis.get() ?: return@successUi
val currentDialog = fragment.dialog as? AlertDialog ?: return@successUi
currentDialog.getButton(DialogInterface.BUTTON_POSITIVE)?.isEnabled = true
currentDialog.getButton(DialogInterface.BUTTON_NEUTRAL)?.isEnabled = true
currentDialog.itemContent.visibility = View.VISIBLE
currentDialog.loadProgress.visibility = View.GONE
currentDialog.itemContent.isFocusable = false
currentDialog.itemContent.itemMenu.visibility = View.GONE
currentDialog.itemContent.actionButtons.visibility = View.GONE
val adapter = DummyItemAdapter(fragment.context, requestManager = Glide.with(fragment))
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, currentDialog.itemContent)
holder.displayStatus(status = status, displayInReplyTo = false)
currentDialog.onStatusLoaded(details, status, savedInstanceState)
}.failUi {
val fragment = weakThis.get()?.takeIf { it.dialog != null } ?: return@failUi
Toast.makeText(fragment.context, R.string.message_toast_error_occurred, Toast.LENGTH_SHORT).show()
fragment.dismiss()
}
}
return dialog
}
protected abstract fun AlertDialog.Builder.setupAlertDialog()
protected abstract fun AlertDialog.onStatusLoaded(details: AccountDetails, status: ParcelableStatus,
savedInstanceState: Bundle?)
companion object {
fun showStatus(context: Context, details: AccountDetails, statusId: String,
status: ParcelableStatus?): Promise<ParcelableStatus, Exception> {
if (status != null) {
status.apply {
if (account_key != details.key) {
my_retweet_id = null
is_favorite = false
}
account_key = details.key
account_color = details.color
}
return Promise.ofSuccess(status)
}
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
val profileImageSize = context.getString(R.string.profile_image_size)
return task {
val status = ParcelableStatusUtils.fromStatus(microBlog.showStatus(statusId),
details.key, details.type, profileImageSize = profileImageSize)
status.account_color = details.color
return@task status
}
}
}
}

View File

@ -19,111 +19,66 @@
package org.mariotaku.twidere.fragment.content
import android.accounts.AccountManager
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.support.v4.app.FragmentManager
import android.support.v7.app.AlertDialog
import android.view.View
import android.widget.ImageButton
import android.widget.LinearLayout
import com.bumptech.glide.Glide
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.Bundle
import org.mariotaku.ktextension.set
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.content.RetweetQuoteDialogActivity
import org.mariotaku.twidere.adapter.DummyItemAdapter
import org.mariotaku.twidere.activity.content.FavoriteConfirmDialogActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.iWantMyStarsBackKey
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.view.ColorLabelRelativeLayout
import org.mariotaku.twidere.view.holder.StatusViewHolder
/**
* Asks user to favorite a status.
*
* Created by mariotaku on 2017/4/12.
*/
class FavoriteConfirmDialogFragment : BaseDialogFragment() {
class FavoriteConfirmDialogFragment : AbsStatusDialogFragment() {
private val Dialog.loadProgress get() = findViewById(R.id.loadProgress)
private val Dialog.itemContent get() = findViewById(R.id.itemContent) as ColorLabelRelativeLayout
private val Dialog.itemMenu get() = findViewById(R.id.itemMenu) as ImageButton
private val Dialog.actionButtons get() = findViewById(R.id.actionButtons) as LinearLayout
override val Dialog.loadProgress: View get() = findViewById(R.id.loadProgress)
private val status: ParcelableStatus
get() = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS)
override val Dialog.itemContent: View get() = findViewById(R.id.itemContent)
private val accountKey: UserKey
get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) ?: status.account_key
override fun AlertDialog.Builder.setupAlertDialog() {
setTitle(R.string.title_favorite_confirm)
setView(R.layout.dialog_status_favorite_confirm)
setPositiveButton(R.string.action_favorite, null)
setNegativeButton(android.R.string.cancel, null)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context)
val accountKey = this.accountKey
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)!!
val status = this.status.apply {
if (account_key != accountKey) {
is_favorite = false
}
account_key = details.key
account_color = details.color
}
builder.setView(R.layout.dialog_status_favorite_confirm)
builder.setTitle(R.string.title_favorite_confirm)
override fun AlertDialog.onStatusLoaded(details: AccountDetails, status: ParcelableStatus,
savedInstanceState: Bundle?) {
val positiveButton = getButton(DialogInterface.BUTTON_POSITIVE)
if (preferences[iWantMyStarsBackKey]) {
builder.setPositiveButton(R.string.action_favorite, null)
} else {
builder.setPositiveButton(R.string.action_like, null)
}
builder.setNegativeButton(android.R.string.cancel, null)
val dialog = builder.create()
dialog.setOnShowListener { dialog ->
dialog as AlertDialog
dialog.applyTheme()
val adapter = DummyItemAdapter(context, requestManager = Glide.with(this))
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, dialog.itemContent)
holder.displayStatus(status = status, displayInReplyTo = false)
dialog.loadProgress.visibility = View.GONE
dialog.itemMenu.visibility = View.GONE
dialog.actionButtons.visibility = View.GONE
dialog.itemContent.isFocusable = false
val positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE)
if (preferences[iWantMyStarsBackKey]) {
if (status.is_favorite) {
positiveButton.setText(R.string.action_unfavorite)
} else {
positiveButton.setText(R.string.action_favorite)
}
if (status.is_favorite) {
positiveButton.setText(R.string.action_unfavorite)
} else {
if (status.is_favorite) {
positiveButton.setText(R.string.action_undo_like)
} else {
positiveButton.setText(R.string.action_like)
}
positiveButton.setText(R.string.action_favorite)
}
positiveButton.setOnClickListener {
if (status.is_favorite) {
twitterWrapper.destroyFavoriteAsync(accountKey, status.id)
} else {
twitterWrapper.createFavoriteAsync(accountKey, status)
}
dismiss()
} else {
if (status.is_favorite) {
positiveButton.setText(R.string.action_undo_like)
} else {
positiveButton.setText(R.string.action_like)
}
}
return dialog
positiveButton.setOnClickListener {
if (status.is_favorite) {
twitterWrapper.destroyFavoriteAsync(accountKey, status.id)
} else {
twitterWrapper.createFavoriteAsync(accountKey, status)
}
dismiss()
}
}
override fun onCancel(dialog: DialogInterface) {
@ -137,7 +92,7 @@ class FavoriteConfirmDialogFragment : BaseDialogFragment() {
private fun finishFavoriteConfirmActivity() {
val activity = this.activity
if (activity is RetweetQuoteDialogActivity && !activity.isFinishing) {
if (activity is FavoriteConfirmDialogActivity && !activity.isFinishing) {
activity.finish()
}
}
@ -146,8 +101,8 @@ class FavoriteConfirmDialogFragment : BaseDialogFragment() {
val FRAGMENT_TAG = "favorite_confirm"
fun show(fm: FragmentManager, accountKey: UserKey? = null, statusId: String,
status: ParcelableStatus?): FavoriteConfirmDialogFragment {
fun show(fm: FragmentManager, accountKey: UserKey, statusId: String,
status: ParcelableStatus? = null): FavoriteConfirmDialogFragment {
val f = FavoriteConfirmDialogFragment()
f.arguments = Bundle {
this[EXTRA_ACCOUNT_KEY] = accountKey

View File

@ -19,8 +19,8 @@
package org.mariotaku.twidere.fragment.content
import android.accounts.AccountManager
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
@ -30,15 +30,19 @@ import android.support.annotation.CheckResult
import android.support.v4.app.FragmentManager
import android.support.v7.app.AlertDialog
import android.support.v7.widget.PopupMenu
import android.text.Editable
import android.text.TextWatcher
import android.view.Gravity
import android.view.View
import android.widget.*
import android.widget.EditText
import android.widget.ImageButton
import android.widget.RelativeLayout
import android.widget.Toast
import com.bumptech.glide.Glide
import com.twitter.Validator
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.task
import org.mariotaku.ktextension.*
import org.mariotaku.library.objectcursor.ObjectCursor
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.twidere.R
import org.mariotaku.twidere.activity.content.RetweetQuoteDialogActivity
import org.mariotaku.twidere.adapter.DummyItemAdapter
@ -46,18 +50,19 @@ import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_QUICK_SEND
import org.mariotaku.twidere.extension.applyTheme
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.model.textLimit
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.draft.QuoteStatusActionExtras
import org.mariotaku.twidere.model.util.AccountUtils
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.service.LengthyOperationsService
import org.mariotaku.twidere.util.Analyzer
import org.mariotaku.twidere.util.EditTextEnterHandler
import org.mariotaku.twidere.util.LinkCreator
import org.mariotaku.twidere.util.Utils.isMyRetweet
import org.mariotaku.twidere.view.ColorLabelRelativeLayout
import org.mariotaku.twidere.util.view.SimpleTextWatcher
import org.mariotaku.twidere.view.ComposeEditText
import org.mariotaku.twidere.view.StatusTextCountView
import org.mariotaku.twidere.view.holder.StatusViewHolder
@ -66,46 +71,100 @@ import java.util.*
/**
* Asks user to retweet/quote a status.
*/
class RetweetQuoteDialogFragment : BaseDialogFragment() {
class RetweetQuoteDialogFragment : AbsStatusDialogFragment() {
override val Dialog.loadProgress: View get() = findViewById(R.id.loadProgress)
override val Dialog.itemContent: View get() = findViewById(R.id.itemContent)
private lateinit var popupMenu: PopupMenu
private val PopupMenu.quoteOriginalStatus get() = menu.isItemChecked(R.id.quote_original_status)
private val Dialog.loadProgress get() = findViewById(R.id.loadProgress)
private val Dialog.itemContent get() = findViewById(R.id.itemContent) as ColorLabelRelativeLayout
private val Dialog.textCountView get() = findViewById(R.id.commentTextCount) as StatusTextCountView
private val Dialog.itemMenu get() = findViewById(R.id.itemMenu) as ImageButton
private val Dialog.actionButtons get() = findViewById(R.id.actionButtons) as LinearLayout
private val Dialog.commentContainer get() = findViewById(R.id.commentContainer) as RelativeLayout
private val Dialog.editComment get() = findViewById(R.id.editComment) as ComposeEditText
private val Dialog.commentMenu get() = findViewById(R.id.commentMenu) as ImageButton
private val status: ParcelableStatus
get() = arguments.getParcelable<ParcelableStatus>(EXTRA_STATUS)
private val accountKey: UserKey
get() = arguments.getParcelable(EXTRA_ACCOUNT_KEY) ?: status.account_key
private val PopupMenu.quoteOriginalStatus get() = menu.isItemChecked(R.id.quote_original_status)
private val text: String?
get() = arguments.getString(EXTRA_TEXT)
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context)
val accountKey = this.accountKey
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true)!!
val status = this.status.apply {
if (account_key != accountKey) {
my_retweet_id = null
}
account_key = details.key
account_color = details.color
}
override fun AlertDialog.Builder.setupAlertDialog() {
setTitle(R.string.title_retweet_quote_confirm)
setView(R.layout.dialog_status_quote_retweet)
setPositiveButton(R.string.action_retweet, null)
setNegativeButton(android.R.string.cancel, null)
setNeutralButton(R.string.action_quote, null)
}
builder.setView(R.layout.dialog_status_quote_retweet)
builder.setTitle(R.string.title_retweet_quote_confirm)
builder.setPositiveButton(R.string.action_retweet, null)
builder.setNegativeButton(android.R.string.cancel, null)
builder.setNeutralButton(R.string.action_quote) { _, _ ->
override fun AlertDialog.onStatusLoaded(details: AccountDetails, status: ParcelableStatus,
savedInstanceState: Bundle?) {
val adapter = DummyItemAdapter(context, requestManager = Glide.with(this@RetweetQuoteDialogFragment))
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, itemContent)
holder.displayStatus(status = status, displayInReplyTo = false)
textCountView.maxLength = details.textLimit
val useQuote = useQuote(!status.user_is_protected, details)
commentContainer.visibility = if (useQuote) View.VISIBLE else View.GONE
editComment.accountKey = details.key
val enterHandler = EditTextEnterHandler.attach(editComment, object : EditTextEnterHandler.EnterListener {
override fun shouldCallListener(): Boolean {
return true
}
override fun onHitEnter(): Boolean {
if (retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)) {
dismiss()
return true
}
return false
}
}, preferences.getBoolean(KEY_QUICK_SEND))
enterHandler.addTextChangedListener(object : SimpleTextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
updateTextCount(getDialog(), s, status, details)
}
})
popupMenu = PopupMenu(context, commentMenu, Gravity.NO_GRAVITY,
R.attr.actionOverflowMenuStyle, 0).apply {
inflate(R.menu.menu_dialog_comment)
menu.setItemAvailability(R.id.quote_original_status, status.retweet_id != null || status.quoted_id != null)
setOnMenuItemClickListener(PopupMenu.OnMenuItemClickListener { item ->
if (item.isCheckable) {
item.isChecked = !item.isChecked
return@OnMenuItemClickListener true
}
false
})
}
commentMenu.setOnClickListener { popupMenu.show() }
commentMenu.setOnTouchListener(popupMenu.dragToOpenListener)
commentMenu.visibility = if (popupMenu.menu.hasVisibleItems()) View.VISIBLE else View.GONE
getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
var dismissDialog = false
if (editComment.length() > 0) {
dismissDialog = retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)
} else if (isMyRetweet(status)) {
twitterWrapper.cancelRetweetAsync(details.key, status.id, status.my_retweet_id)
dismissDialog = true
} else if (useQuote(!status.user_is_protected, details)) {
dismissDialog = retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)
} else {
Analyzer.logException(IllegalStateException(status.toString()))
}
if (dismissDialog) {
dismiss()
}
}
getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener {
val intent = Intent(INTENT_ACTION_QUOTE)
val menu = popupMenu.menu
val quoteOriginalStatus = menu.findItem(R.id.quote_original_status)
@ -114,96 +173,12 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
startActivity(intent)
}
val dialog = builder.create()
dialog.setOnShowListener { dialog ->
dialog as AlertDialog
dialog.applyTheme()
val adapter = DummyItemAdapter(context, requestManager = Glide.with(this))
adapter.setShouldShowAccountsColor(true)
val holder = StatusViewHolder(adapter, dialog.itemContent)
holder.displayStatus(status = status, displayInReplyTo = false)
dialog.textCountView.maxLength = details.textLimit
dialog.loadProgress.visibility = View.GONE
dialog.itemMenu.visibility = View.GONE
dialog.actionButtons.visibility = View.GONE
dialog.itemContent.isFocusable = false
val useQuote = useQuote(!status.user_is_protected, details)
dialog.commentContainer.visibility = if (useQuote) View.VISIBLE else View.GONE
dialog.editComment.accountKey = details.key
val sendByEnter = preferences.getBoolean(KEY_QUICK_SEND)
val enterHandler = EditTextEnterHandler.attach(dialog.editComment, object : EditTextEnterHandler.EnterListener {
override fun shouldCallListener(): Boolean {
return true
}
override fun onHitEnter(): Boolean {
if (retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)) {
dismiss()
return true
}
return false
}
}, sendByEnter)
enterHandler.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
updateTextCount(getDialog(), s, status, details)
}
override fun afterTextChanged(s: Editable) {
}
})
popupMenu = PopupMenu(context, dialog.commentMenu, Gravity.NO_GRAVITY,
R.attr.actionOverflowMenuStyle, 0).apply {
inflate(R.menu.menu_dialog_comment)
menu.setItemAvailability(R.id.quote_original_status, status.retweet_id != null || status.quoted_id != null)
setOnMenuItemClickListener(PopupMenu.OnMenuItemClickListener { item ->
if (item.isCheckable) {
item.isChecked = !item.isChecked
return@OnMenuItemClickListener true
}
false
})
}
dialog.commentMenu.setOnClickListener { popupMenu.show() }
dialog.commentMenu.setOnTouchListener(popupMenu.dragToOpenListener)
dialog.commentMenu.visibility = if (popupMenu.menu.hasVisibleItems()) View.VISIBLE else View.GONE
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
var dismissDialog = false
if (dialog.editComment.length() > 0) {
dismissDialog = retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)
} else if (isMyRetweet(status)) {
twitterWrapper.cancelRetweetAsync(details.key, status.id, status.my_retweet_id)
dismissDialog = true
} else if (useQuote(!status.user_is_protected, details)) {
dismissDialog = retweetOrQuote(details, status, SHOW_PROTECTED_CONFIRM)
} else {
Analyzer.logException(IllegalStateException(status.toString()))
}
if (dismissDialog) {
dismiss()
}
}
if (savedInstanceState == null) {
dialog.editComment.setText(text)
}
dialog.editComment.setSelection(dialog.editComment.length())
updateTextCount(dialog, dialog.editComment.text, status, details)
if (savedInstanceState == null) {
editComment.setText(text)
}
return dialog
editComment.setSelection(editComment.length())
updateTextCount(dialog, editComment.text, status, details)
}
override fun onCancel(dialog: DialogInterface) {
@ -311,7 +286,6 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
return preCondition || AccountType.FANFOU == account.type
}
private fun Dialog.saveToDrafts() {
val text = dialog.editComment.text.toString()
val draft = Draft()
@ -391,8 +365,9 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
val FRAGMENT_TAG = "retweet_quote"
private val SHOW_PROTECTED_CONFIRM = java.lang.Boolean.parseBoolean("false")
fun show(fm: FragmentManager, accountKey: UserKey? = null, statusId: String,
status: ParcelableStatus?, text: String? = null): RetweetQuoteDialogFragment {
fun show(fm: FragmentManager, accountKey: UserKey, statusId: String,
status: ParcelableStatus? = null, text: String? = null):
RetweetQuoteDialogFragment {
val f = RetweetQuoteDialogFragment()
f.arguments = Bundle {
this[EXTRA_ACCOUNT_KEY] = accountKey
@ -403,5 +378,26 @@ class RetweetQuoteDialogFragment : BaseDialogFragment() {
f.show(fm, FRAGMENT_TAG)
return f
}
fun showStatus(context: Context, details: AccountDetails, statusId: String,
status: ParcelableStatus?): Promise<ParcelableStatus, Exception> {
if (status != null) {
status.apply {
if (account_key != details.key) {
my_retweet_id = null
}
account_key = details.key
account_color = details.color
}
return Promise.ofSuccess(status)
}
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
val profileImageSize = context.getString(R.string.profile_image_size)
return task {
ParcelableStatusUtils.fromStatus(microBlog.showStatus(statusId), details.key,
details.type, profileImageSize = profileImageSize)
}
}
}
}

View File

@ -17,6 +17,7 @@ import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.MediaViewerActivity
import org.mariotaku.twidere.annotation.Referral
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.fragment.SensitiveContentWarningDialogFragment
import org.mariotaku.twidere.model.*
import org.mariotaku.twidere.model.util.ParcelableLocationUtils
@ -77,13 +78,15 @@ object IntentUtils {
}
fun userProfile(accountKey: UserKey?, userKey: UserKey?, screenName: String?,
@Referral referral: String? = null, profileUrl: String? = null): Intent {
@Referral referral: String? = null, profileUrl: String? = null,
accountHost: String? = accountKey?.host ?: userKey?.host): Intent {
val uri = LinkCreator.getTwidereUserLink(accountKey, userKey, screenName)
val intent = Intent(Intent.ACTION_VIEW, uri)
if (referral != null) {
intent.putExtra(EXTRA_REFERRAL, referral)
}
intent.putExtra(EXTRA_PROFILE_URL, profileUrl)
intent.putExtra(EXTRA_ACCOUNT_HOST, accountHost)
return intent
}

View File

@ -39,7 +39,7 @@
android:id="@+id/loadProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="96dp">
android:minHeight="@dimen/element_size_mlarge">
<ProgressBar
android:layout_width="wrap_content"

View File

@ -94,7 +94,7 @@
android:id="@+id/loadProgress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="96dp">
android:minHeight="@dimen/element_size_mlarge">
<ProgressBar
android:layout_width="wrap_content"