2016-06-29 15:47:52 +02:00
|
|
|
/*
|
|
|
|
* Twidere - Twitter client for Android
|
|
|
|
*
|
|
|
|
* Copyright (C) 2012-2014 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
|
|
|
|
|
2016-12-04 06:45:57 +01:00
|
|
|
import android.accounts.AccountManager
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.animation.ArgbEvaluator
|
|
|
|
import android.annotation.TargetApi
|
|
|
|
import android.app.Activity
|
2016-08-30 14:23:59 +02:00
|
|
|
import android.app.Dialog
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.content.Context
|
2016-08-30 14:23:59 +02:00
|
|
|
import android.content.DialogInterface
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.content.Intent
|
|
|
|
import android.graphics.Color
|
|
|
|
import android.graphics.Outline
|
|
|
|
import android.graphics.Rect
|
|
|
|
import android.graphics.drawable.ColorDrawable
|
|
|
|
import android.graphics.drawable.Drawable
|
|
|
|
import android.graphics.drawable.LayerDrawable
|
|
|
|
import android.net.Uri
|
|
|
|
import android.nfc.NdefMessage
|
|
|
|
import android.nfc.NdefRecord
|
|
|
|
import android.nfc.NfcAdapter.CreateNdefMessageCallback
|
|
|
|
import android.os.Build
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.os.Parcelable
|
|
|
|
import android.support.annotation.UiThread
|
2016-08-30 14:23:59 +02:00
|
|
|
import android.support.v4.app.DialogFragment
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.support.v4.app.Fragment
|
|
|
|
import android.support.v4.app.FragmentActivity
|
|
|
|
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
|
|
|
import android.support.v4.content.AsyncTaskLoader
|
|
|
|
import android.support.v4.content.Loader
|
|
|
|
import android.support.v4.content.res.ResourcesCompat
|
2017-01-03 14:22:20 +01:00
|
|
|
import android.support.v4.graphics.ColorUtils
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.support.v4.view.ViewCompat
|
|
|
|
import android.support.v4.view.ViewPager.OnPageChangeListener
|
|
|
|
import android.support.v4.view.WindowCompat
|
2016-08-30 14:23:59 +02:00
|
|
|
import android.support.v7.app.AlertDialog
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.support.v7.app.AppCompatActivity
|
|
|
|
import android.support.v7.widget.Toolbar
|
|
|
|
import android.text.SpannableStringBuilder
|
|
|
|
import android.text.TextUtils
|
|
|
|
import android.text.util.Linkify
|
2016-08-30 14:23:59 +02:00
|
|
|
import android.util.SparseBooleanArray
|
2016-06-29 15:47:52 +02:00
|
|
|
import android.view.*
|
|
|
|
import android.view.View.OnClickListener
|
|
|
|
import android.view.View.OnTouchListener
|
|
|
|
import android.view.animation.AnimationUtils
|
|
|
|
import com.squareup.otto.Subscribe
|
|
|
|
import edu.tsinghua.hotmobi.HotMobiLogger
|
|
|
|
import edu.tsinghua.hotmobi.model.UserEvent
|
|
|
|
import kotlinx.android.synthetic.main.fragment_user.*
|
|
|
|
import kotlinx.android.synthetic.main.fragment_user.view.*
|
|
|
|
import kotlinx.android.synthetic.main.header_user.*
|
|
|
|
import kotlinx.android.synthetic.main.header_user.view.*
|
|
|
|
import kotlinx.android.synthetic.main.layout_content_fragment_common.*
|
|
|
|
import kotlinx.android.synthetic.main.layout_content_pages_common.*
|
2016-11-26 08:14:32 +01:00
|
|
|
import nl.komponents.kovenant.task
|
2016-08-30 14:23:59 +02:00
|
|
|
import nl.komponents.kovenant.then
|
|
|
|
import nl.komponents.kovenant.ui.alwaysUi
|
|
|
|
import nl.komponents.kovenant.ui.failUi
|
|
|
|
import nl.komponents.kovenant.ui.promiseOnUi
|
|
|
|
import nl.komponents.kovenant.ui.successUi
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.apache.commons.lang3.ObjectUtils
|
2016-12-18 06:21:24 +01:00
|
|
|
import org.mariotaku.chameleon.Chameleon
|
2016-12-18 16:16:03 +01:00
|
|
|
import org.mariotaku.chameleon.ChameleonUtils
|
2017-01-07 15:45:33 +01:00
|
|
|
import org.mariotaku.kpreferences.get
|
2017-01-28 08:32:28 +01:00
|
|
|
import org.mariotaku.ktextension.*
|
2017-02-02 07:22:00 +01:00
|
|
|
import org.mariotaku.microblog.library.MicroBlog
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.microblog.library.MicroBlogException
|
|
|
|
import org.mariotaku.microblog.library.twitter.model.FriendshipUpdate
|
2016-11-26 08:14:32 +01:00
|
|
|
import org.mariotaku.microblog.library.twitter.model.Paging
|
2017-02-02 07:22:00 +01:00
|
|
|
import org.mariotaku.microblog.library.twitter.model.UserList
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.Constants.*
|
|
|
|
import org.mariotaku.twidere.R
|
2016-08-30 14:23:59 +02:00
|
|
|
import org.mariotaku.twidere.activity.AccountSelectorActivity
|
|
|
|
import org.mariotaku.twidere.activity.BaseActivity
|
|
|
|
import org.mariotaku.twidere.activity.ColorPickerDialogActivity
|
|
|
|
import org.mariotaku.twidere.activity.LinkHandlerActivity
|
|
|
|
import org.mariotaku.twidere.activity.iface.IExtendedActivity
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
2016-12-03 06:48:40 +01:00
|
|
|
import org.mariotaku.twidere.annotation.AccountType
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.annotation.Referral
|
|
|
|
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
|
2017-01-20 15:08:42 +01:00
|
|
|
import org.mariotaku.twidere.constant.displaySensitiveContentsKey
|
2017-01-28 08:32:28 +01:00
|
|
|
import org.mariotaku.twidere.constant.lightFontKey
|
2017-01-20 15:08:42 +01:00
|
|
|
import org.mariotaku.twidere.constant.newDocumentApiKey
|
2017-01-07 15:45:33 +01:00
|
|
|
import org.mariotaku.twidere.constant.profileImageStyleKey
|
2016-08-19 16:25:27 +02:00
|
|
|
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
|
|
|
|
import org.mariotaku.twidere.fragment.UserTimelineFragment.UserTimelineFragmentDelegate
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
|
|
|
|
import org.mariotaku.twidere.fragment.iface.IToolBarSupportFragment
|
|
|
|
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
|
|
|
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
|
|
|
import org.mariotaku.twidere.graphic.ActionBarColorDrawable
|
|
|
|
import org.mariotaku.twidere.graphic.ActionIconDrawable
|
|
|
|
import org.mariotaku.twidere.loader.ParcelableUserLoader
|
|
|
|
import org.mariotaku.twidere.model.*
|
|
|
|
import org.mariotaku.twidere.model.message.FriendshipTaskEvent
|
|
|
|
import org.mariotaku.twidere.model.message.FriendshipUpdatedEvent
|
|
|
|
import org.mariotaku.twidere.model.message.ProfileUpdatedEvent
|
|
|
|
import org.mariotaku.twidere.model.message.TaskStateChangedEvent
|
2016-11-30 08:18:43 +01:00
|
|
|
import org.mariotaku.twidere.model.tab.DrawableHolder
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.model.util.*
|
2016-12-13 16:11:35 +01:00
|
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
|
|
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.util.*
|
|
|
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
|
|
|
import org.mariotaku.twidere.util.TwidereLinkify.OnLinkClickListener
|
|
|
|
import org.mariotaku.twidere.util.UserColorNameManager.UserColorChangedListener
|
|
|
|
import org.mariotaku.twidere.util.UserColorNameManager.UserNicknameChangedListener
|
|
|
|
import org.mariotaku.twidere.util.menu.TwidereMenuInfo
|
|
|
|
import org.mariotaku.twidere.util.support.ActivitySupport
|
|
|
|
import org.mariotaku.twidere.util.support.ActivitySupport.TaskDescriptionCompat
|
|
|
|
import org.mariotaku.twidere.util.support.ViewSupport
|
|
|
|
import org.mariotaku.twidere.util.support.WindowSupport
|
|
|
|
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback
|
|
|
|
import org.mariotaku.twidere.view.TabPagerIndicator
|
|
|
|
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener
|
2017-01-07 12:34:42 +01:00
|
|
|
import java.lang.ref.WeakReference
|
2016-06-29 15:47:52 +02:00
|
|
|
import java.util.*
|
|
|
|
|
2017-01-12 17:26:44 +01:00
|
|
|
class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
|
2016-08-19 16:25:27 +02:00
|
|
|
OnSizeChangedListener, OnTouchListener, DrawerCallback, SupportFragmentCallback,
|
|
|
|
SystemWindowsInsetsCallback, RefreshScrollTopInterface, OnPageChangeListener,
|
|
|
|
KeyboardShortcutCallback, UserColorChangedListener, UserNicknameChangedListener,
|
|
|
|
IToolBarSupportFragment, StatusesFragmentDelegate, UserTimelineFragmentDelegate {
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
override val toolbar: Toolbar
|
|
|
|
get() = profileContentContainer.toolbar
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
private var actionBarBackground: ActionBarDrawable? = null
|
|
|
|
private lateinit var pagerAdapter: SupportTabsAdapter
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
// Data fields
|
|
|
|
var user: ParcelableUser? = null
|
|
|
|
private set
|
2016-12-04 04:58:03 +01:00
|
|
|
private var account: AccountDetails? = null
|
2016-11-26 10:41:35 +01:00
|
|
|
private var relationship: ParcelableRelationship? = null
|
2016-08-20 04:30:54 +02:00
|
|
|
private var locale: Locale? = null
|
2016-12-11 07:29:00 +01:00
|
|
|
private var getUserInfoLoaderInitialized: Boolean = false
|
|
|
|
private var getFriendShipLoaderInitialized: Boolean = false
|
|
|
|
private var bannerWidth: Int = 0
|
2016-08-20 04:30:54 +02:00
|
|
|
private var cardBackgroundColor: Int = 0
|
|
|
|
private var actionBarShadowColor: Int = 0
|
|
|
|
private var uiColor: Int = 0
|
2016-12-11 07:29:00 +01:00
|
|
|
private var primaryColor: Int = 0
|
|
|
|
private var primaryColorDark: Int = 0
|
2016-08-20 04:30:54 +02:00
|
|
|
private var nameFirst: Boolean = false
|
2016-12-11 07:29:00 +01:00
|
|
|
private var previousTabItemIsDark: Int = 0
|
|
|
|
private var previousActionBarItemIsDark: Int = 0
|
|
|
|
private var hideBirthdayView: Boolean = false
|
2016-08-20 04:30:54 +02:00
|
|
|
private var userEvent: UserEvent? = null
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
private val friendshipLoaderCallbacks = object : LoaderCallbacks<SingleResponse<ParcelableRelationship>> {
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
override fun onCreateLoader(id: Int, args: Bundle): Loader<SingleResponse<ParcelableRelationship>> {
|
2016-11-30 08:18:43 +01:00
|
|
|
activity.invalidateOptionsMenu()
|
2016-06-29 15:47:52 +02:00
|
|
|
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val user = args.getParcelable<ParcelableUser>(EXTRA_USER)
|
|
|
|
if (user != null && user.key == accountKey) {
|
|
|
|
followingYouIndicator.visibility = View.GONE
|
|
|
|
followContainer.follow.visibility = View.VISIBLE
|
2016-12-11 07:29:00 +01:00
|
|
|
followProgress.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
|
|
|
followingYouIndicator.visibility = View.GONE
|
|
|
|
followContainer.follow.visibility = View.GONE
|
2016-12-11 07:29:00 +01:00
|
|
|
followProgress.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
return UserRelationshipLoader(activity, accountKey, user)
|
|
|
|
}
|
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableRelationship>>) {
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableRelationship>>,
|
|
|
|
data: SingleResponse<ParcelableRelationship>) {
|
2016-12-11 07:29:00 +01:00
|
|
|
followProgress.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
val relationship = data.data
|
|
|
|
displayRelationship(user, relationship)
|
|
|
|
updateOptionsMenuVisibility()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2016-11-26 08:14:32 +01:00
|
|
|
private val userInfoLoaderCallbacks = object : LoaderCallbacks<SingleResponse<ParcelableUser>> {
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
override fun onCreateLoader(id: Int, args: Bundle): Loader<SingleResponse<ParcelableUser>> {
|
|
|
|
val omitIntentExtra = args.getBoolean(EXTRA_OMIT_INTENT_EXTRA, true)
|
|
|
|
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val userId = args.getParcelable<UserKey>(EXTRA_USER_KEY)
|
|
|
|
val screenName = args.getString(EXTRA_SCREEN_NAME)
|
|
|
|
if (user == null && (!omitIntentExtra || !args.containsKey(EXTRA_USER))) {
|
2016-08-19 16:25:27 +02:00
|
|
|
cardContent.visibility = View.GONE
|
|
|
|
errorContainer.visibility = View.GONE
|
|
|
|
progressContainer.visibility = View.VISIBLE
|
|
|
|
errorText.text = null
|
|
|
|
errorText.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val user = this@UserFragment.user
|
|
|
|
val loadFromCache = user == null || !user.is_cache && user.key.maybeEquals(userId)
|
|
|
|
return ParcelableUserLoader(activity, accountKey, userId, screenName, arguments,
|
|
|
|
omitIntentExtra, loadFromCache)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableUser>>) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableUser>>,
|
|
|
|
data: SingleResponse<ParcelableUser>) {
|
|
|
|
val activity = activity ?: return
|
2016-07-05 15:19:51 +02:00
|
|
|
if (data.data != null) {
|
2016-06-29 15:47:52 +02:00
|
|
|
val user = data.data
|
2016-08-19 16:25:27 +02:00
|
|
|
cardContent.visibility = View.VISIBLE
|
|
|
|
errorContainer.visibility = View.GONE
|
|
|
|
progressContainer.visibility = View.GONE
|
2016-12-04 04:58:03 +01:00
|
|
|
val account: AccountDetails = data.extras.getParcelable(EXTRA_ACCOUNT)
|
2016-06-29 15:47:52 +02:00
|
|
|
displayUser(user, account)
|
|
|
|
if (user.is_cache) {
|
|
|
|
val args = Bundle()
|
|
|
|
args.putParcelable(EXTRA_ACCOUNT_KEY, user.account_key)
|
|
|
|
args.putParcelable(EXTRA_USER_KEY, user.key)
|
|
|
|
args.putString(EXTRA_SCREEN_NAME, user.screen_name)
|
|
|
|
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, true)
|
|
|
|
loaderManager.restartLoader(LOADER_ID_USER, args, this)
|
|
|
|
}
|
|
|
|
updateOptionsMenuVisibility()
|
|
|
|
} else if (user != null && user!!.is_cache) {
|
2016-08-19 16:25:27 +02:00
|
|
|
cardContent.visibility = View.VISIBLE
|
|
|
|
errorContainer.visibility = View.GONE
|
|
|
|
progressContainer.visibility = View.GONE
|
2016-07-26 08:51:43 +02:00
|
|
|
displayUser(user, account)
|
2016-06-29 15:47:52 +02:00
|
|
|
updateOptionsMenuVisibility()
|
|
|
|
} else {
|
|
|
|
if (data.hasException()) {
|
2016-08-19 16:25:27 +02:00
|
|
|
errorText.text = Utils.getErrorMessage(activity, data.exception)
|
|
|
|
errorText.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-08-19 16:25:27 +02:00
|
|
|
cardContent.visibility = View.GONE
|
|
|
|
errorContainer.visibility = View.VISIBLE
|
|
|
|
progressContainer.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
displayUser(null, null)
|
|
|
|
updateOptionsMenuVisibility()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2016-08-19 16:25:27 +02:00
|
|
|
override val pinnedStatusIds: Array<String>?
|
|
|
|
get() = user?.extras?.pinned_status_ids
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
private fun updateOptionsMenuVisibility() {
|
2016-08-20 04:30:54 +02:00
|
|
|
setHasOptionsMenu(user != null && relationship != null)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun displayRelationship(user: ParcelableUser?,
|
2016-11-26 10:41:35 +01:00
|
|
|
userRelationship: ParcelableRelationship?) {
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user == null) {
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if (user.account_key.maybeEquals(user.key)) {
|
2016-12-26 17:26:09 +01:00
|
|
|
followContainer.follow.setText(R.string.action_edit)
|
2016-06-29 15:47:52 +02:00
|
|
|
followContainer.follow.visibility = View.VISIBLE
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = userRelationship
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if (userRelationship == null || !userRelationship.check(user)) {
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
} else {
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = userRelationship
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-11-30 08:18:43 +01:00
|
|
|
activity.invalidateOptionsMenu()
|
2016-06-29 15:47:52 +02:00
|
|
|
if (userRelationship.blocked_by) {
|
2016-12-11 07:29:00 +01:00
|
|
|
pagesErrorContainer.visibility = View.GONE
|
|
|
|
pagesErrorText.text = null
|
|
|
|
pagesContent.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
} else if (!userRelationship.following && user.is_protected) {
|
2016-12-11 07:29:00 +01:00
|
|
|
pagesErrorContainer.visibility = View.VISIBLE
|
|
|
|
pagesErrorText.setText(R.string.user_protected_summary)
|
|
|
|
pagesErrorIcon.setImageResource(R.drawable.ic_info_locked)
|
|
|
|
pagesContent.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-12-11 07:29:00 +01:00
|
|
|
pagesErrorContainer.visibility = View.GONE
|
|
|
|
pagesErrorText.text = null
|
|
|
|
pagesContent.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
if (userRelationship.blocking) {
|
2016-12-26 17:26:09 +01:00
|
|
|
followContainer.follow.setText(R.string.action_unblock)
|
2016-12-24 06:48:01 +01:00
|
|
|
} else if (userRelationship.blocked_by) {
|
|
|
|
followContainer.follow.setText(R.string.action_block)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else if (userRelationship.following) {
|
2016-12-26 17:26:09 +01:00
|
|
|
followContainer.follow.setText(R.string.action_unfollow)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else if (user.is_follow_request_sent) {
|
|
|
|
followContainer.follow.setText(R.string.requested)
|
|
|
|
} else {
|
2016-12-26 17:26:09 +01:00
|
|
|
followContainer.follow.setText(R.string.action_follow)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
followContainer.follow.compoundDrawablePadding = Math.round(followContainer.follow.textSize * 0.25f)
|
|
|
|
followingYouIndicator.visibility = if (userRelationship.followed_by) View.VISIBLE else View.GONE
|
|
|
|
|
2017-01-17 18:59:44 +01:00
|
|
|
val resolver = context.applicationContext.contentResolver
|
2016-11-26 08:14:32 +01:00
|
|
|
task {
|
|
|
|
resolver.insert(CachedUsers.CONTENT_URI, ParcelableUserValuesCreator.create(user))
|
2016-11-26 10:41:35 +01:00
|
|
|
resolver.insert(CachedRelationships.CONTENT_URI, ParcelableRelationshipValuesCreator.create(userRelationship))
|
2016-11-26 08:14:32 +01:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
followContainer.follow.visibility = View.VISIBLE
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun canScroll(dy: Float): Boolean {
|
|
|
|
val fragment = currentVisibleFragment
|
|
|
|
return fragment is DrawerCallback && fragment.canScroll(dy)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun cancelTouch() {
|
|
|
|
val fragment = currentVisibleFragment
|
|
|
|
if (fragment is DrawerCallback) {
|
|
|
|
fragment.cancelTouch()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun fling(velocity: Float) {
|
|
|
|
val fragment = currentVisibleFragment
|
|
|
|
if (fragment is DrawerCallback) {
|
|
|
|
fragment.fling(velocity)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun isScrollContent(x: Float, y: Float): Boolean {
|
|
|
|
val v = viewPager
|
|
|
|
val location = IntArray(2)
|
2016-12-11 07:29:00 +01:00
|
|
|
v.getLocationInWindow(location)
|
2016-06-29 15:47:52 +02:00
|
|
|
return x >= location[0] && x <= location[0] + v.width
|
|
|
|
&& y >= location[1] && y <= location[1] + v.height
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageSelected(position: Int) {
|
|
|
|
updateSubtitle()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateSubtitle() {
|
2016-08-25 04:10:53 +02:00
|
|
|
val activity = activity as AppCompatActivity
|
2016-06-29 15:47:52 +02:00
|
|
|
val actionBar = activity.supportActionBar ?: return
|
|
|
|
val user = this.user
|
|
|
|
if (user == null) {
|
|
|
|
actionBar.subtitle = null
|
|
|
|
return
|
|
|
|
}
|
2016-12-11 07:29:00 +01:00
|
|
|
val spec = pagerAdapter.getTab(viewPager.currentItem)
|
2016-06-29 15:47:52 +02:00
|
|
|
assert(spec.type != null)
|
|
|
|
when (spec.type) {
|
|
|
|
TAB_TYPE_STATUSES -> {
|
|
|
|
actionBar.subtitle = resources.getQuantityString(R.plurals.N_statuses,
|
|
|
|
user.statuses_count.toInt(), user.statuses_count)
|
|
|
|
}
|
|
|
|
TAB_TYPE_MEDIA -> {
|
|
|
|
if (user.media_count < 0) {
|
|
|
|
actionBar.setSubtitle(R.string.recent_media)
|
|
|
|
} else {
|
|
|
|
actionBar.subtitle = resources.getQuantityString(R.plurals.N_media,
|
|
|
|
user.media_count.toInt(), user.media_count)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TAB_TYPE_FAVORITES -> {
|
|
|
|
if (preferences.getBoolean(KEY_I_WANT_MY_STARS_BACK)) {
|
|
|
|
actionBar.subtitle = resources.getQuantityString(R.plurals.N_favorites,
|
|
|
|
user.favorites_count.toInt(), user.favorites_count)
|
|
|
|
} else {
|
|
|
|
actionBar.subtitle = resources.getQuantityString(R.plurals.N_likes,
|
|
|
|
user.favorites_count.toInt(), user.favorites_count)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
actionBar.subtitle = null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateTitleAlpha()
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onPageScrollStateChanged(state: Int) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun scrollBy(dy: Float) {
|
|
|
|
val fragment = currentVisibleFragment
|
|
|
|
if (fragment is DrawerCallback) {
|
|
|
|
fragment.scrollBy(dy)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun shouldLayoutHeaderBottom(): Boolean {
|
|
|
|
val drawer = userProfileDrawer
|
|
|
|
val card = profileDetailsContainer
|
|
|
|
if (drawer == null || card == null) return false
|
|
|
|
return card.top + drawer.headerTop - drawer.paddingTop <= 0
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun topChanged(top: Int) {
|
|
|
|
val drawer = userProfileDrawer ?: return
|
|
|
|
val offset = drawer.paddingTop - top
|
|
|
|
updateScrollOffset(offset)
|
|
|
|
|
|
|
|
val fragment = currentVisibleFragment
|
|
|
|
if (fragment is DrawerCallback) {
|
|
|
|
fragment.topChanged(top)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@UiThread
|
2016-12-04 04:58:03 +01:00
|
|
|
fun displayUser(user: ParcelableUser?, account: AccountDetails?) {
|
2016-06-29 15:47:52 +02:00
|
|
|
val activity = activity ?: return
|
|
|
|
this.user = user
|
2016-07-26 08:51:43 +02:00
|
|
|
this.account = account
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user == null || user.key == null) {
|
2016-07-02 06:05:23 +02:00
|
|
|
profileImage.visibility = View.GONE
|
2016-12-11 07:29:00 +01:00
|
|
|
profileType.visibility = View.GONE
|
2016-12-18 06:21:24 +01:00
|
|
|
val theme = Chameleon.getOverrideTheme(activity, activity)
|
2016-12-18 16:16:03 +01:00
|
|
|
setUiColor(theme.colorPrimary)
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
}
|
2016-12-11 07:29:00 +01:00
|
|
|
val adapter = pagerAdapter
|
2016-08-19 16:25:27 +02:00
|
|
|
for (i in 0 until adapter.count) {
|
|
|
|
val sf = adapter.instantiateItem(viewPager, i) as? AbsStatusesFragment
|
|
|
|
sf?.initLoaderIfNeeded()
|
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
profileImage.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
val resources = resources
|
|
|
|
val lm = loaderManager
|
|
|
|
lm.destroyLoader(LOADER_ID_USER)
|
|
|
|
lm.destroyLoader(LOADER_ID_FRIENDSHIP)
|
2016-12-11 07:29:00 +01:00
|
|
|
cardContent.visibility = View.VISIBLE
|
|
|
|
errorContainer.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
progressContainer.visibility = View.GONE
|
|
|
|
this.user = user
|
|
|
|
profileImage.setBorderColor(if (user.color != 0) user.color else Color.WHITE)
|
|
|
|
profileNameContainer.drawEnd(user.account_color)
|
|
|
|
profileNameContainer.name.text = bidiFormatter.unicodeWrap(if (TextUtils.isEmpty(user.nickname)) user.name else getString(R.string.name_with_nickname, user.name, user.nickname))
|
|
|
|
val typeIconRes = Utils.getUserTypeIconRes(user.is_verified, user.is_protected)
|
|
|
|
if (typeIconRes != 0) {
|
|
|
|
profileType.setImageResource(typeIconRes)
|
|
|
|
profileType.visibility = View.VISIBLE
|
|
|
|
} else {
|
|
|
|
profileType.setImageDrawable(null)
|
|
|
|
profileType.visibility = View.GONE
|
|
|
|
}
|
|
|
|
profileNameContainer.screenName.text = "@${user.screen_name}"
|
|
|
|
val linkify = TwidereLinkify(this)
|
|
|
|
if (user.description_unescaped != null) {
|
|
|
|
val text = SpannableStringBuilder.valueOf(user.description_unescaped)
|
|
|
|
ParcelableStatusUtils.applySpans(text, user.description_spans)
|
|
|
|
linkify.applyAllLinks(text, user.account_key, false, false)
|
|
|
|
descriptionContainer.description.text = text
|
|
|
|
} else {
|
|
|
|
descriptionContainer.description.text = user.description_plain
|
|
|
|
Linkify.addLinks(descriptionContainer.description, Linkify.WEB_URLS)
|
|
|
|
}
|
|
|
|
descriptionContainer.visibility = if (descriptionContainer.description.empty) View.GONE else View.VISIBLE
|
|
|
|
|
|
|
|
locationContainer.visibility = if (TextUtils.isEmpty(user.location)) View.GONE else View.VISIBLE
|
|
|
|
locationContainer.location.text = user.location
|
|
|
|
urlContainer.visibility = if (TextUtils.isEmpty(user.url) && TextUtils.isEmpty(user.url_expanded)) View.GONE else View.VISIBLE
|
|
|
|
urlContainer.url.text = if (TextUtils.isEmpty(user.url_expanded)) user.url else user.url_expanded
|
|
|
|
val createdAt = Utils.formatToLongTimeString(activity, user.created_at)
|
|
|
|
val daysSinceCreation = (System.currentTimeMillis() - user.created_at) / 1000 / 60 / 60 / 24.toFloat()
|
|
|
|
val dailyTweets = Math.round(user.statuses_count / Math.max(1f, daysSinceCreation))
|
|
|
|
createdAtContainer.createdAt.text = resources.getQuantityString(R.plurals.created_at_with_N_tweets_per_day, dailyTweets,
|
|
|
|
createdAt, dailyTweets)
|
2016-08-20 04:30:54 +02:00
|
|
|
listedContainer.listedCount.text = Utils.getLocalizedNumber(locale, user.listed_count)
|
2016-06-29 15:47:52 +02:00
|
|
|
val groupsCount = if (user.extras != null) user.extras.groups_count else -1
|
2016-08-20 04:30:54 +02:00
|
|
|
groupsContainer.groupsCount.text = Utils.getLocalizedNumber(locale, groupsCount)
|
2016-12-11 07:29:00 +01:00
|
|
|
followersContainer.followersCount.text = Utils.getLocalizedNumber(locale, user.followers_count)
|
|
|
|
friendsContainer.friendsCount.text = Utils.getLocalizedNumber(locale, user.friends_count)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-07-02 06:05:23 +02:00
|
|
|
listedContainer.visibility = if (user.listed_count < 0) View.GONE else View.VISIBLE
|
|
|
|
groupsContainer.visibility = if (groupsCount < 0) View.GONE else View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
mediaLoader.displayOriginalProfileImage(profileImage, user)
|
|
|
|
if (user.color != 0) {
|
|
|
|
setUiColor(user.color)
|
|
|
|
} else if (user.link_color != 0) {
|
|
|
|
setUiColor(user.link_color)
|
2016-12-18 06:21:24 +01:00
|
|
|
} else {
|
|
|
|
val theme = Chameleon.getOverrideTheme(activity, activity)
|
2016-12-18 16:16:03 +01:00
|
|
|
setUiColor(theme.colorPrimary)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val defWidth = resources.displayMetrics.widthPixels
|
2016-12-11 07:29:00 +01:00
|
|
|
val width = if (bannerWidth > 0) bannerWidth else defWidth
|
2016-06-29 15:47:52 +02:00
|
|
|
val bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user)
|
2016-07-02 06:05:23 +02:00
|
|
|
if (ObjectUtils.notEqual(profileBanner.tag, bannerUrl) || profileBanner.drawable == null) {
|
|
|
|
profileBanner.tag = bannerUrl
|
2016-06-29 15:47:52 +02:00
|
|
|
mediaLoader.displayProfileBanner(profileBanner, bannerUrl, width)
|
|
|
|
}
|
2016-08-20 04:30:54 +02:00
|
|
|
val relationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
if (relationship == null) {
|
|
|
|
getFriendship()
|
|
|
|
}
|
|
|
|
activity.title = UserColorNameManager.decideDisplayName(user.nickname, user.name,
|
2016-08-20 04:30:54 +02:00
|
|
|
user.screen_name, nameFirst)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
val cal = Calendar.getInstance()
|
|
|
|
val currentMonth = cal.get(Calendar.MONTH)
|
|
|
|
val currentDay = cal.get(Calendar.DAY_OF_MONTH)
|
|
|
|
cal.timeInMillis = user.created_at
|
2016-12-11 07:29:00 +01:00
|
|
|
if (cal.get(Calendar.MONTH) == currentMonth && cal.get(Calendar.DAY_OF_MONTH) == currentDay && !hideBirthdayView) {
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBirthdayBanner.visibility = View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBirthdayBanner.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
updateTitleAlpha()
|
2016-11-30 08:18:43 +01:00
|
|
|
activity.invalidateOptionsMenu()
|
2016-06-29 15:47:52 +02:00
|
|
|
updateSubtitle()
|
|
|
|
}
|
|
|
|
|
2016-07-06 15:21:34 +02:00
|
|
|
override val currentVisibleFragment: Fragment?
|
|
|
|
get() {
|
|
|
|
val currentItem = viewPager.currentItem
|
2016-12-11 07:29:00 +01:00
|
|
|
if (currentItem < 0 || currentItem >= pagerAdapter.count) return null
|
2017-02-04 08:39:08 +01:00
|
|
|
return pagerAdapter.instantiateItem(viewPager, currentItem)
|
2016-07-06 15:21:34 +02:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
override fun triggerRefresh(position: Int): Boolean {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getSystemWindowsInsets(insets: Rect): Boolean {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2016-07-14 14:00:27 +02:00
|
|
|
fun getUserInfo(accountKey: UserKey, userKey: UserKey?, screenName: String?,
|
2016-06-29 15:47:52 +02:00
|
|
|
omitIntentExtra: Boolean) {
|
|
|
|
val lm = loaderManager
|
|
|
|
lm.destroyLoader(LOADER_ID_USER)
|
|
|
|
lm.destroyLoader(LOADER_ID_FRIENDSHIP)
|
|
|
|
val args = Bundle()
|
|
|
|
args.putParcelable(EXTRA_ACCOUNT_KEY, accountKey)
|
|
|
|
args.putParcelable(EXTRA_USER_KEY, userKey)
|
|
|
|
args.putString(EXTRA_SCREEN_NAME, screenName)
|
|
|
|
args.putBoolean(EXTRA_OMIT_INTENT_EXTRA, omitIntentExtra)
|
2016-12-11 07:29:00 +01:00
|
|
|
if (!getUserInfoLoaderInitialized) {
|
2016-11-26 08:14:32 +01:00
|
|
|
lm.initLoader(LOADER_ID_USER, args, userInfoLoaderCallbacks)
|
2016-12-11 07:29:00 +01:00
|
|
|
getUserInfoLoaderInitialized = true
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-11-26 08:14:32 +01:00
|
|
|
lm.restartLoader(LOADER_ID_USER, args, userInfoLoaderCallbacks)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-08-09 09:48:16 +02:00
|
|
|
if (userKey == null && screenName == null) {
|
2016-12-11 07:29:00 +01:00
|
|
|
cardContent.visibility = View.GONE
|
|
|
|
errorContainer.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Subscribe
|
|
|
|
fun notifyFriendshipUpdated(event: FriendshipUpdatedEvent) {
|
|
|
|
val user = user
|
|
|
|
if (user == null || !event.isAccount(user.account_key) || !event.isUser(user.key.id))
|
|
|
|
return
|
|
|
|
getFriendship()
|
|
|
|
}
|
|
|
|
|
|
|
|
@Subscribe
|
|
|
|
fun notifyFriendshipUserUpdated(event: FriendshipTaskEvent) {
|
|
|
|
val user = user
|
|
|
|
if (user == null || !event.isSucceeded || !event.isUser(user)) return
|
|
|
|
getFriendship()
|
|
|
|
}
|
|
|
|
|
|
|
|
@Subscribe
|
|
|
|
fun notifyProfileUpdated(event: ProfileUpdatedEvent) {
|
|
|
|
val user = user
|
|
|
|
// TODO check account status
|
|
|
|
if (user == null || user != event.user) return
|
2016-07-26 08:51:43 +02:00
|
|
|
displayUser(event.user, account)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Subscribe
|
|
|
|
fun notifyTaskStateChanged(event: TaskStateChangedEvent) {
|
2016-11-30 08:18:43 +01:00
|
|
|
activity.invalidateOptionsMenu()
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
|
|
val user = user
|
|
|
|
when (requestCode) {
|
|
|
|
REQUEST_SET_COLOR -> {
|
|
|
|
if (user == null) return
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
if (data == null) return
|
|
|
|
val color = data.getIntExtra(EXTRA_COLOR, Color.TRANSPARENT)
|
|
|
|
userColorNameManager.setUserColor(this.user!!.key, color)
|
|
|
|
} else if (resultCode == ColorPickerDialogActivity.RESULT_CLEARED) {
|
|
|
|
userColorNameManager.clearUserColor(this.user!!.key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
REQUEST_ADD_TO_LIST -> {
|
|
|
|
if (user == null) return
|
|
|
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
|
|
|
val twitter = twitterWrapper
|
2016-08-20 04:30:54 +02:00
|
|
|
val list = data.getParcelableExtra<ParcelableUserList>(EXTRA_USER_LIST) ?: return
|
2016-06-29 15:47:52 +02:00
|
|
|
twitter.addUserListMembersAsync(user.account_key, list.id, user)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
REQUEST_SELECT_ACCOUNT -> {
|
|
|
|
if (user == null) return
|
|
|
|
if (resultCode == Activity.RESULT_OK) {
|
|
|
|
if (data == null || !data.hasExtra(EXTRA_ID)) return
|
|
|
|
val accountKey = data.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
@Referral
|
|
|
|
val referral = arguments.getString(EXTRA_REFERRAL)
|
2016-08-20 04:30:54 +02:00
|
|
|
IntentUtils.openUserProfile(activity, accountKey, user.key, user.screen_name,
|
2017-01-20 15:08:42 +01:00
|
|
|
preferences.getBoolean(KEY_NEW_DOCUMENT_API), referral, null)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
|
|
|
return inflater.inflate(R.layout.fragment_user, container, false)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
|
|
|
super.onActivityCreated(savedInstanceState)
|
|
|
|
val activity = activity
|
|
|
|
userColorNameManager.registerColorChangedListener(this)
|
|
|
|
userColorNameManager.registerNicknameChangedListener(this)
|
2016-08-20 04:30:54 +02:00
|
|
|
nameFirst = preferences.getBoolean(KEY_NAME_FIRST)
|
|
|
|
locale = resources.configuration.locale
|
|
|
|
cardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity,
|
2016-06-29 15:47:52 +02:00
|
|
|
ThemeUtils.getThemeBackgroundOption(activity),
|
|
|
|
ThemeUtils.getUserThemeBackgroundAlpha(activity))
|
2016-08-20 04:30:54 +02:00
|
|
|
actionBarShadowColor = 0xA0000000.toInt()
|
2016-06-29 15:47:52 +02:00
|
|
|
val args = arguments
|
2016-07-14 14:00:27 +02:00
|
|
|
val accountId: UserKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val userId: UserKey? = args.getParcelable<UserKey>(EXTRA_USER_KEY)
|
|
|
|
val screenName: String? = args.getString(EXTRA_SCREEN_NAME)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
Utils.setNdefPushMessageCallback(activity, CreateNdefMessageCallback {
|
|
|
|
val user = user ?: return@CreateNdefMessageCallback null
|
|
|
|
NdefMessage(arrayOf(NdefRecord.createUri(LinkCreator.getUserWebLink(user))))
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
userFragmentView.setWindowInsetsListener { left, top, right, bottom ->
|
2016-08-09 09:48:16 +02:00
|
|
|
profileContentContainer.setPadding(0, top, 0, 0)
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBannerSpace.statusBarHeight = top
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-07-02 06:05:23 +02:00
|
|
|
if (profileBannerSpace.toolbarHeight == 0) {
|
2016-06-29 15:47:52 +02:00
|
|
|
var toolbarHeight = toolbar.measuredHeight
|
|
|
|
if (toolbarHeight == 0) {
|
|
|
|
toolbarHeight = ThemeUtils.getActionBarHeight(context)
|
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBannerSpace.toolbarHeight = toolbarHeight
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
2016-08-09 09:48:16 +02:00
|
|
|
profileContentContainer.setOnSizeChangedListener { view, w, h, oldw, oldh ->
|
2016-06-29 15:47:52 +02:00
|
|
|
val toolbarHeight = toolbar.measuredHeight
|
2016-08-09 09:48:16 +02:00
|
|
|
userProfileDrawer.setPadding(0, toolbarHeight, 0, 0)
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBannerSpace.toolbarHeight = toolbarHeight
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-08-09 09:48:16 +02:00
|
|
|
userProfileDrawer.setDrawerCallback(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
pagerAdapter = SupportTabsAdapter(activity, childFragmentManager)
|
|
|
|
|
2016-07-02 06:05:23 +02:00
|
|
|
viewPager.offscreenPageLimit = 3
|
|
|
|
viewPager.adapter = pagerAdapter
|
|
|
|
toolbarTabs.setViewPager(viewPager)
|
2016-12-18 16:16:03 +01:00
|
|
|
toolbarTabs.setTabDisplayOption(TabPagerIndicator.DisplayOption.LABEL)
|
2016-07-02 06:05:23 +02:00
|
|
|
toolbarTabs.setOnPageChangeListener(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
followContainer.follow.setOnClickListener(this)
|
2016-07-02 06:05:23 +02:00
|
|
|
profileImage.setOnClickListener(this)
|
|
|
|
profileBanner.setOnClickListener(this)
|
|
|
|
listedContainer.setOnClickListener(this)
|
|
|
|
groupsContainer.setOnClickListener(this)
|
|
|
|
followersContainer.setOnClickListener(this)
|
|
|
|
friendsContainer.setOnClickListener(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
errorIcon.setOnClickListener(this)
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBirthdayBanner.setOnClickListener(this)
|
|
|
|
profileBanner.setOnSizeChangedListener(this)
|
|
|
|
profileBannerSpace.setOnTouchListener(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
|
2016-08-20 04:30:54 +02:00
|
|
|
profileNameBackground.setBackgroundColor(cardBackgroundColor)
|
|
|
|
profileDetailsContainer.setBackgroundColor(cardBackgroundColor)
|
|
|
|
toolbarTabs.setBackgroundColor(cardBackgroundColor)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
val actionBarElevation = ThemeUtils.getSupportActionBarElevation(activity)
|
|
|
|
ViewCompat.setElevation(toolbarTabs, actionBarElevation)
|
|
|
|
|
|
|
|
setupBaseActionBar()
|
2017-01-07 15:45:33 +01:00
|
|
|
setupViewStyle()
|
2016-06-29 15:47:52 +02:00
|
|
|
setupUserPages()
|
|
|
|
|
|
|
|
getUserInfo(accountId, userId, screenName, false)
|
|
|
|
}
|
|
|
|
|
2017-01-07 15:45:33 +01:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
override fun onStart() {
|
|
|
|
super.onStart()
|
|
|
|
bus.register(this)
|
|
|
|
|
|
|
|
@Referral
|
|
|
|
val referral = arguments.getString(EXTRA_REFERRAL)
|
|
|
|
val context = context
|
2016-08-20 04:30:54 +02:00
|
|
|
if (userEvent == null) {
|
|
|
|
userEvent = UserEvent.create(context, referral)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-08-20 04:30:54 +02:00
|
|
|
userEvent!!.markStart(context)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onStop() {
|
|
|
|
val context = context
|
2016-08-20 04:30:54 +02:00
|
|
|
if (userEvent != null && context != null && user != null) {
|
|
|
|
userEvent!!.setUser(user!!)
|
|
|
|
userEvent!!.markEnd()
|
2016-12-06 06:15:22 +01:00
|
|
|
HotMobiLogger.getInstance(context).log(userEvent!!)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
bus.unregister(this)
|
|
|
|
super.onStop()
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onResume() {
|
|
|
|
super.onResume()
|
2016-08-20 04:30:54 +02:00
|
|
|
setUiColor(uiColor)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun onSaveInstanceState(outState: Bundle) {
|
|
|
|
outState.putParcelable(EXTRA_USER, user)
|
2016-06-29 15:47:52 +02:00
|
|
|
super.onSaveInstanceState(outState)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onDestroyView() {
|
|
|
|
user = null
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
val lm = loaderManager
|
|
|
|
lm.destroyLoader(LOADER_ID_USER)
|
|
|
|
lm.destroyLoader(LOADER_ID_FRIENDSHIP)
|
|
|
|
super.onDestroyView()
|
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
|
|
|
inflater.inflate(R.menu.menu_user_profile, menu)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@UiThread
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun onPrepareOptionsMenu(menu: Menu) {
|
2016-07-02 06:05:23 +02:00
|
|
|
val user = user ?: return
|
2016-11-26 09:13:00 +01:00
|
|
|
val account = this.account
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
val isMyself = user.account_key.maybeEquals(user.key)
|
2016-12-11 07:29:00 +01:00
|
|
|
val mentionItem = menu.findItem(R.id.mention)
|
2016-06-29 15:47:52 +02:00
|
|
|
if (mentionItem != null) {
|
|
|
|
val displayName = UserColorNameManager.decideDisplayName(user.nickname,
|
2016-08-20 04:30:54 +02:00
|
|
|
user.name, user.screen_name, nameFirst)
|
2016-06-29 15:47:52 +02:00
|
|
|
mentionItem.title = getString(R.string.mention_user_name, displayName)
|
|
|
|
}
|
2016-07-04 03:31:17 +02:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.mention, !isMyself)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.incoming_friendships, isMyself)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.saved_searches, isMyself)
|
|
|
|
|
2016-11-26 09:13:00 +01:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.blocked_users, isMyself)
|
2016-07-04 03:31:17 +02:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.block, !isMyself)
|
2016-11-26 09:13:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
val isTwitter: Boolean
|
|
|
|
|
2016-07-26 08:51:43 +02:00
|
|
|
if (account != null) {
|
2016-12-04 06:45:57 +01:00
|
|
|
isTwitter = AccountType.TWITTER == account.type
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-11-26 09:13:00 +01:00
|
|
|
isTwitter = false
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-11-26 09:13:00 +01:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.add_to_list, isTwitter)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.mute_user, !isMyself && isTwitter)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.muted_users, isMyself && isTwitter)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.report_spam, !isMyself && isTwitter)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.enable_retweets, !isMyself && isTwitter)
|
|
|
|
|
2016-08-20 04:30:54 +02:00
|
|
|
val userRelationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
if (userRelationship != null) {
|
|
|
|
|
|
|
|
val filterItem = menu.findItem(R.id.add_to_filter)
|
|
|
|
if (filterItem != null) {
|
|
|
|
filterItem.isChecked = userRelationship.filtering
|
|
|
|
}
|
|
|
|
if (isMyself) {
|
2016-07-04 03:31:17 +02:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.send_direct_message, false)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-07-04 03:31:17 +02:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.send_direct_message, userRelationship.can_dm)
|
|
|
|
MenuUtils.setItemAvailability(menu, R.id.block, true)
|
2016-06-29 15:47:52 +02:00
|
|
|
val blockItem = menu.findItem(R.id.block)
|
|
|
|
if (blockItem != null) {
|
|
|
|
ActionIconDrawable.setMenuHighlight(blockItem, TwidereMenuInfo(userRelationship.blocking))
|
2016-12-26 17:26:09 +01:00
|
|
|
blockItem.setTitle(if (userRelationship.blocking) R.string.action_unblock else R.string.action_block)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val muteItem = menu.findItem(R.id.mute_user)
|
|
|
|
if (muteItem != null) {
|
|
|
|
muteItem.isChecked = userRelationship.muting
|
|
|
|
}
|
|
|
|
val wantRetweetsItem = menu.findItem(R.id.enable_retweets)
|
|
|
|
if (wantRetweetsItem != null) {
|
|
|
|
wantRetweetsItem.isChecked = userRelationship.retweet_enabled
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2016-07-04 03:31:17 +02:00
|
|
|
MenuUtils.setItemAvailability(menu, R.id.send_direct_message, false)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val intent = Intent(INTENT_ACTION_EXTENSION_OPEN_USER)
|
|
|
|
val extras = Bundle()
|
|
|
|
extras.putParcelable(EXTRA_USER, user)
|
|
|
|
intent.putExtras(extras)
|
|
|
|
menu.removeGroup(MENU_GROUP_USER_EXTENSION)
|
|
|
|
MenuUtils.addIntentToMenu(activity, menu, intent, MENU_GROUP_USER_EXTENSION)
|
|
|
|
val drawer = userProfileDrawer
|
|
|
|
if (drawer != null) {
|
|
|
|
val offset = drawer.paddingTop - drawer.headerTop
|
2016-12-11 07:29:00 +01:00
|
|
|
previousActionBarItemIsDark = 0
|
|
|
|
previousTabItemIsDark = 0
|
2016-06-29 15:47:52 +02:00
|
|
|
updateScrollOffset(offset)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
val context = context
|
|
|
|
val twitter = twitterWrapper
|
|
|
|
val user = user
|
2016-08-20 04:30:54 +02:00
|
|
|
val userRelationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user == null) return false
|
2016-12-11 07:29:00 +01:00
|
|
|
when (item.itemId) {
|
2016-06-29 15:47:52 +02:00
|
|
|
R.id.block -> {
|
|
|
|
if (userRelationship == null) return true
|
|
|
|
if (userRelationship.blocking) {
|
|
|
|
twitter.destroyBlockAsync(user.account_key, user.key)
|
|
|
|
} else {
|
|
|
|
CreateUserBlockDialogFragment.show(fragmentManager, user)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
R.id.report_spam -> {
|
|
|
|
ReportSpamDialogFragment.show(fragmentManager, user)
|
|
|
|
}
|
|
|
|
R.id.add_to_filter -> {
|
|
|
|
if (userRelationship == null) return true
|
|
|
|
if (userRelationship.filtering) {
|
2016-12-28 06:17:24 +01:00
|
|
|
DataStoreUtils.removeFromFilter(context, listOf(user))
|
2017-01-27 08:43:25 +01:00
|
|
|
Utils.showInfoMessage(activity, R.string.message_toast_user_filters_removed, false)
|
2016-12-11 07:29:00 +01:00
|
|
|
getFriendship()
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-12-11 07:29:00 +01:00
|
|
|
AddUserFilterDialogFragment.show(fragmentManager, user)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
R.id.mute_user -> {
|
|
|
|
if (userRelationship == null) return true
|
|
|
|
if (userRelationship.muting) {
|
|
|
|
twitter.destroyMuteAsync(user.account_key, user.key)
|
|
|
|
} else {
|
|
|
|
CreateUserMuteDialogFragment.show(fragmentManager, user)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
R.id.mention -> {
|
|
|
|
val intent = Intent(INTENT_ACTION_MENTION)
|
|
|
|
val bundle = Bundle()
|
|
|
|
bundle.putParcelable(EXTRA_USER, user)
|
|
|
|
intent.putExtras(bundle)
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
R.id.send_direct_message -> {
|
|
|
|
val builder = Uri.Builder()
|
|
|
|
builder.scheme(SCHEME_TWIDERE)
|
|
|
|
builder.authority(AUTHORITY_DIRECT_MESSAGES_CONVERSATION)
|
|
|
|
builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, user.account_key.toString())
|
|
|
|
builder.appendQueryParameter(QUERY_PARAM_USER_KEY, user.key.toString())
|
|
|
|
val intent = Intent(Intent.ACTION_VIEW, builder.build())
|
2016-12-15 06:11:32 +01:00
|
|
|
intent.putExtra(EXTRA_ACCOUNT, AccountUtils.getAccountDetails(AccountManager.get(activity), user.account_key, true))
|
2016-06-29 15:47:52 +02:00
|
|
|
intent.putExtra(EXTRA_USER, user)
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
R.id.set_color -> {
|
|
|
|
val intent = Intent(activity, ColorPickerDialogActivity::class.java)
|
|
|
|
intent.putExtra(EXTRA_COLOR, userColorNameManager.getUserColor(user.key))
|
|
|
|
intent.putExtra(EXTRA_ALPHA_SLIDER, false)
|
|
|
|
intent.putExtra(EXTRA_CLEAR_BUTTON, true)
|
|
|
|
startActivityForResult(intent, REQUEST_SET_COLOR)
|
|
|
|
}
|
|
|
|
R.id.clear_nickname -> {
|
|
|
|
userColorNameManager.clearUserNickname(user.key)
|
|
|
|
}
|
|
|
|
R.id.set_nickname -> {
|
|
|
|
val nick = userColorNameManager.getUserNickname(user.key)
|
|
|
|
SetUserNicknameDialogFragment.show(fragmentManager, user.key, nick)
|
|
|
|
}
|
|
|
|
R.id.add_to_list -> {
|
2016-08-30 14:23:59 +02:00
|
|
|
promiseOnUi {
|
|
|
|
executeAfterFragmentResumed {
|
|
|
|
ProgressDialogFragment.show(fragmentManager, "get_list_progress")
|
|
|
|
}
|
|
|
|
}.then {
|
2017-02-02 07:22:00 +01:00
|
|
|
fun MicroBlog.getUserListOwnerMemberships(id: String): ArrayList<UserList> {
|
|
|
|
val result = ArrayList<UserList>()
|
|
|
|
var nextCursor: Long
|
|
|
|
val paging = Paging()
|
|
|
|
paging.count(100)
|
|
|
|
do {
|
|
|
|
val resp = getUserListMemberships(user.key.id, paging, true)
|
|
|
|
result.addAll(resp)
|
|
|
|
nextCursor = resp.nextCursor
|
|
|
|
paging.cursor(nextCursor)
|
|
|
|
} while (nextCursor > 0)
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2016-12-06 06:15:22 +01:00
|
|
|
val microBlog = MicroBlogAPIFactory.getInstance(context, user.account_key)
|
2017-02-02 07:22:00 +01:00
|
|
|
val ownedLists = ArrayList<ParcelableUserList>()
|
|
|
|
val listMemberships = microBlog.getUserListOwnerMemberships(user.key.id)
|
2016-11-26 08:14:32 +01:00
|
|
|
val paging = Paging()
|
2017-02-02 07:22:00 +01:00
|
|
|
paging.count(100)
|
|
|
|
var nextCursor: Long
|
|
|
|
do {
|
|
|
|
val resp = microBlog.getUserListOwnerships(paging)
|
|
|
|
resp.mapTo(ownedLists) { item ->
|
|
|
|
val userList = ParcelableUserListUtils.from(item, user.account_key)
|
|
|
|
userList.is_user_inside = listMemberships.any { it.id == item.id }
|
|
|
|
return@mapTo userList
|
|
|
|
}
|
|
|
|
nextCursor = resp.nextCursor
|
|
|
|
paging.cursor(nextCursor)
|
|
|
|
} while (nextCursor > 0)
|
|
|
|
return@then ownedLists.toTypedArray()
|
2016-08-30 14:23:59 +02:00
|
|
|
}.alwaysUi {
|
|
|
|
executeAfterFragmentResumed {
|
|
|
|
val df = fragmentManager.findFragmentByTag("get_list_progress") as? DialogFragment
|
|
|
|
df?.dismiss()
|
|
|
|
}
|
|
|
|
}.successUi { result ->
|
2017-01-07 12:34:42 +01:00
|
|
|
executeAfterFragmentResumed { fragment ->
|
2016-08-30 14:23:59 +02:00
|
|
|
val df = AddRemoveUserListDialogFragment()
|
|
|
|
df.arguments = Bundle {
|
|
|
|
this[EXTRA_ACCOUNT_KEY] = user.account_key
|
|
|
|
this[EXTRA_USER_KEY] = user.key
|
|
|
|
this[EXTRA_USER_LISTS] = result
|
|
|
|
}
|
2017-01-07 12:34:42 +01:00
|
|
|
df.show(fragment.fragmentManager, "add_remove_list")
|
2016-08-30 14:23:59 +02:00
|
|
|
}
|
|
|
|
}.failUi {
|
|
|
|
Utils.showErrorMessage(context, R.string.action_getting_user_lists, it, false)
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
R.id.open_with_account -> {
|
|
|
|
val intent = Intent(INTENT_ACTION_SELECT_ACCOUNT)
|
|
|
|
intent.setClass(activity, AccountSelectorActivity::class.java)
|
|
|
|
intent.putExtra(EXTRA_SINGLE_SELECTION, true)
|
|
|
|
intent.putExtra(EXTRA_ACCOUNT_HOST, user.key.host)
|
|
|
|
startActivityForResult(intent, REQUEST_SELECT_ACCOUNT)
|
|
|
|
}
|
|
|
|
R.id.follow -> {
|
|
|
|
if (userRelationship == null) return true
|
|
|
|
val updatingRelationship = twitter.isUpdatingRelationship(user.account_key,
|
|
|
|
user.key)
|
|
|
|
if (!updatingRelationship) {
|
|
|
|
if (userRelationship.following) {
|
|
|
|
DestroyFriendshipDialogFragment.show(fragmentManager, user)
|
|
|
|
} else {
|
|
|
|
twitter.createFriendshipAsync(user.account_key, user.key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.enable_retweets -> {
|
|
|
|
val newState = !item.isChecked
|
|
|
|
val update = FriendshipUpdate()
|
|
|
|
update.retweets(newState)
|
2016-07-05 15:19:51 +02:00
|
|
|
twitter.updateFriendship(user.account_key, user.key, update)
|
2016-06-29 15:47:52 +02:00
|
|
|
item.isChecked = newState
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.muted_users -> {
|
|
|
|
IntentUtils.openMutesUsers(activity, user.account_key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.blocked_users -> {
|
|
|
|
IntentUtils.openUserBlocks(activity, user.account_key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.incoming_friendships -> {
|
|
|
|
IntentUtils.openIncomingFriendships(activity, user.account_key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.user_mentions -> {
|
|
|
|
IntentUtils.openUserMentions(context, user.account_key, user.screen_name)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.saved_searches -> {
|
|
|
|
IntentUtils.openSavedSearches(context, user.account_key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.scheduled_statuses -> {
|
|
|
|
IntentUtils.openScheduledStatuses(context, user.account_key)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.open_in_browser -> {
|
|
|
|
val uri = LinkCreator.getUserWebLink(user)
|
|
|
|
val intent = Intent(Intent.ACTION_VIEW, uri)
|
|
|
|
intent.addCategory(Intent.CATEGORY_BROWSABLE)
|
|
|
|
intent.`package` = IntentUtils.getDefaultBrowserPackage(context, uri, true)
|
|
|
|
if (intent.resolveActivity(context.packageManager) != null) {
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
val intent = item.intent
|
|
|
|
if (intent != null && intent.resolveActivity(context.packageManager) != null) {
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
|
|
|
|
super.onViewCreated(view, savedInstanceState)
|
|
|
|
val host = host
|
|
|
|
if (host is AppCompatActivity) {
|
|
|
|
host.setSupportActionBar(toolbar)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
if (handleFragmentKeyboardShortcutSingle(handler, keyCode, event, metaState)) return true
|
|
|
|
val action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
|
|
|
if (action != null) {
|
|
|
|
when (action) {
|
|
|
|
ACTION_NAVIGATION_PREVIOUS_TAB -> {
|
|
|
|
val previous = viewPager.currentItem - 1
|
2016-12-11 07:29:00 +01:00
|
|
|
if (previous >= 0 && previous < pagerAdapter.count) {
|
2016-07-02 06:05:23 +02:00
|
|
|
viewPager.setCurrentItem(previous, true)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
ACTION_NAVIGATION_NEXT_TAB -> {
|
|
|
|
val next = viewPager.currentItem + 1
|
2016-12-11 07:29:00 +01:00
|
|
|
if (next >= 0 && next < pagerAdapter.count) {
|
2016-07-02 06:05:23 +02:00
|
|
|
viewPager.setCurrentItem(next, true)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return handler.handleKey(activity, null, keyCode, event, metaState)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
if (isFragmentKeyboardShortcutHandled(handler, keyCode, event, metaState)) return true
|
|
|
|
val action = handler.getKeyAction(CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
|
|
|
if (action != null) {
|
|
|
|
when (action) {
|
|
|
|
ACTION_NAVIGATION_PREVIOUS_TAB, ACTION_NAVIGATION_NEXT_TAB -> return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler,
|
|
|
|
keyCode: Int, repeatCount: Int,
|
|
|
|
event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
return handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleFragmentKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler,
|
|
|
|
keyCode: Int, repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
val fragment = keyboardShortcutRecipient
|
|
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
|
|
return fragment.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleFragmentKeyboardShortcutSingle(handler: KeyboardShortcutsHandler,
|
|
|
|
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
val fragment = keyboardShortcutRecipient
|
|
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
|
|
return fragment.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun isFragmentKeyboardShortcutHandled(handler: KeyboardShortcutsHandler,
|
|
|
|
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
|
|
val fragment = keyboardShortcutRecipient
|
|
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
|
|
return fragment.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
private val keyboardShortcutRecipient: Fragment?
|
|
|
|
get() = currentVisibleFragment
|
|
|
|
|
|
|
|
override fun fitSystemWindows(insets: Rect) {
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun setupWindow(activity: FragmentActivity): Boolean {
|
|
|
|
if (activity is AppCompatActivity) {
|
|
|
|
activity.supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
|
|
activity.supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_MODE_OVERLAY)
|
|
|
|
}
|
|
|
|
WindowSupport.setStatusBarColor(activity.window, Color.TRANSPARENT)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onClick(view: View) {
|
|
|
|
val activity = activity
|
|
|
|
val user = user
|
|
|
|
if (activity == null || user == null) return
|
|
|
|
when (view.id) {
|
|
|
|
R.id.errorContainer -> {
|
|
|
|
getUserInfo(true)
|
|
|
|
}
|
|
|
|
R.id.follow -> {
|
|
|
|
if (user.account_key.maybeEquals(user.key)) {
|
|
|
|
IntentUtils.openProfileEditor(getActivity(), user.account_key)
|
|
|
|
} else {
|
2016-08-20 04:30:54 +02:00
|
|
|
val userRelationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
val twitter = twitterWrapper
|
|
|
|
if (userRelationship == null) return
|
|
|
|
if (userRelationship.blocking) {
|
|
|
|
twitter.destroyBlockAsync(user.account_key, user.key)
|
2016-12-24 06:48:01 +01:00
|
|
|
} else if (userRelationship.blocked_by) {
|
|
|
|
CreateUserBlockDialogFragment.show(childFragmentManager, user)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else if (userRelationship.following) {
|
|
|
|
DestroyFriendshipDialogFragment.show(fragmentManager, user)
|
|
|
|
} else {
|
|
|
|
twitter.createFriendshipAsync(user.account_key, user.key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
R.id.profileImage -> {
|
2016-06-29 15:47:52 +02:00
|
|
|
val url = Utils.getOriginalTwitterProfileImage(user.profile_image_url)
|
|
|
|
val profileImage = ParcelableMediaUtils.image(url)
|
|
|
|
profileImage.type = ParcelableMedia.Type.IMAGE
|
|
|
|
val media = arrayOf(profileImage)
|
2017-01-20 15:08:42 +01:00
|
|
|
IntentUtils.openMedia(activity, user.account_key, media, null, false,
|
|
|
|
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
R.id.profileBanner -> {
|
|
|
|
val bannerUrl = ParcelableUserUtils.getProfileBannerUrl(user) ?: return
|
|
|
|
val url = InternalTwitterContentUtils.getBestBannerUrl(bannerUrl,
|
|
|
|
Integer.MAX_VALUE)
|
|
|
|
val profileBanner = ParcelableMediaUtils.image(url)
|
|
|
|
profileBanner.type = ParcelableMedia.Type.IMAGE
|
|
|
|
val media = arrayOf(profileBanner)
|
2017-01-20 15:08:42 +01:00
|
|
|
IntentUtils.openMedia(activity, user.account_key, media, null, false,
|
|
|
|
preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey])
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
R.id.listedContainer -> {
|
|
|
|
IntentUtils.openUserLists(getActivity(), user.account_key, user.key,
|
|
|
|
user.screen_name)
|
|
|
|
}
|
|
|
|
R.id.groupsContainer -> {
|
|
|
|
IntentUtils.openUserGroups(getActivity(), user.account_key, user.key,
|
|
|
|
user.screen_name)
|
|
|
|
}
|
|
|
|
R.id.followersContainer -> {
|
|
|
|
IntentUtils.openUserFollowers(getActivity(), user.account_key, user.key,
|
|
|
|
user.screen_name)
|
|
|
|
}
|
|
|
|
R.id.friendsContainer -> {
|
|
|
|
IntentUtils.openUserFriends(getActivity(), user.account_key, user.key,
|
|
|
|
user.screen_name)
|
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
R.id.nameContainer -> {
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user.account_key == user.key) return
|
|
|
|
IntentUtils.openProfileEditor(getActivity(), user.account_key)
|
|
|
|
}
|
|
|
|
R.id.profileBirthdayBanner -> {
|
2016-12-11 07:29:00 +01:00
|
|
|
hideBirthdayView = true
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBirthdayBanner.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out))
|
|
|
|
profileBirthdayBanner.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-07-16 09:27:46 +02:00
|
|
|
override fun onLinkClick(link: String, orig: String?, accountKey: UserKey?,
|
2016-06-29 15:47:52 +02:00
|
|
|
extraId: Long, type: Int, sensitive: Boolean,
|
|
|
|
start: Int, end: Int): Boolean {
|
|
|
|
val user = user ?: return false
|
|
|
|
when (type) {
|
|
|
|
TwidereLinkify.LINK_TYPE_MENTION -> {
|
2017-01-20 15:08:42 +01:00
|
|
|
IntentUtils.openUserProfile(activity, user.account_key, null, link, preferences.getBoolean(KEY_NEW_DOCUMENT_API),
|
|
|
|
Referral.USER_MENTION, null)
|
2016-06-29 15:47:52 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
TwidereLinkify.LINK_TYPE_HASHTAG -> {
|
2016-07-16 09:27:46 +02:00
|
|
|
IntentUtils.openTweetSearch(activity, user.account_key, "#" + link)
|
2016-06-29 15:47:52 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
TwidereLinkify.LINK_TYPE_LINK_IN_TEXT, TwidereLinkify.LINK_TYPE_ENTITY_URL -> {
|
|
|
|
val uri = Uri.parse(link)
|
|
|
|
val intent: Intent
|
|
|
|
if (uri.scheme != null) {
|
|
|
|
intent = Intent(Intent.ACTION_VIEW, uri)
|
|
|
|
} else {
|
|
|
|
intent = Intent(Intent.ACTION_VIEW, uri.buildUpon().scheme("http").build())
|
|
|
|
}
|
|
|
|
startActivity(intent)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
TwidereLinkify.LINK_TYPE_LIST -> {
|
2016-08-25 04:10:53 +02:00
|
|
|
val mentionList = link.split("/").dropLastWhile(String::isEmpty)
|
2016-07-16 09:27:46 +02:00
|
|
|
if (mentionList.size != 2) {
|
2016-06-29 15:47:52 +02:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onUserNicknameChanged(userId: UserKey, nick: String) {
|
|
|
|
if (user == null || user!!.key != userId) return
|
2016-07-26 08:51:43 +02:00
|
|
|
displayUser(user, account)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onUserColorChanged(userId: UserKey, color: Int) {
|
|
|
|
if (user == null || user!!.key != userId) return
|
2016-07-26 08:51:43 +02:00
|
|
|
displayUser(user, account)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onSizeChanged(view: View, w: Int, h: Int, oldw: Int, oldh: Int) {
|
2016-12-11 07:29:00 +01:00
|
|
|
bannerWidth = w
|
2016-06-29 15:47:52 +02:00
|
|
|
if (w != oldw || h != oldh) {
|
|
|
|
requestFitSystemWindows()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
2016-07-02 06:05:23 +02:00
|
|
|
if (profileBirthdayBanner.visibility == View.VISIBLE) {
|
|
|
|
return profileBirthdayBanner.dispatchTouchEvent(event)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
return profileBanner.dispatchTouchEvent(event)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun scrollToStart(): Boolean {
|
2016-12-06 06:15:22 +01:00
|
|
|
val fragment = currentVisibleFragment as? RefreshScrollTopInterface ?: return false
|
2016-06-29 15:47:52 +02:00
|
|
|
fragment.scrollToStart()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun triggerRefresh(): Boolean {
|
2016-12-06 06:15:22 +01:00
|
|
|
val fragment = currentVisibleFragment as? RefreshScrollTopInterface ?: return false
|
2016-06-29 15:47:52 +02:00
|
|
|
fragment.triggerRefresh()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun getFriendship() {
|
|
|
|
val user = user ?: return
|
2016-08-20 04:30:54 +02:00
|
|
|
relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
val lm = loaderManager
|
|
|
|
lm.destroyLoader(LOADER_ID_FRIENDSHIP)
|
|
|
|
val args = Bundle()
|
|
|
|
args.putParcelable(EXTRA_ACCOUNT_KEY, user.account_key)
|
|
|
|
args.putParcelable(EXTRA_USER, user)
|
2016-12-11 07:29:00 +01:00
|
|
|
if (!getFriendShipLoaderInitialized) {
|
2016-11-26 08:14:32 +01:00
|
|
|
lm.initLoader(LOADER_ID_FRIENDSHIP, args, friendshipLoaderCallbacks)
|
2016-12-11 07:29:00 +01:00
|
|
|
getFriendShipLoaderInitialized = true
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-11-26 08:14:32 +01:00
|
|
|
lm.restartLoader(LOADER_ID_FRIENDSHIP, args, friendshipLoaderCallbacks)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun getUserInfo(omitIntentExtra: Boolean) {
|
|
|
|
val user = this.user ?: return
|
|
|
|
getUserInfo(user.account_key, user.key, user.screen_name, omitIntentExtra)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setUiColor(color: Int) {
|
2016-08-20 04:30:54 +02:00
|
|
|
uiColor = color
|
2016-12-11 07:29:00 +01:00
|
|
|
previousActionBarItemIsDark = 0
|
|
|
|
previousTabItemIsDark = 0
|
|
|
|
if (actionBarBackground == null) {
|
2016-06-29 15:47:52 +02:00
|
|
|
setupBaseActionBar()
|
|
|
|
}
|
|
|
|
val activity = activity as BaseActivity
|
2016-12-18 06:21:24 +01:00
|
|
|
val theme = Chameleon.getOverrideTheme(activity, activity)
|
2016-12-18 03:32:11 +01:00
|
|
|
if (theme.isToolbarColored) {
|
2016-12-11 07:29:00 +01:00
|
|
|
primaryColor = color
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-12-18 16:16:03 +01:00
|
|
|
primaryColor = theme.colorToolbar
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-12-18 16:16:03 +01:00
|
|
|
primaryColorDark = ChameleonUtils.darkenColor(primaryColor)
|
2016-12-11 07:29:00 +01:00
|
|
|
if (actionBarBackground != null) {
|
|
|
|
actionBarBackground!!.color = primaryColor
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val taskColor: Int
|
2016-12-18 03:32:11 +01:00
|
|
|
if (theme.isToolbarColored) {
|
2017-01-03 14:22:20 +01:00
|
|
|
taskColor = ColorUtils.setAlphaComponent(color, 0xFF)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-01-03 14:22:20 +01:00
|
|
|
taskColor = ColorUtils.setAlphaComponent(theme.colorToolbar, 0xFF)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
if (user != null) {
|
2016-08-20 04:30:54 +02:00
|
|
|
val name = userColorNameManager.getDisplayName(user, nameFirst)
|
2016-06-29 15:47:52 +02:00
|
|
|
ActivitySupport.setTaskDescription(activity, TaskDescriptionCompat(name, null, taskColor))
|
|
|
|
} else {
|
|
|
|
ActivitySupport.setTaskDescription(activity, TaskDescriptionCompat(null, null, taskColor))
|
|
|
|
}
|
|
|
|
val optimalAccentColor = ThemeUtils.getOptimalAccentColor(color,
|
|
|
|
descriptionContainer.description.currentTextColor)
|
|
|
|
descriptionContainer.description.setLinkTextColor(optimalAccentColor)
|
|
|
|
locationContainer.location.setLinkTextColor(optimalAccentColor)
|
|
|
|
urlContainer.url.setLinkTextColor(optimalAccentColor)
|
|
|
|
profileBanner.setBackgroundColor(color)
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
toolbarTabs.setBackgroundColor(primaryColor)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
val drawer = userProfileDrawer
|
|
|
|
if (drawer != null) {
|
|
|
|
val offset = drawer.paddingTop - drawer.headerTop
|
|
|
|
updateScrollOffset(offset)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setupBaseActionBar() {
|
2016-12-06 06:15:22 +01:00
|
|
|
val activity = activity as? LinkHandlerActivity ?: return
|
2016-06-29 15:47:52 +02:00
|
|
|
val actionBar = activity.supportActionBar ?: return
|
2016-12-11 07:29:00 +01:00
|
|
|
val shadow = ResourcesCompat.getDrawable(activity.resources, R.drawable.shadow_user_banner_action_bar, null)!!
|
|
|
|
actionBarBackground = ActionBarDrawable(shadow)
|
2016-06-29 15:47:52 +02:00
|
|
|
if (!ThemeUtils.isWindowFloating(activity) && ThemeUtils.isTransparentBackground(activity.currentThemeBackgroundOption)) {
|
|
|
|
// mActionBarBackground.setAlpha(ThemeUtils.getActionBarAlpha(linkHandler.getCurrentThemeBackgroundAlpha()));
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBanner.alpha = activity.currentThemeBackgroundAlpha / 255f
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-12-11 07:29:00 +01:00
|
|
|
actionBar.setBackgroundDrawable(actionBarBackground)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2017-01-07 15:45:33 +01:00
|
|
|
|
|
|
|
private fun setupViewStyle() {
|
|
|
|
profileImage.style = preferences[profileImageStyleKey]
|
2017-01-28 08:32:28 +01:00
|
|
|
|
|
|
|
val lightFont = preferences[lightFontKey]
|
|
|
|
|
|
|
|
profileNameContainer.name.applyFontFamily(lightFont)
|
|
|
|
profileNameContainer.screenName.applyFontFamily(lightFont)
|
|
|
|
profileNameContainer.followingYouIndicator.applyFontFamily(lightFont)
|
|
|
|
descriptionContainer.description.applyFontFamily(lightFont)
|
|
|
|
urlContainer.url.applyFontFamily(lightFont)
|
|
|
|
locationContainer.location.applyFontFamily(lightFont)
|
|
|
|
createdAtContainer.createdAt.applyFontFamily(lightFont)
|
2017-01-07 15:45:33 +01:00
|
|
|
}
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
private fun setupUserPages() {
|
|
|
|
val args = arguments
|
|
|
|
val tabArgs = Bundle()
|
|
|
|
val user = args.getParcelable<ParcelableUser>(EXTRA_USER)
|
|
|
|
if (user != null) {
|
|
|
|
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, user.account_key)
|
|
|
|
tabArgs.putParcelable(EXTRA_USER_KEY, user.key)
|
|
|
|
tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name)
|
|
|
|
} else {
|
|
|
|
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, args.getParcelable<Parcelable>(EXTRA_ACCOUNT_KEY))
|
|
|
|
tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable<Parcelable>(EXTRA_USER_KEY))
|
|
|
|
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME))
|
|
|
|
}
|
2016-12-26 17:46:37 +01:00
|
|
|
pagerAdapter.addTab(cls = UserTimelineFragment::class.java, args = tabArgs, name = getString(R.string.title_statuses),
|
2016-11-30 08:18:43 +01:00
|
|
|
icon = DrawableHolder.resource(R.drawable.ic_action_quote), type = TAB_TYPE_STATUSES, position = TAB_POSITION_STATUSES)
|
2016-12-11 07:29:00 +01:00
|
|
|
pagerAdapter.addTab(cls = UserMediaTimelineFragment::class.java, args = tabArgs, name = getString(R.string.media),
|
2016-11-30 08:18:43 +01:00
|
|
|
icon = DrawableHolder.resource(R.drawable.ic_action_gallery), type = TAB_TYPE_MEDIA, position = TAB_POSITION_MEDIA)
|
2016-06-29 15:47:52 +02:00
|
|
|
if (preferences.getBoolean(KEY_I_WANT_MY_STARS_BACK)) {
|
2016-12-26 17:26:09 +01:00
|
|
|
pagerAdapter.addTab(cls = UserFavoritesFragment::class.java, args = tabArgs, name = getString(R.string.title_favorites),
|
2016-11-30 08:18:43 +01:00
|
|
|
icon = DrawableHolder.resource(R.drawable.ic_action_star), type = TAB_TYPE_FAVORITES, position = TAB_POSITION_FAVORITES)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-12-26 17:26:09 +01:00
|
|
|
pagerAdapter.addTab(cls = UserFavoritesFragment::class.java, args = tabArgs, name = getString(R.string.title_likes),
|
2016-11-30 08:18:43 +01:00
|
|
|
icon = DrawableHolder.resource(R.drawable.ic_action_heart), type = TAB_TYPE_FAVORITES, position = TAB_POSITION_FAVORITES)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateScrollOffset(offset: Int) {
|
2016-12-11 07:29:00 +01:00
|
|
|
val spaceHeight = profileBannerSpace.height
|
2017-02-04 11:42:14 +01:00
|
|
|
val factor = (if (spaceHeight == 0) 0f else offset / spaceHeight.toFloat()).coerceIn(0f, 1f)
|
2016-12-11 07:29:00 +01:00
|
|
|
profileBannerContainer.translationY = (-offset).toFloat()
|
|
|
|
profileBanner.translationY = (offset / 2).toFloat()
|
|
|
|
profileBirthdayBanner.translationY = (offset / 2).toFloat()
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
val activity = activity as BaseActivity
|
|
|
|
|
|
|
|
|
|
|
|
val statusBarColor = sArgbEvaluator.evaluate(factor, 0xA0000000.toInt(),
|
2016-12-11 07:29:00 +01:00
|
|
|
ThemeUtils.computeDarkColor(primaryColorDark)) as Int
|
2016-06-29 15:47:52 +02:00
|
|
|
val window = activity.window
|
2016-12-11 07:29:00 +01:00
|
|
|
userFragmentView.setStatusBarColor(statusBarColor)
|
2016-06-29 15:47:52 +02:00
|
|
|
ThemeUtils.setLightStatusBar(window, ThemeUtils.isLightColor(statusBarColor))
|
2016-12-11 07:29:00 +01:00
|
|
|
val stackedTabColor = primaryColor
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
|
2016-07-02 06:05:23 +02:00
|
|
|
val profileContentHeight = (profileNameContainer!!.height + profileDetailsContainer.height).toFloat()
|
2016-06-29 15:47:52 +02:00
|
|
|
val tabOutlineAlphaFactor: Float
|
|
|
|
if (offset - spaceHeight > 0) {
|
2017-02-04 11:42:14 +01:00
|
|
|
tabOutlineAlphaFactor = 1f - ((offset - spaceHeight) / profileContentHeight).coerceIn(0f, 1f)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
|
|
|
tabOutlineAlphaFactor = 1f
|
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
actionBarBackground?.apply {
|
|
|
|
this.factor = factor
|
|
|
|
this.outlineAlphaFactor = tabOutlineAlphaFactor
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
2016-12-11 07:29:00 +01:00
|
|
|
windowOverlay.alpha = factor * tabOutlineAlphaFactor
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
val currentTabColor = sArgbEvaluator.evaluate(tabOutlineAlphaFactor,
|
2016-08-20 04:30:54 +02:00
|
|
|
stackedTabColor, cardBackgroundColor) as Int
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-07-02 06:05:23 +02:00
|
|
|
val tabBackground = toolbarTabs.background
|
2016-06-29 15:47:52 +02:00
|
|
|
(tabBackground as ColorDrawable).color = currentTabColor
|
|
|
|
val tabItemIsDark = ThemeUtils.isLightColor(currentTabColor)
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
if (previousTabItemIsDark == 0 || (if (tabItemIsDark) 1 else -1) != previousTabItemIsDark) {
|
2016-06-29 15:47:52 +02:00
|
|
|
val tabContrastColor = ThemeUtils.getColorDependent(currentTabColor)
|
2016-07-02 06:05:23 +02:00
|
|
|
toolbarTabs.setIconColor(tabContrastColor)
|
|
|
|
toolbarTabs.setLabelColor(tabContrastColor)
|
2016-12-18 06:21:24 +01:00
|
|
|
val theme = Chameleon.getOverrideTheme(activity, activity)
|
2016-12-18 03:32:11 +01:00
|
|
|
if (theme.isToolbarColored) {
|
2016-07-02 06:05:23 +02:00
|
|
|
toolbarTabs.setStripColor(tabContrastColor)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2016-12-18 03:32:11 +01:00
|
|
|
toolbarTabs.setStripColor(ThemeUtils.getOptimalAccentColor(uiColor, tabContrastColor))
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
toolbarTabs.updateAppearance()
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-12-11 07:29:00 +01:00
|
|
|
previousTabItemIsDark = if (tabItemIsDark) 1 else -1
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-08-20 04:30:54 +02:00
|
|
|
val currentActionBarColor = sArgbEvaluator.evaluate(factor, actionBarShadowColor,
|
2016-06-29 15:47:52 +02:00
|
|
|
stackedTabColor) as Int
|
|
|
|
val actionItemIsDark = ThemeUtils.isLightColor(currentActionBarColor)
|
2016-12-11 07:29:00 +01:00
|
|
|
if (previousActionBarItemIsDark == 0 || (if (actionItemIsDark) 1 else -1) != previousActionBarItemIsDark) {
|
2016-06-29 15:47:52 +02:00
|
|
|
ThemeUtils.applyToolbarItemColor(activity, toolbar, currentActionBarColor)
|
|
|
|
}
|
2016-12-11 07:29:00 +01:00
|
|
|
previousActionBarItemIsDark = if (actionItemIsDark) 1 else -1
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
updateTitleAlpha()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateTitleAlpha() {
|
|
|
|
val location = IntArray(2)
|
|
|
|
profileNameContainer.name.getLocationInWindow(location)
|
|
|
|
val nameShowingRatio = (userProfileDrawer.paddingTop - location[1]) / profileNameContainer.name.height.toFloat()
|
2017-02-04 11:42:14 +01:00
|
|
|
val textAlpha = nameShowingRatio.coerceIn(0f, 1f)
|
2016-06-29 15:47:52 +02:00
|
|
|
val titleView = ViewSupport.findViewByText(toolbar, toolbar.title)
|
|
|
|
if (titleView != null) {
|
|
|
|
titleView.alpha = textAlpha
|
|
|
|
}
|
|
|
|
val subtitleView = ViewSupport.findViewByText(toolbar, toolbar.subtitle)
|
|
|
|
if (subtitleView != null) {
|
|
|
|
subtitleView.alpha = textAlpha
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override var controlBarOffset: Float
|
2016-12-11 07:29:00 +01:00
|
|
|
get() = 0f
|
|
|
|
set(value) = Unit //Ignore
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
|
|
|
|
override val controlBarHeight: Int
|
2016-12-11 07:29:00 +01:00
|
|
|
get() = 0
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-08-19 16:25:27 +02:00
|
|
|
override val shouldInitLoader: Boolean
|
|
|
|
get() = user != null
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
private class ActionBarDrawable(shadow: Drawable) : LayerDrawable(arrayOf(shadow, ActionBarColorDrawable.create(true))) {
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
private val shadowDrawable: Drawable
|
|
|
|
private val colorDrawable: ColorDrawable
|
|
|
|
private var alphaValue: Int = 0
|
|
|
|
|
|
|
|
var factor: Float = 0f
|
|
|
|
set(value) {
|
|
|
|
field = value
|
|
|
|
updateValue()
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
var color: Int = 0
|
|
|
|
set(value) {
|
|
|
|
field = value
|
2016-12-11 07:29:00 +01:00
|
|
|
colorDrawable.color = value
|
|
|
|
updateValue()
|
|
|
|
}
|
|
|
|
|
|
|
|
var outlineAlphaFactor: Float = 0f
|
|
|
|
set(value) {
|
|
|
|
field = value
|
|
|
|
updateValue()
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
init {
|
2016-12-11 07:29:00 +01:00
|
|
|
shadowDrawable = getDrawable(0)
|
|
|
|
colorDrawable = getDrawable(1) as ColorDrawable
|
2016-06-29 15:47:52 +02:00
|
|
|
alpha = 0xFF
|
2016-12-11 07:29:00 +01:00
|
|
|
updateValue()
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun setAlpha(alpha: Int) {
|
|
|
|
alphaValue = alpha
|
|
|
|
updateValue()
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
override fun getAlpha(): Int {
|
|
|
|
return alphaValue
|
|
|
|
}
|
|
|
|
|
|
|
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
|
|
|
override fun getOutline(outline: Outline) {
|
|
|
|
colorDrawable.getOutline(outline)
|
|
|
|
outline.alpha = factor * outlineAlphaFactor * 0.99f
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getIntrinsicWidth(): Int {
|
2016-12-11 07:29:00 +01:00
|
|
|
return colorDrawable.intrinsicWidth
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun getIntrinsicHeight(): Int {
|
2016-12-11 07:29:00 +01:00
|
|
|
return colorDrawable.intrinsicHeight
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-12-11 07:29:00 +01:00
|
|
|
private fun updateValue() {
|
2017-02-04 11:42:14 +01:00
|
|
|
val shadowAlpha = Math.round(alpha * (1 - factor).coerceIn(0f, 1f))
|
2016-12-11 07:29:00 +01:00
|
|
|
shadowDrawable.alpha = shadowAlpha
|
2016-06-29 15:47:52 +02:00
|
|
|
val hasColor = color != 0
|
2017-02-04 11:42:14 +01:00
|
|
|
val colorAlpha = if (hasColor) Math.round(alpha * factor.coerceIn(0f, 1f)) else 0
|
2016-12-11 07:29:00 +01:00
|
|
|
colorDrawable.alpha = colorAlpha
|
2016-06-29 15:47:52 +02:00
|
|
|
invalidateSelf()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
internal class UserRelationshipLoader(
|
|
|
|
context: Context,
|
|
|
|
private val accountKey: UserKey?,
|
|
|
|
private val user: ParcelableUser?
|
2016-11-26 10:41:35 +01:00
|
|
|
) : AsyncTaskLoader<SingleResponse<ParcelableRelationship>>(context) {
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
override fun loadInBackground(): SingleResponse<ParcelableRelationship> {
|
2016-06-29 15:47:52 +02:00
|
|
|
if (accountKey == null || user == null) {
|
2016-11-26 10:41:35 +01:00
|
|
|
return SingleResponse.Companion.getInstance<ParcelableRelationship>(MicroBlogException("Null parameters"))
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
val userKey = user.key
|
|
|
|
val isFiltering = DataStoreUtils.isFilteringUser(context, userKey)
|
|
|
|
if (accountKey == user.key) {
|
2016-11-26 10:41:35 +01:00
|
|
|
return SingleResponse.getInstance(ParcelableRelationshipUtils.create(accountKey, userKey,
|
2016-06-29 15:47:52 +02:00
|
|
|
null, isFiltering))
|
|
|
|
}
|
2016-12-04 06:45:57 +01:00
|
|
|
val details = AccountUtils.getAccountDetails(AccountManager.get(context),
|
2016-12-15 06:11:32 +01:00
|
|
|
accountKey, true) ?: return SingleResponse.getInstance<ParcelableRelationship>(MicroBlogException("No Account"))
|
2016-12-04 06:45:57 +01:00
|
|
|
if (details.type == AccountType.TWITTER) {
|
2016-06-29 15:47:52 +02:00
|
|
|
if (!UserKeyUtils.isSameHost(accountKey, user.key)) {
|
2016-11-26 10:41:35 +01:00
|
|
|
return SingleResponse.getInstance(ParcelableRelationshipUtils.create(user, isFiltering))
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
2016-12-06 06:15:22 +01:00
|
|
|
val twitter = MicroBlogAPIFactory.getInstance(context, accountKey) ?: return SingleResponse.Companion.getInstance<ParcelableRelationship>(MicroBlogException("No Account"))
|
2016-06-29 15:47:52 +02:00
|
|
|
try {
|
|
|
|
val relationship = twitter.showFriendship(user.key.id)
|
|
|
|
if (relationship.isSourceBlockingTarget || relationship.isSourceBlockedByTarget) {
|
|
|
|
Utils.setLastSeen(context, userKey, -1)
|
|
|
|
} else {
|
|
|
|
Utils.setLastSeen(context, userKey, System.currentTimeMillis())
|
|
|
|
}
|
2016-11-26 10:41:35 +01:00
|
|
|
val data = ParcelableRelationshipUtils.create(accountKey, userKey, relationship,
|
|
|
|
isFiltering)
|
|
|
|
val resolver = context.contentResolver
|
|
|
|
val values = ParcelableRelationshipValuesCreator.create(data)
|
|
|
|
resolver.insert(CachedRelationships.CONTENT_URI, values)
|
|
|
|
return SingleResponse.getInstance(data)
|
2016-06-29 15:47:52 +02:00
|
|
|
} catch (e: MicroBlogException) {
|
2016-11-26 10:41:35 +01:00
|
|
|
return SingleResponse.Companion.getInstance<ParcelableRelationship>(e)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onStartLoading() {
|
|
|
|
forceLoad()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-26 10:41:35 +01:00
|
|
|
private fun ParcelableRelationship.check(user: ParcelableUser): Boolean {
|
|
|
|
if (account_key != user.account_key) {
|
|
|
|
return false
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-11-26 10:41:35 +01:00
|
|
|
return user.extras != null && TextUtils.equals(user_key.id, user.extras.unique_id) || TextUtils.equals(user_key.id, user.key.id)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2016-08-30 14:23:59 +02:00
|
|
|
class AddRemoveUserListDialogFragment : BaseDialogFragment() {
|
|
|
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
|
|
val lists = arguments.getParcelableArray(EXTRA_USER_LISTS).toTypedArray(ParcelableUserList.CREATOR)
|
|
|
|
val userKey = arguments.getParcelable<UserKey>(EXTRA_USER_KEY)
|
|
|
|
val accountKey = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val builder = AlertDialog.Builder(context)
|
|
|
|
builder.setTitle(R.string.add_or_remove_from_list)
|
|
|
|
val entries = Array(lists.size) { idx ->
|
|
|
|
lists[idx].name
|
|
|
|
}
|
|
|
|
val states = BooleanArray(lists.size) { idx ->
|
|
|
|
lists[idx].is_user_inside
|
|
|
|
}
|
|
|
|
builder.setPositiveButton(android.R.string.ok, null)
|
|
|
|
builder.setNeutralButton(R.string.new_user_list, null)
|
|
|
|
builder.setNegativeButton(android.R.string.cancel, null)
|
|
|
|
|
|
|
|
builder.setMultiChoiceItems(entries, states, null)
|
|
|
|
val dialog = builder.create()
|
|
|
|
dialog.setOnShowListener {
|
|
|
|
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
|
|
|
val checkedPositions = dialog.listView.checkedItemPositions
|
2017-01-07 12:34:42 +01:00
|
|
|
val weakActivity = WeakReference(activity)
|
2016-08-30 14:23:59 +02:00
|
|
|
promiseOnUi {
|
2017-01-07 12:34:42 +01:00
|
|
|
val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@promiseOnUi
|
|
|
|
activity.executeAfterFragmentResumed { activity ->
|
|
|
|
ProgressDialogFragment.show(activity.supportFragmentManager, "update_lists_progress")
|
2016-08-30 14:23:59 +02:00
|
|
|
}
|
|
|
|
}.then {
|
2017-01-07 12:34:42 +01:00
|
|
|
val activity = weakActivity.get() ?: throw IllegalStateException()
|
|
|
|
val twitter = MicroBlogAPIFactory.getInstance(activity, accountKey)
|
2016-08-30 14:23:59 +02:00
|
|
|
val successfulStates = SparseBooleanArray()
|
|
|
|
try {
|
|
|
|
for (i in 0 until checkedPositions.size()) {
|
|
|
|
val pos = checkedPositions.keyAt(i)
|
|
|
|
val checked = checkedPositions.valueAt(i)
|
|
|
|
if (states[pos] != checked) {
|
|
|
|
if (checked) {
|
|
|
|
twitter.addUserListMember(lists[pos].id, userKey.id)
|
|
|
|
} else {
|
|
|
|
twitter.deleteUserListMember(lists[pos].id, userKey.id)
|
|
|
|
}
|
|
|
|
successfulStates.put(pos, checked)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e: MicroBlogException) {
|
|
|
|
throw UpdateListsException(successfulStates)
|
|
|
|
}
|
|
|
|
}.alwaysUi {
|
2017-01-07 12:34:42 +01:00
|
|
|
val activity = weakActivity.get() as? IExtendedActivity<*> ?: return@alwaysUi
|
|
|
|
activity.executeAfterFragmentResumed { activity ->
|
|
|
|
val manager = activity.supportFragmentManager
|
|
|
|
val df = manager.findFragmentByTag("update_lists_progress") as? DialogFragment
|
2016-08-30 14:23:59 +02:00
|
|
|
df?.dismiss()
|
|
|
|
}
|
|
|
|
}.successUi {
|
|
|
|
dismiss()
|
|
|
|
}.failUi { e ->
|
|
|
|
if (e is UpdateListsException) {
|
|
|
|
val successfulStates = e.successfulStates
|
|
|
|
for (i in 0 until successfulStates.size()) {
|
|
|
|
val pos = successfulStates.keyAt(i)
|
|
|
|
val checked = successfulStates.valueAt(i)
|
|
|
|
dialog.listView.setItemChecked(pos, checked)
|
|
|
|
states[pos] = checked
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Utils.showErrorMessage(context, R.string.action_modifying_lists, e, false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener {
|
|
|
|
val df = CreateUserListDialogFragment()
|
|
|
|
df.arguments = Bundle {
|
|
|
|
this[EXTRA_ACCOUNT_KEY] = accountKey
|
|
|
|
}
|
|
|
|
df.show(fragmentManager, "create_user_list")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dialog
|
|
|
|
}
|
|
|
|
|
|
|
|
class UpdateListsException(val successfulStates: SparseBooleanArray) : MicroBlogException()
|
|
|
|
}
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
companion object {
|
|
|
|
|
|
|
|
private val sArgbEvaluator = ArgbEvaluator()
|
|
|
|
private val LOADER_ID_USER = 1
|
|
|
|
private val LOADER_ID_FRIENDSHIP = 2
|
|
|
|
|
|
|
|
private val TAB_POSITION_STATUSES = 0
|
|
|
|
private val TAB_POSITION_MEDIA = 1
|
|
|
|
private val TAB_POSITION_FAVORITES = 2
|
|
|
|
private val TAB_TYPE_STATUSES = "statuses"
|
|
|
|
private val TAB_TYPE_MEDIA = "media"
|
|
|
|
private val TAB_TYPE_FAVORITES = "favorites"
|
|
|
|
}
|
|
|
|
}
|