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
|
2017-04-13 05:18:12 +02:00
|
|
|
import android.annotation.SuppressLint
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-04-11 15:01:25 +02:00
|
|
|
import android.graphics.PorterDuff
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-04-07 09:21:56 +02:00
|
|
|
import android.support.annotation.ColorRes
|
|
|
|
import android.support.annotation.DrawableRes
|
|
|
|
import android.support.annotation.StringRes
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-04-07 09:21:56 +02:00
|
|
|
import android.support.v4.content.ContextCompat
|
2017-02-07 16:36:29 +01:00
|
|
|
import android.support.v4.content.FixedAsyncTaskLoader
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-03-27 16:10:42 +02:00
|
|
|
import android.text.Spanned
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-05-13 08:19:23 +02:00
|
|
|
import android.widget.TextView
|
2017-03-18 10:35:32 +01:00
|
|
|
import android.widget.Toast
|
2017-03-01 15:12:25 +01:00
|
|
|
import com.bumptech.glide.Glide
|
2016-06-29 15:47:52 +02:00
|
|
|
import com.squareup.otto.Subscribe
|
|
|
|
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.successUi
|
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-03-05 09:08:09 +01:00
|
|
|
import org.mariotaku.library.objectcursor.ObjectCursor
|
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
|
2017-04-22 09:18:44 +02:00
|
|
|
import org.mariotaku.microblog.library.mastodon.Mastodon
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-03-01 02:11:56 +01:00
|
|
|
import org.mariotaku.twidere.activity.iface.IBaseActivity
|
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
|
2017-03-21 03:33:27 +01:00
|
|
|
import org.mariotaku.twidere.constant.*
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
|
2017-04-20 14:04:37 +02:00
|
|
|
import org.mariotaku.twidere.extension.*
|
2017-04-22 09:18:44 +02:00
|
|
|
import org.mariotaku.twidere.extension.model.*
|
|
|
|
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
|
2017-04-21 12:01:54 +02:00
|
|
|
import org.mariotaku.twidere.extension.model.api.microblog.toParcelable
|
2016-08-19 16:25:27 +02:00
|
|
|
import org.mariotaku.twidere.fragment.AbsStatusesFragment.StatusesFragmentDelegate
|
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
|
2017-04-21 14:24:15 +02:00
|
|
|
import org.mariotaku.twidere.fragment.statuses.UserFavoritesFragment
|
|
|
|
import org.mariotaku.twidere.fragment.statuses.UserMediaTimelineFragment
|
|
|
|
import org.mariotaku.twidere.fragment.statuses.UserTimelineFragment
|
2016-06-29 15:47:52 +02:00
|
|
|
import org.mariotaku.twidere.graphic.ActionBarColorDrawable
|
|
|
|
import org.mariotaku.twidere.graphic.ActionIconDrawable
|
|
|
|
import org.mariotaku.twidere.loader.ParcelableUserLoader
|
|
|
|
import org.mariotaku.twidere.model.*
|
2017-02-09 09:00:12 +01:00
|
|
|
import org.mariotaku.twidere.model.event.FriendshipTaskEvent
|
|
|
|
import org.mariotaku.twidere.model.event.FriendshipUpdatedEvent
|
|
|
|
import org.mariotaku.twidere.model.event.ProfileUpdatedEvent
|
|
|
|
import org.mariotaku.twidere.model.event.TaskStateChangedEvent
|
2017-04-22 09:18:44 +02:00
|
|
|
import org.mariotaku.twidere.model.util.AccountUtils
|
|
|
|
import org.mariotaku.twidere.model.util.ParcelableMediaUtils
|
|
|
|
import org.mariotaku.twidere.model.util.ParcelableRelationshipUtils
|
2016-12-13 16:11:35 +01:00
|
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships
|
|
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers
|
2017-03-27 16:10:42 +02:00
|
|
|
import org.mariotaku.twidere.text.TwidereURLSpan
|
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
|
2017-06-11 15:49:05 +02:00
|
|
|
import org.mariotaku.twidere.view.TintedStatusFrameLayout
|
2016-06-29 15:47:52 +02:00
|
|
|
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,
|
2017-04-28 03:41:17 +02:00
|
|
|
IToolBarSupportFragment, StatusesFragmentDelegate,
|
2017-03-11 14:15:29 +01:00
|
|
|
AbsContentRecyclerViewFragment.RefreshCompleteListener {
|
2016-08-19 16:25:27 +02:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
override val toolbar: Toolbar
|
|
|
|
get() = profileContentContainer.toolbar
|
|
|
|
|
2017-02-19 15:29:08 +01:00
|
|
|
private lateinit var profileBirthdayBanner: View
|
|
|
|
private lateinit var actionBarBackground: ActionBarDrawable
|
2016-12-11 07:29:00 +01:00
|
|
|
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-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-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>>,
|
2017-02-15 07:48:10 +01:00
|
|
|
data: SingleResponse<ParcelableRelationship>) {
|
2016-12-11 07:29:00 +01:00
|
|
|
followProgress.visibility = View.GONE
|
2017-04-13 05:18:12 +02:00
|
|
|
displayRelationship(data.data)
|
2016-06-29 15:47:52 +02:00
|
|
|
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)
|
2017-04-12 14:58:08 +02:00
|
|
|
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
2017-04-12 14:58:08 +02:00
|
|
|
val loadFromCache = user == null || !user.is_cache && user.key.maybeEquals(userKey)
|
|
|
|
return ParcelableUserLoader(activity, accountKey, userKey, screenName, arguments,
|
2016-06-29 15:47:52 +02:00
|
|
|
omitIntentExtra, loadFromCache)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoaderReset(loader: Loader<SingleResponse<ParcelableUser>>) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onLoadFinished(loader: Loader<SingleResponse<ParcelableUser>>,
|
2017-02-15 07:48:10 +01:00
|
|
|
data: SingleResponse<ParcelableUser>) {
|
2016-06-29 15:47:52 +02:00
|
|
|
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()
|
2017-04-20 14:04:37 +02:00
|
|
|
} else if (user?.is_cache ?: false) {
|
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()) {
|
2017-04-20 14:04:37 +02:00
|
|
|
errorText.text = data.exception?.getErrorMessage(activity)
|
2016-08-19 16:25:27 +02:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateOptionsMenuVisibility() {
|
2016-08-20 04:30:54 +02:00
|
|
|
setHasOptionsMenu(user != null && relationship != null)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2017-04-13 05:18:12 +02:00
|
|
|
private fun displayRelationship(relationship: ParcelableRelationship?) {
|
|
|
|
val user = this.user ?: run {
|
|
|
|
this.relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
}
|
2017-04-13 05:18:12 +02:00
|
|
|
if (user.key.maybeEquals(user.account_key)) {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_edit, R.color.material_light_blue,
|
|
|
|
R.string.action_edit)
|
2016-06-29 15:47:52 +02:00
|
|
|
followContainer.follow.visibility = View.VISIBLE
|
2017-04-13 05:18:12 +02:00
|
|
|
this.relationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
}
|
2017-04-13 05:18:12 +02:00
|
|
|
if (relationship == null || !relationship.check(user)) {
|
|
|
|
this.relationship = null
|
2016-06-29 15:47:52 +02:00
|
|
|
return
|
|
|
|
} else {
|
2017-04-13 05:18:12 +02:00
|
|
|
this.relationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2016-11-30 08:18:43 +01:00
|
|
|
activity.invalidateOptionsMenu()
|
2017-04-13 05:18:12 +02:00
|
|
|
if (relationship.blocked_by) {
|
2016-12-11 07:29:00 +01:00
|
|
|
pagesErrorContainer.visibility = View.GONE
|
|
|
|
pagesErrorText.text = null
|
|
|
|
pagesContent.visibility = View.VISIBLE
|
2017-04-13 05:18:12 +02:00
|
|
|
} else if (!relationship.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
|
|
|
}
|
2017-04-13 05:18:12 +02:00
|
|
|
if (relationship.blocking) {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_block, R.color.material_red,
|
|
|
|
R.string.action_unblock)
|
2017-04-13 05:18:12 +02:00
|
|
|
} else if (relationship.blocked_by) {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_block, R.color.material_grey,
|
|
|
|
R.string.action_block)
|
2017-04-13 05:18:12 +02:00
|
|
|
} else if (relationship.following) {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_confirm, R.color.material_light_blue,
|
|
|
|
R.string.action_unfollow)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else if (user.is_follow_request_sent) {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_time, R.color.material_light_blue,
|
|
|
|
R.string.label_follow_request_sent)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-04-07 09:21:56 +02:00
|
|
|
setFollowEditButton(R.drawable.ic_action_add, android.R.color.white,
|
|
|
|
R.string.action_follow)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2017-04-13 05:18:12 +02:00
|
|
|
followingYouIndicator.visibility = if (relationship.followed_by) View.VISIBLE else View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-01-17 18:59:44 +01:00
|
|
|
val resolver = context.applicationContext.contentResolver
|
2016-11-26 08:14:32 +01:00
|
|
|
task {
|
2017-05-13 18:15:52 +02:00
|
|
|
resolver.insert(CachedUsers.CONTENT_URI, user, ParcelableUser::class.java)
|
|
|
|
resolver.insert(CachedRelationships.CONTENT_URI, relationship, ParcelableRelationship::class.java)
|
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()
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2017-05-13 08:19:23 +02:00
|
|
|
profileNameContainer.name.setText(bidiFormatter.unicodeWrap(when {
|
|
|
|
user.nickname.isNullOrEmpty() -> user.name
|
|
|
|
else -> getString(R.string.name_with_nickname, user.name, user.nickname)
|
|
|
|
}), TextView.BufferType.SPANNABLE)
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
|
|
|
}
|
2017-04-13 05:18:12 +02:00
|
|
|
@SuppressLint("SetTextI18n")
|
2017-05-13 08:19:23 +02:00
|
|
|
profileNameContainer.screenName.spannable = "@${user.acct}"
|
2017-03-27 16:10:42 +02:00
|
|
|
val linkHighlightOption = preferences[linkHighlightOptionKey]
|
|
|
|
val linkify = TwidereLinkify(this, linkHighlightOption)
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user.description_unescaped != null) {
|
2017-02-11 09:04:11 +01:00
|
|
|
val text = SpannableStringBuilder.valueOf(user.description_unescaped).apply {
|
|
|
|
user.description_spans?.applyTo(this)
|
|
|
|
linkify.applyAllLinks(this, user.account_key, false, false)
|
|
|
|
}
|
2017-05-13 08:19:23 +02:00
|
|
|
descriptionContainer.description.spannable = text
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-05-13 08:19:23 +02:00
|
|
|
descriptionContainer.description.spannable = user.description_plain
|
2016-06-29 15:47:52 +02:00
|
|
|
Linkify.addLinks(descriptionContainer.description, Linkify.WEB_URLS)
|
|
|
|
}
|
2017-05-13 08:19:23 +02:00
|
|
|
descriptionContainer.hideIfEmpty(descriptionContainer.description)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-05-13 08:19:23 +02:00
|
|
|
locationContainer.location.spannable = user.location
|
2017-03-27 16:10:42 +02:00
|
|
|
locationContainer.visibility = if (locationContainer.location.empty) View.GONE else View.VISIBLE
|
2017-05-13 08:19:23 +02:00
|
|
|
urlContainer.url.spannable = user.urlPreferred?.let {
|
2017-03-27 16:10:42 +02:00
|
|
|
val ssb = SpannableStringBuilder(it)
|
|
|
|
ssb.setSpan(TwidereURLSpan(it, highlightStyle = linkHighlightOption), 0, ssb.length,
|
|
|
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
|
|
|
return@let ssb
|
|
|
|
}
|
2017-05-13 08:19:23 +02:00
|
|
|
urlContainer.hideIfEmpty(urlContainer.url)
|
2017-02-25 05:06:04 +01:00
|
|
|
if (user.created_at >= 0) {
|
|
|
|
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.visibility = View.VISIBLE
|
|
|
|
createdAtContainer.createdAt.text = resources.getQuantityString(R.plurals.created_at_with_N_tweets_per_day, dailyTweets,
|
|
|
|
createdAt, dailyTweets)
|
|
|
|
} else {
|
|
|
|
createdAtContainer.visibility = View.GONE
|
|
|
|
}
|
2017-03-04 05:26:14 +01:00
|
|
|
val locale = Locale.getDefault()
|
|
|
|
|
2016-08-20 04:30:54 +02:00
|
|
|
listedContainer.listedCount.text = Utils.getLocalizedNumber(locale, user.listed_count)
|
2017-04-25 17:54:18 +02:00
|
|
|
groupsContainer.groupsCount.text = Utils.getLocalizedNumber(locale, user.groups_count)
|
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
|
2017-04-25 17:54:18 +02:00
|
|
|
groupsContainer.visibility = if (user.groups_count < 0) View.GONE else View.VISIBLE
|
2016-06-29 15:47:52 +02:00
|
|
|
|
|
|
|
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
|
2017-03-02 09:26:12 +01:00
|
|
|
val requestManager = Glide.with(this)
|
2017-03-02 13:42:53 +01:00
|
|
|
requestManager.loadProfileBanner(context, user, width).into(profileBanner)
|
2017-03-07 10:22:02 +01:00
|
|
|
requestManager.loadOriginalProfileImage(context, user, profileImage.style,
|
2017-04-12 08:12:45 +02:00
|
|
|
profileImage.cornerRadius, profileImage.cornerRadiusRatio)
|
|
|
|
.thumbnail(requestManager.loadProfileImage(context, user, profileImage.style,
|
|
|
|
profileImage.cornerRadius, profileImage.cornerRadiusRatio,
|
|
|
|
getString(R.string.profile_image_size))).into(profileImage)
|
2016-08-20 04:30:54 +02:00
|
|
|
val relationship = relationship
|
2016-06-29 15:47:52 +02:00
|
|
|
if (relationship == null) {
|
|
|
|
getFriendship()
|
|
|
|
}
|
2017-05-13 08:19:23 +02:00
|
|
|
activity.title = SpannableStringBuilder.valueOf(UserColorNameManager.decideDisplayName(user.nickname, user.name,
|
|
|
|
user.screen_name, nameFirst)).also {
|
|
|
|
externalThemeManager.emoji?.applyTo(it)
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-02-25 05:06:04 +01:00
|
|
|
val userCreationDay = condition@ if (user.created_at >= 0) {
|
|
|
|
val cal = Calendar.getInstance()
|
|
|
|
val currentMonth = cal.get(Calendar.MONTH)
|
|
|
|
val currentDay = cal.get(Calendar.DAY_OF_MONTH)
|
|
|
|
cal.timeInMillis = user.created_at
|
|
|
|
cal.get(Calendar.MONTH) == currentMonth && cal.get(Calendar.DAY_OF_MONTH) == currentDay
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
2017-02-19 15:29:08 +01:00
|
|
|
|
2017-02-25 05:06:04 +01:00
|
|
|
if (userCreationDay && !hideBirthdayView) {
|
2017-02-19 15:29:08 +01:00
|
|
|
if (profileBirthdayStub != null) {
|
|
|
|
profileBirthdayBanner = profileBirthdayStub.inflate()
|
|
|
|
profileBirthdayBanner.setOnClickListener(this)
|
|
|
|
} else {
|
|
|
|
profileBirthdayBanner.visibility = View.VISIBLE
|
|
|
|
}
|
|
|
|
} else if (profileBirthdayStub == null) {
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBirthdayBanner.visibility = View.GONE
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2017-04-05 07:12:01 +02:00
|
|
|
|
|
|
|
urlContainer.url.movementMethod = null
|
|
|
|
|
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?,
|
2017-02-15 07:48:10 +01:00
|
|
|
omitIntentExtra: Boolean) {
|
2016-06-29 15:47:52 +02:00
|
|
|
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)
|
2017-04-25 17:54:18 +02:00
|
|
|
var userKey = user.key
|
|
|
|
if (account?.type == AccountType.MASTODON && account?.key?.host != accountKey.host) {
|
2017-04-26 17:38:59 +02:00
|
|
|
userKey = AcctPlaceholderUserKey(user.key.host)
|
2017-04-25 17:54:18 +02:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
@Referral
|
|
|
|
val referral = arguments.getString(EXTRA_REFERRAL)
|
2017-04-25 17:54:18 +02:00
|
|
|
IntentUtils.openUserProfile(activity, accountKey, userKey, user.screen_name,
|
|
|
|
user.extras?.statusnet_profile_url, preferences[newDocumentApiKey],
|
2017-04-07 13:05:02 +02:00
|
|
|
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
|
2017-04-17 15:10:14 +02:00
|
|
|
nameFirst = preferences[nameFirstKey]
|
2016-08-20 04:30:54 +02:00
|
|
|
cardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity,
|
2017-03-21 03:33:27 +01:00
|
|
|
preferences[themeBackgroundOptionKey], preferences[themeBackgroundAlphaKey])
|
2016-08-20 04:30:54 +02:00
|
|
|
actionBarShadowColor = 0xA0000000.toInt()
|
2016-06-29 15:47:52 +02:00
|
|
|
val args = arguments
|
2017-04-12 14:58:08 +02:00
|
|
|
val accountKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY) ?: run {
|
|
|
|
activity.finish()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
val userKey = args.getParcelable<UserKey?>(EXTRA_USER_KEY)
|
|
|
|
val screenName = 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))))
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-06-11 15:49:05 +02:00
|
|
|
userFragmentView.windowInsetsListener = object : TintedStatusFrameLayout.WindowInsetsListener {
|
|
|
|
override fun onApplyWindowInsets(left: Int, top: Int, right: Int, bottom: Int) {
|
|
|
|
profileContentContainer.setPadding(0, top, 0, 0)
|
|
|
|
profileBannerSpace.statusBarHeight = top
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-06-11 15:49:05 +02:00
|
|
|
if (profileBannerSpace.toolbarHeight == 0) {
|
|
|
|
var toolbarHeight = toolbar.measuredHeight
|
|
|
|
if (toolbarHeight == 0) {
|
|
|
|
toolbarHeight = ThemeUtils.getActionBarHeight(context)
|
|
|
|
}
|
|
|
|
profileBannerSpace.toolbarHeight = toolbarHeight
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-11 15:49:05 +02:00
|
|
|
|
|
|
|
profileContentContainer.onSizeChangedListener = object : OnSizeChangedListener {
|
|
|
|
override fun onSizeChanged(view: View, w: Int, h: Int, oldw: Int, oldh: Int) {
|
|
|
|
val toolbarHeight = toolbar.measuredHeight
|
|
|
|
userProfileDrawer.setPadding(0, toolbarHeight, 0, 0)
|
|
|
|
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)
|
2017-04-05 07:12:01 +02:00
|
|
|
urlContainer.setOnClickListener(this)
|
2017-06-11 15:49:05 +02:00
|
|
|
profileBanner.onSizeChangedListener = this
|
2016-07-02 06:05:23 +02:00
|
|
|
profileBannerSpace.setOnTouchListener(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-03-11 14:15:29 +01:00
|
|
|
userProfileSwipeLayout.setOnRefreshListener {
|
|
|
|
if (!triggerRefresh()) {
|
|
|
|
userProfileSwipeLayout.isRefreshing = false
|
|
|
|
}
|
|
|
|
}
|
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)
|
|
|
|
|
2017-02-19 15:29:08 +01:00
|
|
|
actionBarBackground = ActionBarDrawable(ResourcesCompat.getDrawable(activity.resources,
|
|
|
|
R.drawable.shadow_user_banner_action_bar, null)!!)
|
2016-06-29 15:47:52 +02:00
|
|
|
setupBaseActionBar()
|
2017-01-07 15:45:33 +01:00
|
|
|
setupViewStyle()
|
2016-06-29 15:47:52 +02:00
|
|
|
setupUserPages()
|
|
|
|
|
2017-04-12 14:58:08 +02:00
|
|
|
getUserInfo(accountKey, userKey, screenName, false)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
override fun onStart() {
|
|
|
|
super.onStart()
|
|
|
|
bus.register(this)
|
2017-04-14 17:03:58 +02:00
|
|
|
userColorNameManager.registerColorChangedListener(this)
|
|
|
|
userColorNameManager.registerNicknameChangedListener(this)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2017-04-13 05:18:12 +02:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
override fun onStop() {
|
2017-04-14 17:03:58 +02:00
|
|
|
userColorNameManager.unregisterColorChangedListener(this)
|
|
|
|
userColorNameManager.unregisterNicknameChangedListener(this)
|
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) {
|
2017-03-19 06:47:27 +01:00
|
|
|
val user = this.user ?: return
|
2016-11-26 09:13:00 +01:00
|
|
|
val account = this.account
|
2017-03-19 06:47:27 +01:00
|
|
|
val relationship = this.relationship
|
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)
|
|
|
|
}
|
2017-04-12 10:17:20 +02:00
|
|
|
menu.setItemAvailability(R.id.mention, !isMyself)
|
|
|
|
menu.setItemAvailability(R.id.incoming_friendships, isMyself)
|
|
|
|
menu.setItemAvailability(R.id.saved_searches, isMyself)
|
2016-07-04 03:31:17 +02:00
|
|
|
|
2017-04-12 10:17:20 +02:00
|
|
|
menu.setItemAvailability(R.id.blocked_users, isMyself)
|
|
|
|
menu.setItemAvailability(R.id.block, !isMyself)
|
2016-11-26 09:13:00 +01:00
|
|
|
|
2017-04-22 09:27:05 +02:00
|
|
|
var canAddToList = false
|
|
|
|
var canMute = false
|
|
|
|
var canReportSpam = false
|
|
|
|
var canEnableRetweet = false
|
|
|
|
var canEnableNotifications = false
|
|
|
|
when (account?.type) {
|
|
|
|
AccountType.TWITTER -> {
|
|
|
|
canAddToList = true
|
|
|
|
canMute = true
|
|
|
|
canReportSpam = true
|
|
|
|
canEnableRetweet = true
|
|
|
|
canEnableNotifications = true
|
|
|
|
}
|
|
|
|
AccountType.MASTODON -> {
|
|
|
|
canMute = true
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2017-04-22 09:27:05 +02:00
|
|
|
menu.setItemAvailability(R.id.add_to_list, canAddToList)
|
|
|
|
menu.setItemAvailability(R.id.mute_user, !isMyself && canMute)
|
|
|
|
menu.setItemAvailability(R.id.muted_users, isMyself && canMute)
|
|
|
|
menu.setItemAvailability(R.id.report_spam, !isMyself && canReportSpam)
|
|
|
|
menu.setItemAvailability(R.id.enable_retweets, !isMyself && canEnableRetweet)
|
2016-11-26 09:13:00 +01:00
|
|
|
|
2017-03-19 06:47:27 +01:00
|
|
|
if (relationship != null) {
|
|
|
|
menu.findItem(R.id.add_to_filter)?.apply {
|
|
|
|
isChecked = relationship.filtering
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2017-03-19 06:47:27 +01:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
if (isMyself) {
|
2017-04-12 10:17:20 +02:00
|
|
|
menu.setItemAvailability(R.id.send_direct_message, false)
|
|
|
|
menu.setItemAvailability(R.id.enable_notifications, false)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-04-12 10:17:20 +02:00
|
|
|
menu.setItemAvailability(R.id.send_direct_message, relationship.can_dm)
|
|
|
|
menu.setItemAvailability(R.id.block, true)
|
2017-04-22 09:27:05 +02:00
|
|
|
menu.setItemAvailability(R.id.enable_notifications, canEnableNotifications &&
|
|
|
|
relationship.following)
|
2017-03-19 06:47:27 +01:00
|
|
|
|
|
|
|
menu.findItem(R.id.block)?.apply {
|
|
|
|
ActionIconDrawable.setMenuHighlight(this, TwidereMenuInfo(relationship.blocking))
|
|
|
|
this.setTitle(if (relationship.blocking) R.string.action_unblock else R.string.action_block)
|
|
|
|
}
|
|
|
|
menu.findItem(R.id.mute_user)?.apply {
|
|
|
|
isChecked = relationship.muting
|
|
|
|
}
|
|
|
|
menu.findItem(R.id.enable_retweets)?.apply {
|
|
|
|
isChecked = relationship.retweet_enabled
|
|
|
|
}
|
|
|
|
menu.findItem(R.id.enable_notifications)?.apply {
|
|
|
|
isChecked = relationship.notifications_enabled
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
2017-03-19 06:47:27 +01:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-04-12 10:17:20 +02:00
|
|
|
menu.setItemAvailability(R.id.send_direct_message, false)
|
|
|
|
menu.setItemAvailability(R.id.enable_notifications, 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 -> {
|
2017-04-21 14:24:15 +02:00
|
|
|
ReportUserSpamDialogFragment.show(fragmentManager, user)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
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-04-20 14:04:37 +02:00
|
|
|
Toast.makeText(activity, R.string.message_toast_user_filters_removed,
|
|
|
|
Toast.LENGTH_SHORT).show()
|
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 -> {
|
2017-04-09 08:15:01 +02:00
|
|
|
val am = AccountManager.get(activity)
|
|
|
|
val builder = Uri.Builder().apply {
|
|
|
|
scheme(SCHEME_TWIDERE)
|
|
|
|
authority(AUTHORITY_MESSAGES)
|
|
|
|
path(PATH_MESSAGES_CONVERSATION_NEW)
|
|
|
|
appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, user.account_key.toString())
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
val intent = Intent(Intent.ACTION_VIEW, builder.build())
|
2017-04-09 08:15:01 +02:00
|
|
|
intent.putExtra(EXTRA_ACCOUNT, AccountUtils.getAccountDetails(am, user.account_key,
|
|
|
|
true))
|
|
|
|
intent.putExtra(EXTRA_USERS, arrayOf(user))
|
2017-04-24 02:12:37 +02:00
|
|
|
intent.putExtra(EXTRA_OPEN_CONVERSATION, true)
|
2016-06-29 15:47:52 +02:00
|
|
|
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 -> {
|
2017-04-20 14:04:37 +02:00
|
|
|
showAddToListDialog(user)
|
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)
|
2017-04-25 17:54:18 +02:00
|
|
|
when (account?.type) {
|
|
|
|
AccountType.MASTODON -> intent.putExtra(EXTRA_ACCOUNT_TYPE, AccountType.MASTODON)
|
|
|
|
else -> intent.putExtra(EXTRA_ACCOUNT_HOST, user.key.host)
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
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 {
|
2017-04-22 09:27:05 +02:00
|
|
|
twitter.createFriendshipAsync(user.account_key, user.key, user.screen_name)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
2017-03-18 10:35:32 +01:00
|
|
|
R.id.enable_notifications -> {
|
|
|
|
val newState = !item.isChecked
|
|
|
|
if (newState) {
|
|
|
|
Toast.makeText(context, R.string.message_toast_notification_enabled_hint,
|
|
|
|
Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
val update = FriendshipUpdate()
|
|
|
|
update.deviceNotifications(newState)
|
|
|
|
twitter.updateFriendship(user.account_key, user.key, update)
|
|
|
|
item.isChecked = newState
|
|
|
|
return true
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
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.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)
|
|
|
|
}
|
2017-04-03 16:55:41 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
R.id.qr_code -> {
|
|
|
|
executeAfterFragmentResumed {
|
2017-04-10 08:13:33 +02:00
|
|
|
val df = UserQrDialogFragment()
|
2017-04-03 16:55:41 +02:00
|
|
|
df.arguments = Bundle {
|
|
|
|
this[EXTRA_USER] = user
|
|
|
|
}
|
|
|
|
df.show(it.childFragmentManager, "user_qr_code")
|
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
val intent = item.intent
|
|
|
|
if (intent != null && intent.resolveActivity(context.packageManager) != null) {
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2017-04-20 14:04:37 +02:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
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,
|
2017-02-15 07:48:10 +01:00
|
|
|
keyCode: Int, repeatCount: Int,
|
|
|
|
event: KeyEvent, metaState: Int): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
return handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
|
|
}
|
|
|
|
|
2017-04-13 05:18:12 +02:00
|
|
|
private fun updateSubtitle() {
|
|
|
|
val activity = activity as AppCompatActivity
|
|
|
|
val actionBar = activity.supportActionBar ?: return
|
|
|
|
val user = this.user
|
|
|
|
if (user == null) {
|
|
|
|
actionBar.subtitle = null
|
|
|
|
return
|
|
|
|
}
|
|
|
|
val spec = pagerAdapter.get(viewPager.currentItem)
|
|
|
|
assert(spec.type != null)
|
|
|
|
when (spec.type) {
|
|
|
|
TAB_TYPE_STATUSES, TAB_TYPE_STATUSES_WITH_REPLIES -> {
|
|
|
|
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 -> {
|
2017-04-19 12:59:39 +02:00
|
|
|
if (user.favorites_count < 0) {
|
|
|
|
if (preferences[iWantMyStarsBackKey]) {
|
|
|
|
actionBar.setSubtitle(R.string.title_favorites)
|
|
|
|
} else {
|
|
|
|
actionBar.setSubtitle(R.string.title_likes)
|
|
|
|
}
|
|
|
|
} else if (preferences[iWantMyStarsBackKey]) {
|
2017-04-13 05:18:12 +02:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
private fun handleFragmentKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler,
|
2017-02-15 07:48:10 +01:00
|
|
|
keyCode: Int, repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
val fragment = keyboardShortcutRecipient
|
|
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
|
|
return fragment.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleFragmentKeyboardShortcutSingle(handler: KeyboardShortcutsHandler,
|
2017-02-15 07:48:10 +01:00
|
|
|
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
val fragment = keyboardShortcutRecipient
|
|
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
|
|
return fragment.handleKeyboardShortcutSingle(handler, keyCode, event, metaState)
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun isFragmentKeyboardShortcutHandled(handler: KeyboardShortcutsHandler,
|
2017-02-15 07:48:10 +01:00
|
|
|
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
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 {
|
2017-04-22 09:27:05 +02:00
|
|
|
twitter.createFriendshipAsync(user.account_key, user.key, user.screen_name)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-02 06:05:23 +02:00
|
|
|
R.id.profileImage -> {
|
2017-04-10 13:11:49 +02:00
|
|
|
val url = user.originalProfileImage ?: return
|
2016-06-29 15:47:52 +02:00
|
|
|
val profileImage = ParcelableMediaUtils.image(url)
|
|
|
|
profileImage.type = ParcelableMedia.Type.IMAGE
|
2017-04-12 08:12:45 +02:00
|
|
|
profileImage.preview_url = user.profile_image_url
|
2016-06-29 15:47:52 +02:00
|
|
|
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 -> {
|
2017-04-16 15:09:56 +02:00
|
|
|
val url = user.getBestProfileBanner(0) ?: return
|
2016-06-29 15:47:52 +02:00
|
|
|
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)
|
|
|
|
}
|
2017-04-05 07:12:01 +02:00
|
|
|
R.id.urlContainer -> {
|
2017-04-15 10:18:01 +02:00
|
|
|
val uri = user.urlPreferred?.let(Uri::parse) ?: return
|
|
|
|
OnLinkClickHandler.openLink(context, preferences, uri)
|
2017-04-05 07:12:01 +02:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
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?,
|
2017-02-15 07:48:10 +01:00
|
|
|
extraId: Long, type: Int, sensitive: Boolean,
|
|
|
|
start: Int, end: Int): Boolean {
|
2016-06-29 15:47:52 +02:00
|
|
|
val user = user ?: return false
|
|
|
|
when (type) {
|
|
|
|
TwidereLinkify.LINK_TYPE_MENTION -> {
|
2017-04-07 13:05:02 +02:00
|
|
|
IntentUtils.openUserProfile(activity, user.account_key, null, link, null,
|
|
|
|
preferences[newDocumentApiKey], 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
|
|
|
|
}
|
|
|
|
|
2017-04-14 16:34:43 +02:00
|
|
|
override fun onUserNicknameChanged(userKey: UserKey, nick: String?) {
|
2017-04-12 14:58:08 +02:00
|
|
|
if (user?.key != userKey) return
|
2016-07-26 08:51:43 +02:00
|
|
|
displayUser(user, account)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
2017-04-12 14:58:08 +02:00
|
|
|
override fun onUserColorChanged(userKey: UserKey, color: Int) {
|
|
|
|
if (user?.key != userKey) 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 {
|
2017-02-19 15:29:08 +01:00
|
|
|
if (profileBirthdayStub == null && profileBirthdayBanner.visibility == View.VISIBLE) {
|
2016-07-02 06:05:23 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-03-11 14:15:29 +01:00
|
|
|
override fun onRefreshComplete(fragment: AbsContentRecyclerViewFragment<*, *>) {
|
|
|
|
userProfileSwipeLayout.isRefreshing = false
|
|
|
|
}
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
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) {
|
2017-04-20 07:28:57 +02:00
|
|
|
val theme = Chameleon.getOverrideTheme(activity, activity)
|
|
|
|
uiColor = if (color != 0) color else theme.colorPrimary
|
2016-12-11 07:29:00 +01:00
|
|
|
previousActionBarItemIsDark = 0
|
|
|
|
previousTabItemIsDark = 0
|
2017-03-04 05:26:14 +01:00
|
|
|
setupBaseActionBar()
|
2016-06-29 15:47:52 +02:00
|
|
|
val activity = activity as BaseActivity
|
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)
|
2017-03-04 05:26:14 +01:00
|
|
|
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
|
|
|
}
|
2017-04-14 17:03:58 +02:00
|
|
|
val user = this.user
|
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
|
|
|
|
if (!ThemeUtils.isWindowFloating(activity) && ThemeUtils.isTransparentBackground(activity.currentThemeBackgroundOption)) {
|
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)
|
2017-03-27 15:56:03 +02:00
|
|
|
val userKey: UserKey?
|
2016-06-29 15:47:52 +02:00
|
|
|
if (user != null) {
|
2017-03-27 15:56:03 +02:00
|
|
|
userKey = user.account_key
|
|
|
|
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userKey)
|
2016-06-29 15:47:52 +02:00
|
|
|
tabArgs.putParcelable(EXTRA_USER_KEY, user.key)
|
|
|
|
tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name)
|
2017-04-07 13:05:02 +02:00
|
|
|
tabArgs.putString(EXTRA_PROFILE_URL, user.extras?.statusnet_profile_url)
|
2016-06-29 15:47:52 +02:00
|
|
|
} else {
|
2017-04-12 14:58:08 +02:00
|
|
|
userKey = args.getParcelable<UserKey?>(EXTRA_ACCOUNT_KEY)
|
2017-03-27 15:56:03 +02:00
|
|
|
tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userKey)
|
2016-06-29 15:47:52 +02:00
|
|
|
tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable<Parcelable>(EXTRA_USER_KEY))
|
|
|
|
tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME))
|
2017-04-07 13:05:02 +02:00
|
|
|
tabArgs.putString(EXTRA_PROFILE_URL, args.getString(EXTRA_PROFILE_URL))
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
2017-03-31 10:05:50 +02:00
|
|
|
pagerAdapter.add(cls = UserTimelineFragment::class.java, args = Bundle(tabArgs).apply {
|
|
|
|
this[UserTimelineFragment.EXTRA_ENABLE_TIMELINE_FILTER] = true
|
2017-04-28 03:41:17 +02:00
|
|
|
this[UserTimelineFragment.EXTRA_LOAD_PINNED_STATUS] = true
|
2017-03-31 10:05:50 +02:00
|
|
|
}, name = getString(R.string.title_statuses), type = TAB_TYPE_STATUSES,
|
|
|
|
position = TAB_POSITION_STATUSES)
|
2017-03-27 05:08:09 +02:00
|
|
|
pagerAdapter.add(cls = UserMediaTimelineFragment::class.java, args = tabArgs,
|
2017-03-31 10:05:50 +02:00
|
|
|
name = getString(R.string.media), type = TAB_TYPE_MEDIA, position = TAB_POSITION_MEDIA)
|
2017-04-19 13:30:07 +02:00
|
|
|
if (account?.type != AccountType.MASTODON || account?.key == userKey) {
|
|
|
|
if (preferences[iWantMyStarsBackKey]) {
|
|
|
|
pagerAdapter.add(cls = UserFavoritesFragment::class.java, args = tabArgs,
|
|
|
|
name = getString(R.string.title_favorites), type = TAB_TYPE_FAVORITES,
|
|
|
|
position = TAB_POSITION_FAVORITES)
|
|
|
|
} else {
|
|
|
|
pagerAdapter.add(cls = UserFavoritesFragment::class.java, args = tabArgs,
|
|
|
|
name = getString(R.string.title_likes), 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()
|
2017-02-19 15:29:08 +01:00
|
|
|
if (profileBirthdayStub == null) {
|
|
|
|
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(),
|
2017-04-15 10:42:50 +02:00
|
|
|
ChameleonUtils.darkenColor(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)
|
2017-04-15 10:18:01 +02:00
|
|
|
WindowSupport.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
|
|
|
|
}
|
|
|
|
|
2017-03-04 05:26:14 +01:00
|
|
|
actionBarBackground.apply {
|
2016-12-11 07:29:00 +01:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:21:56 +02:00
|
|
|
override var controlBarOffset: Float
|
|
|
|
get() = 0f
|
|
|
|
set(value) = Unit //Ignore
|
|
|
|
|
|
|
|
override val controlBarHeight: Int
|
|
|
|
get() = 0
|
|
|
|
|
|
|
|
|
|
|
|
override val shouldInitLoader: Boolean
|
|
|
|
get() = user != null
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:21:56 +02:00
|
|
|
private fun ParcelableRelationship.check(user: ParcelableUser): Boolean {
|
|
|
|
if (account_key != user.account_key) {
|
|
|
|
return false
|
|
|
|
}
|
2017-04-25 17:54:18 +02:00
|
|
|
return user_key.id == user.extras?.unique_id || user_key.id == user.key.id
|
2017-04-07 09:21:56 +02:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-04-07 09:21:56 +02:00
|
|
|
private fun setFollowEditButton(@DrawableRes icon: Int, @ColorRes color: Int, @StringRes label: Int) {
|
2017-04-11 15:01:25 +02:00
|
|
|
val followButton = followContainer.follow
|
|
|
|
followButton.setImageResource(icon)
|
|
|
|
ViewCompat.setBackgroundTintMode(followButton, PorterDuff.Mode.SRC_ATOP)
|
|
|
|
ViewCompat.setBackgroundTintList(followButton, ContextCompat.getColorStateList(context, color))
|
|
|
|
followButton.contentDescription = getString(label)
|
2017-04-07 09:21:56 +02:00
|
|
|
}
|
2016-06-29 15:47:52 +02:00
|
|
|
|
2017-04-20 14:04:37 +02:00
|
|
|
private fun showAddToListDialog(user: ParcelableUser) {
|
|
|
|
val weakThis = WeakReference(this)
|
|
|
|
executeAfterFragmentResumed {
|
|
|
|
ProgressDialogFragment.show(it.childFragmentManager, "get_list_progress")
|
|
|
|
}.then {
|
|
|
|
val fragment = weakThis.get() ?: throw InterruptedException()
|
|
|
|
fun MicroBlog.getUserListOwnerMemberships(id: String): ArrayList<UserList> {
|
|
|
|
val result = ArrayList<UserList>()
|
|
|
|
var nextCursor: Long
|
|
|
|
val paging = Paging()
|
|
|
|
paging.count(100)
|
|
|
|
do {
|
|
|
|
val resp = getUserListMemberships(id, paging, true)
|
|
|
|
result.addAll(resp)
|
|
|
|
nextCursor = resp.nextCursor
|
|
|
|
paging.cursor(nextCursor)
|
|
|
|
} while (nextCursor > 0)
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
val microBlog = MicroBlogAPIFactory.getInstance(fragment.context, user.account_key)
|
|
|
|
val ownedLists = ArrayList<ParcelableUserList>()
|
|
|
|
val listMemberships = microBlog.getUserListOwnerMemberships(user.key.id)
|
|
|
|
val paging = Paging()
|
|
|
|
paging.count(100)
|
|
|
|
var nextCursor: Long
|
|
|
|
do {
|
|
|
|
val resp = microBlog.getUserListOwnerships(paging)
|
|
|
|
resp.mapTo(ownedLists) { item ->
|
2017-04-21 12:01:54 +02:00
|
|
|
val userList = item.toParcelable( user.account_key)
|
2017-04-20 14:04:37 +02:00
|
|
|
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()
|
|
|
|
}.alwaysUi {
|
|
|
|
val fragment = weakThis.get() ?: return@alwaysUi
|
|
|
|
fragment.executeAfterFragmentResumed {
|
|
|
|
it.childFragmentManager.dismissDialogFragment("get_list_progress")
|
|
|
|
}
|
|
|
|
}.successUi { result ->
|
|
|
|
val fragment = weakThis.get() ?: return@successUi
|
|
|
|
fragment.executeAfterFragmentResumed { fragment ->
|
|
|
|
val df = AddRemoveUserListDialogFragment()
|
|
|
|
df.arguments = Bundle {
|
|
|
|
this[EXTRA_ACCOUNT_KEY] = user.account_key
|
|
|
|
this[EXTRA_USER_KEY] = user.key
|
|
|
|
this[EXTRA_USER_LISTS] = result
|
|
|
|
}
|
|
|
|
df.show(fragment.childFragmentManager, "add_remove_list")
|
|
|
|
}
|
|
|
|
}.failUi {
|
|
|
|
val fragment = weakThis.get() ?: return@failUi
|
|
|
|
Toast.makeText(fragment.context, it.getErrorMessage(fragment.context),
|
|
|
|
Toast.LENGTH_SHORT).show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
private class ActionBarDrawable(shadow: Drawable) : LayerDrawable(arrayOf(shadow, ActionBarColorDrawable.create(true))) {
|
|
|
|
|
2017-02-19 15:29:08 +01:00
|
|
|
private val shadowDrawable = getDrawable(0)
|
|
|
|
private val colorDrawable = getDrawable(1) as ColorDrawable
|
2016-12-11 07:29:00 +01:00
|
|
|
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 {
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:21:56 +02:00
|
|
|
|
2016-06-29 15:47:52 +02:00
|
|
|
internal class UserRelationshipLoader(
|
|
|
|
context: Context,
|
|
|
|
private val accountKey: UserKey?,
|
|
|
|
private val user: ParcelableUser?
|
2017-02-07 16:36:29 +01:00
|
|
|
) : FixedAsyncTaskLoader<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) {
|
2017-04-22 09:18:44 +02:00
|
|
|
return SingleResponse(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) {
|
2017-04-22 09:18:44 +02:00
|
|
|
return SingleResponse(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),
|
2017-04-22 09:18:44 +02:00
|
|
|
accountKey, true) ?: return SingleResponse(MicroBlogException("No Account"))
|
2016-12-04 06:45:57 +01:00
|
|
|
if (details.type == AccountType.TWITTER) {
|
2017-05-03 15:42:05 +02:00
|
|
|
if (!accountKey.hasSameHost(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
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
2017-04-22 09:18:44 +02:00
|
|
|
val data = when (details.type) {
|
|
|
|
AccountType.MASTODON -> {
|
|
|
|
val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java)
|
|
|
|
mastodon.getRelationships(arrayOf(userKey.id))?.firstOrNull()
|
|
|
|
?.toParcelable(accountKey, userKey, isFiltering)
|
|
|
|
?: throw MicroBlogException("No relationship")
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
val microBlog = details.newMicroBlogInstance(context, MicroBlog::class.java)
|
|
|
|
microBlog.showFriendship(user.key.id).toParcelable(accountKey, userKey,
|
|
|
|
isFiltering)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.blocking || data.blocked_by) {
|
2016-06-29 15:47:52 +02:00
|
|
|
Utils.setLastSeen(context, userKey, -1)
|
|
|
|
} else {
|
|
|
|
Utils.setLastSeen(context, userKey, System.currentTimeMillis())
|
|
|
|
}
|
2016-11-26 10:41:35 +01:00
|
|
|
val resolver = context.contentResolver
|
2017-03-05 09:08:09 +01:00
|
|
|
val values = ObjectCursor.valuesCreatorFrom(ParcelableRelationship::class.java).create(data)
|
2016-11-26 10:41:35 +01:00
|
|
|
resolver.insert(CachedRelationships.CONTENT_URI, values)
|
2017-04-22 09:18:44 +02:00
|
|
|
return SingleResponse(data)
|
2016-06-29 15:47:52 +02:00
|
|
|
} catch (e: MicroBlogException) {
|
2017-04-22 09:18:44 +02:00
|
|
|
return SingleResponse(e)
|
2016-06-29 15:47:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onStartLoading() {
|
|
|
|
forceLoad()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-30 14:23:59 +02:00
|
|
|
class AddRemoveUserListDialogFragment : BaseDialogFragment() {
|
2017-04-12 14:58:08 +02:00
|
|
|
|
2016-08-30 14:23:59 +02:00
|
|
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
2017-05-24 07:34:33 +02:00
|
|
|
val lists = arguments.getTypedArray<ParcelableUserList>(EXTRA_USER_LISTS)
|
2016-08-30 14:23:59 +02:00
|
|
|
val userKey = arguments.getParcelable<UserKey>(EXTRA_USER_KEY)
|
|
|
|
val accountKey = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
|
|
|
val builder = AlertDialog.Builder(context)
|
2017-02-18 17:51:11 +01:00
|
|
|
builder.setTitle(R.string.title_add_or_remove_from_list)
|
2016-08-30 14:23:59 +02:00
|
|
|
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()
|
2017-02-05 14:42:20 +01:00
|
|
|
dialog.setOnShowListener { dialog ->
|
|
|
|
dialog as AlertDialog
|
|
|
|
dialog.applyTheme()
|
2016-08-30 14:23:59 +02:00
|
|
|
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
|
|
|
val checkedPositions = dialog.listView.checkedItemPositions
|
2017-01-07 12:34:42 +01:00
|
|
|
val weakActivity = WeakReference(activity)
|
2017-03-22 13:00:29 +01:00
|
|
|
(activity as IBaseActivity<*>).executeAfterFragmentResumed {
|
|
|
|
ProgressDialogFragment.show(it.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) {
|
2017-05-18 05:08:50 +02:00
|
|
|
throw UpdateListsException(e, successfulStates)
|
2016-08-30 14:23:59 +02:00
|
|
|
}
|
|
|
|
}.alwaysUi {
|
2017-03-01 02:11:56 +01:00
|
|
|
val activity = weakActivity.get() as? IBaseActivity<*> ?: return@alwaysUi
|
2017-01-07 12:34:42 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2017-04-20 19:23:11 +02:00
|
|
|
Toast.makeText(context, e.getErrorMessage(context), Toast.LENGTH_SHORT).show()
|
2016-08-30 14:23:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-05-18 05:08:50 +02:00
|
|
|
class UpdateListsException(cause: Throwable, val successfulStates: SparseBooleanArray) : MicroBlogException(cause)
|
2016-08-30 14:23:59 +02:00
|
|
|
}
|
|
|
|
|
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"
|
2017-03-27 05:08:09 +02:00
|
|
|
private val TAB_TYPE_STATUSES_WITH_REPLIES = "statuses_with_replies"
|
2016-06-29 15:47:52 +02:00
|
|
|
private val TAB_TYPE_MEDIA = "media"
|
|
|
|
private val TAB_TYPE_FAVORITES = "favorites"
|
|
|
|
}
|
|
|
|
}
|