1103 lines
45 KiB
Kotlin
1103 lines
45 KiB
Kotlin
/*
|
|
* 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.activity
|
|
|
|
import android.accounts.Account
|
|
import android.accounts.AccountManager
|
|
import android.accounts.OnAccountsUpdateListener
|
|
import android.annotation.SuppressLint
|
|
import android.app.Dialog
|
|
import android.app.PendingIntent
|
|
import android.app.SearchManager
|
|
import android.content.Context
|
|
import android.content.DialogInterface
|
|
import android.content.Intent
|
|
import android.content.SharedPreferences
|
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
|
import android.content.res.Configuration
|
|
import android.graphics.Rect
|
|
import android.graphics.drawable.Drawable
|
|
import android.os.AsyncTask
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.util.SparseIntArray
|
|
import android.view.Gravity
|
|
import android.view.KeyEvent
|
|
import android.view.MenuItem
|
|
import android.view.View
|
|
import android.view.View.OnClickListener
|
|
import android.view.View.OnLongClickListener
|
|
import android.view.ViewGroup.MarginLayoutParams
|
|
import android.widget.RelativeLayout
|
|
import androidx.annotation.StringRes
|
|
import androidx.appcompat.app.ActionBarDrawerToggle
|
|
import androidx.appcompat.app.AlertDialog
|
|
import androidx.appcompat.app.AppCompatDelegate
|
|
import androidx.appcompat.widget.TintTypedArray
|
|
import androidx.core.app.NotificationCompat
|
|
import androidx.core.view.*
|
|
import androidx.drawerlayout.widget.DrawerLayout
|
|
import androidx.drawerlayout.widget.DrawerLayoutAccessor
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
|
|
import com.getkeepsafe.taptargetview.TapTarget
|
|
import com.getkeepsafe.taptargetview.TapTargetView
|
|
import com.squareup.otto.Subscribe
|
|
import kotlinx.android.synthetic.main.activity_home.*
|
|
import kotlinx.android.synthetic.main.activity_home_content.*
|
|
import kotlinx.android.synthetic.main.layout_empty_tab_hint.*
|
|
import nl.komponents.kovenant.task
|
|
import org.mariotaku.chameleon.ChameleonUtils
|
|
import org.mariotaku.kpreferences.contains
|
|
import org.mariotaku.kpreferences.get
|
|
import org.mariotaku.kpreferences.set
|
|
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
|
|
import org.mariotaku.ktextension.coerceInOr
|
|
import org.mariotaku.ktextension.contains
|
|
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
|
|
import org.mariotaku.sqliteqb.library.Expression
|
|
import org.mariotaku.twidere.Constants.*
|
|
import org.mariotaku.twidere.R
|
|
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
|
|
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
|
import org.mariotaku.twidere.annotation.CustomTabType
|
|
import org.mariotaku.twidere.annotation.FilterScope
|
|
import org.mariotaku.twidere.annotation.NavbarStyle
|
|
import org.mariotaku.twidere.annotation.ReadPositionTag
|
|
import org.mariotaku.twidere.constant.*
|
|
import org.mariotaku.twidere.extension.applyTheme
|
|
import org.mariotaku.twidere.extension.model.notificationBuilder
|
|
import org.mariotaku.twidere.extension.onShow
|
|
import org.mariotaku.twidere.fragment.AccountsDashboardFragment
|
|
import org.mariotaku.twidere.fragment.BaseDialogFragment
|
|
import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment
|
|
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
|
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
|
import org.mariotaku.twidere.graphic.EmptyDrawable
|
|
import org.mariotaku.twidere.model.AccountDetails
|
|
import org.mariotaku.twidere.model.SupportTabSpec
|
|
import org.mariotaku.twidere.model.Tab
|
|
import org.mariotaku.twidere.model.UserKey
|
|
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
|
import org.mariotaku.twidere.model.notification.NotificationChannelSpec
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
|
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
|
import org.mariotaku.twidere.receiver.NotificationReceiver
|
|
import org.mariotaku.twidere.util.*
|
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
|
import org.mariotaku.twidere.util.premium.ExtraFeaturesService
|
|
import org.mariotaku.twidere.view.HomeDrawerLayout
|
|
import org.mariotaku.twidere.view.TabPagerIndicator
|
|
import java.lang.ref.WeakReference
|
|
import kotlin.math.floor
|
|
|
|
class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, SupportFragmentCallback,
|
|
OnLongClickListener, DrawerLayout.DrawerListener {
|
|
|
|
private val accountUpdatedListener = AccountUpdatedListener(this)
|
|
|
|
private var selectedAccountToSearch: AccountDetails? = null
|
|
|
|
private lateinit var multiSelectHandler: MultiSelectEventHandler
|
|
private lateinit var pagerAdapter: SupportTabsAdapter
|
|
private lateinit var drawerToggle: ActionBarDrawerToggle
|
|
|
|
private var propertiesInitialized = false
|
|
private var actionsButtonBottomMargin: Int = 0
|
|
|
|
private var updateUnreadCountTask: UpdateUnreadCountTask? = null
|
|
private val readStateChangeListener = OnSharedPreferenceChangeListener { _, _ -> updateUnreadCount() }
|
|
private val controlBarShowHideHelper = ControlBarShowHideHelper(this)
|
|
|
|
override val controlBarHeight: Int
|
|
get() {
|
|
return mainTabs.height - mainTabs.stripHeight
|
|
}
|
|
|
|
override val currentVisibleFragment: Fragment?
|
|
get() {
|
|
val currentItem = mainPager.currentItem
|
|
if (currentItem < 0 || currentItem >= pagerAdapter.count) return null
|
|
return pagerAdapter.instantiateItem(mainPager, currentItem)
|
|
}
|
|
|
|
private val homeDrawerToggleDelegate = object : ActionBarDrawerToggle.Delegate {
|
|
override fun setActionBarUpIndicator(upDrawable: Drawable, @StringRes contentDescRes: Int) {
|
|
drawerToggleButton.setImageDrawable(upDrawable)
|
|
drawerToggleButton.setColorFilter(ChameleonUtils.getColorDependent(overrideTheme.colorToolbar))
|
|
drawerToggleButton.contentDescription = getString(contentDescRes)
|
|
}
|
|
|
|
override fun setActionBarDescription(@StringRes contentDescRes: Int) {
|
|
drawerToggleButton.contentDescription = getString(contentDescRes)
|
|
}
|
|
|
|
@SuppressLint("RestrictedApi")
|
|
override fun getThemeUpIndicator(): Drawable {
|
|
val a = TintTypedArray.obtainStyledAttributes(actionBarThemedContext, null,
|
|
HOME_AS_UP_ATTRS)
|
|
val result = a.getDrawable(0)
|
|
a.recycle()
|
|
return result
|
|
}
|
|
|
|
override fun getActionBarThemedContext(): Context {
|
|
return toolbar.context
|
|
}
|
|
|
|
override fun isNavigationVisible(): Boolean {
|
|
return true
|
|
}
|
|
}
|
|
|
|
private val keyboardShortcutRecipient: Fragment?
|
|
get() = when {
|
|
homeMenu.isDrawerOpen(GravityCompat.START) -> leftDrawerFragment
|
|
homeMenu.isDrawerOpen(GravityCompat.END) -> null
|
|
else -> currentVisibleFragment
|
|
}
|
|
|
|
private val activatedAccountKeys: Array<UserKey>
|
|
get() = DataStoreUtils.getActivatedAccountKeys(this)
|
|
|
|
private val leftDrawerFragment: Fragment?
|
|
get() = supportFragmentManager.findFragmentById(R.id.leftDrawer)
|
|
|
|
private val isDrawerOpen: Boolean
|
|
get() {
|
|
val drawer = homeMenu ?: return false
|
|
return drawer.isDrawerOpen(GravityCompat.START) || drawer.isDrawerOpen(GravityCompat.END)
|
|
}
|
|
|
|
/**
|
|
* Called when the context is first created.
|
|
*/
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
multiSelectHandler = MultiSelectEventHandler(this)
|
|
multiSelectHandler.dispatchOnCreate()
|
|
DataStoreUtils.prepareDatabase(this)
|
|
if (!DataStoreUtils.hasAccount(this)) {
|
|
val signInIntent = Intent(INTENT_ACTION_TWITTER_LOGIN)
|
|
signInIntent.setClass(this, SignInActivity::class.java)
|
|
startActivity(signInIntent)
|
|
finish()
|
|
if (defaultAutoRefreshAskedKey !in kPreferences) {
|
|
// Assume first install
|
|
kPreferences[defaultAutoRefreshAskedKey] = false
|
|
}
|
|
return
|
|
} else {
|
|
notifyAccountsChanged()
|
|
}
|
|
supportRequestWindowFeature(AppCompatDelegate.FEATURE_ACTION_MODE_OVERLAY)
|
|
setContentView(R.layout.activity_home)
|
|
setSupportActionBar(toolbar)
|
|
|
|
drawerToggle = ActionBarDrawerToggle(this, homeMenu, R.string.open_accounts_dashboard,
|
|
R.string.close_accounts_dashboard)
|
|
pagerAdapter = SupportTabsAdapter(this, supportFragmentManager, mainTabs)
|
|
propertiesInitialized = true
|
|
|
|
ThemeUtils.setCompatContentViewOverlay(window, EmptyDrawable())
|
|
|
|
val refreshOnStart = preferences[refreshOnStartKey]
|
|
var tabDisplayOptionInt = Utils.getTabDisplayOptionInt(this)
|
|
|
|
ViewCompat.setOnApplyWindowInsetsListener(homeContent, this)
|
|
homeMenu.fitsSystemWindows = Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP ||
|
|
preferences[navbarStyleKey] != NavbarStyle.TRANSPARENT
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !ViewCompat.getFitsSystemWindows(homeMenu)) {
|
|
ViewCompat.setOnApplyWindowInsetsListener(homeMenu, null)
|
|
}
|
|
|
|
mainPager.adapter = pagerAdapter
|
|
mainTabs.setViewPager(mainPager)
|
|
mainTabs.setOnPageChangeListener(this)
|
|
if (tabDisplayOptionInt == 0) {
|
|
tabDisplayOptionInt = TabPagerIndicator.DisplayOption.ICON
|
|
}
|
|
mainTabs.setTabDisplayOption(tabDisplayOptionInt)
|
|
mainTabs.setTabExpandEnabled(TabPagerIndicator.DisplayOption.LABEL !in tabDisplayOptionInt)
|
|
mainTabs.setDisplayBadge(preferences[unreadCountKey])
|
|
mainTabs.updateAppearance()
|
|
|
|
if (preferences[drawerToggleKey]) {
|
|
drawerToggleButton.visibility = View.VISIBLE
|
|
} else {
|
|
drawerToggleButton.visibility = View.GONE
|
|
}
|
|
|
|
if (preferences[fabVisibleKey]) {
|
|
actionsButton.visibility = View.VISIBLE
|
|
} else {
|
|
actionsButton.visibility = View.GONE
|
|
}
|
|
actionsButtonBottomMargin = (actionsButton.layoutParams as MarginLayoutParams).bottomMargin
|
|
|
|
homeContent.addOnLayoutChangeListener { _, _, top, _, _, _, oldTop, _, _ ->
|
|
if (top != oldTop) {
|
|
val fragment = leftDrawerFragment
|
|
if (fragment is AccountsDashboardFragment) {
|
|
fragment.setStatusBarHeight(top)
|
|
}
|
|
}
|
|
}
|
|
|
|
actionsButton.setOnClickListener(this)
|
|
actionsButton.setOnLongClickListener(this)
|
|
drawerToggleButton.setOnClickListener(this)
|
|
emptyTabHint.setOnClickListener(this)
|
|
|
|
setupSlidingMenu()
|
|
setupBars()
|
|
showPromotionOffer()
|
|
initUnreadCount()
|
|
setupHomeTabs()
|
|
updateActionsButton()
|
|
|
|
if (savedInstanceState == null) {
|
|
if (refreshOnStart) {
|
|
twitterWrapper.refreshAll(activatedAccountKeys)
|
|
}
|
|
if (intent.getBooleanExtra(EXTRA_OPEN_ACCOUNTS_DRAWER, false)) {
|
|
openAccountsDrawer()
|
|
}
|
|
}
|
|
|
|
val initialTabPosition = handleIntent(intent, savedInstanceState == null)
|
|
setTabPosition(initialTabPosition)
|
|
|
|
if (!showDrawerTutorial() && !kPreferences[defaultAutoRefreshAskedKey]) {
|
|
showAutoRefreshConfirm()
|
|
}
|
|
}
|
|
|
|
override fun onPostCreate(savedInstanceState: Bundle?) {
|
|
super.onPostCreate(savedInstanceState)
|
|
// Sync the toggle state after onRestoreInstanceState has occurred.
|
|
drawerToggle.syncState()
|
|
}
|
|
|
|
override fun onStart() {
|
|
super.onStart()
|
|
multiSelectHandler.dispatchOnStart()
|
|
AccountManager.get(this).addOnAccountsUpdatedListenerSafe(accountUpdatedListener, updateImmediately = false)
|
|
bus.register(this)
|
|
|
|
readStateManager.registerOnSharedPreferenceChangeListener(readStateChangeListener)
|
|
updateUnreadCount()
|
|
}
|
|
|
|
override fun onResume() {
|
|
super.onResume()
|
|
invalidateOptionsMenu()
|
|
updateActionsButton()
|
|
}
|
|
|
|
override fun onStop() {
|
|
multiSelectHandler.dispatchOnStop()
|
|
readStateManager.unregisterOnSharedPreferenceChangeListener(readStateChangeListener)
|
|
bus.unregister(this)
|
|
AccountManager.get(this).removeOnAccountsUpdatedListenerSafe(accountUpdatedListener)
|
|
preferences.edit().putInt(KEY_SAVED_TAB_POSITION, mainPager.currentItem).apply()
|
|
timelineSyncManager?.commit()
|
|
super.onStop()
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
if (isFinishing) {
|
|
// Delete unused items in databases.
|
|
val context = applicationContext
|
|
task { DataStoreUtils.cleanDatabasesByItemLimit(context) }
|
|
}
|
|
super.onDestroy()
|
|
}
|
|
|
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
super.onConfigurationChanged(newConfig)
|
|
// Pass any configuration change to the drawer toggle
|
|
drawerToggle.onConfigurationChanged(newConfig)
|
|
}
|
|
|
|
override fun onAttachFragment(fragment: Fragment) {
|
|
super.onAttachFragment(fragment)
|
|
updateActionsButton()
|
|
}
|
|
|
|
override fun onClick(v: View) {
|
|
when (v) {
|
|
actionsButton -> {
|
|
triggerActionsClick()
|
|
}
|
|
emptyTabHint -> {
|
|
startActivityForResult(IntentUtils.settings("tabs"), REQUEST_SETTINGS)
|
|
}
|
|
drawerToggleButton -> {
|
|
if (homeMenu.isDrawerOpen(GravityCompat.START) || homeMenu.isDrawerOpen(GravityCompat.END)) {
|
|
homeMenu.closeDrawers()
|
|
} else {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onLongClick(v: View): Boolean {
|
|
when (v) {
|
|
actionsButton -> {
|
|
Utils.showMenuItemToast(v, v.contentDescription, true)
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
|
}
|
|
|
|
override fun onPageSelected(position: Int) {
|
|
//TODO handle secondary drawer
|
|
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
homeMenu.closeDrawers()
|
|
}
|
|
updateActionsButton()
|
|
}
|
|
|
|
override fun onPageScrollStateChanged(state: Int) {
|
|
setControlBarVisibleAnimate(true)
|
|
}
|
|
|
|
override fun onSearchRequested(): Boolean {
|
|
startActivity(Intent(this, QuickSearchBarActivity::class.java))
|
|
return true
|
|
}
|
|
|
|
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
|
|
if (caller === leftDrawerFragment) return super.getSystemWindowInsets(caller, insets)
|
|
if (mainTabs == null || homeContent == null || toolbar == null || !toolbar.isVisible) return false
|
|
val height = mainTabs.height
|
|
if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
|
|
if (height != 0) {
|
|
insets.top = height
|
|
} else {
|
|
insets.top = ThemeUtils.getActionBarHeight(this)
|
|
}
|
|
insets.bottom = systemWindowsInsets?.bottom ?: 0
|
|
} else {
|
|
if (height != 0) {
|
|
insets.bottom = height
|
|
} else {
|
|
insets.bottom = ThemeUtils.getActionBarHeight(this)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
@SuppressLint("RestrictedApi")
|
|
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
|
super.onApplyWindowInsets(v, insets)
|
|
val fragment = leftDrawerFragment
|
|
if (fragment is AccountsDashboardFragment) {
|
|
fragment.requestApplyInsets()
|
|
}
|
|
homeMenu.setChildInsets(insets.unwrapped, insets.systemWindowInsetTop > 0)
|
|
if (!ViewCompat.getFitsSystemWindows(homeMenu)) {
|
|
homeContent.setPadding(0, insets.systemWindowInsetTop, 0, 0)
|
|
}
|
|
(toolbar.layoutParams as? MarginLayoutParams)?.bottomMargin = insets.systemWindowInsetBottom
|
|
(actionsButton.layoutParams as? MarginLayoutParams)?.bottomMargin =
|
|
actionsButtonBottomMargin + if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
|
|
insets.systemWindowInsetBottom
|
|
} else {
|
|
0
|
|
}
|
|
return insets
|
|
}
|
|
|
|
override fun onNewIntent(intent: Intent) {
|
|
super.onNewIntent(intent)
|
|
val tabPosition = handleIntent(intent, false)
|
|
if (tabPosition >= 0) {
|
|
mainPager.currentItem = tabPosition.coerceInOr(0 until pagerAdapter.count, 0)
|
|
}
|
|
}
|
|
|
|
override fun setControlBarVisibleAnimate(visible: Boolean,
|
|
listener: ControlBarShowHideHelper.ControlBarAnimationListener?) {
|
|
controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener)
|
|
}
|
|
|
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
if (drawerToggle.onOptionsItemSelected(item)) {
|
|
return true
|
|
}
|
|
when (item.itemId) {
|
|
android.R.id.home -> {
|
|
val fm = supportFragmentManager
|
|
val count = fm.backStackEntryCount
|
|
if (homeMenu.isDrawerOpen(GravityCompat.START) || homeMenu.isDrawerOpen(GravityCompat.END)) {
|
|
homeMenu.closeDrawers()
|
|
return true
|
|
} else if (count == 0) {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
return true
|
|
}
|
|
return true
|
|
}
|
|
R.id.search -> {
|
|
openSearchView(selectedAccountToSearch)
|
|
return true
|
|
}
|
|
R.id.actions -> {
|
|
triggerActionsClick()
|
|
return true
|
|
}
|
|
}
|
|
return super.onOptionsItemSelected(item)
|
|
}
|
|
|
|
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int,
|
|
event: KeyEvent, metaState: Int): Boolean {
|
|
if (handleFragmentKeyboardShortcutSingle(handler, keyCode, event, metaState)) return true
|
|
var action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_HOME, keyCode, event, metaState)
|
|
if (action != null) {
|
|
when (action) {
|
|
KeyboardShortcutConstants.ACTION_HOME_ACCOUNTS_DASHBOARD -> {
|
|
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
homeMenu.closeDrawers()
|
|
} else {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
setControlBarVisibleAnimate(true)
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
|
if (action != null) {
|
|
when (action) {
|
|
KeyboardShortcutConstants.ACTION_NAVIGATION_PREVIOUS_TAB -> {
|
|
val previous = mainPager.currentItem - 1
|
|
if (previous < 0 && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.START) != null) {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
setControlBarVisibleAnimate(true)
|
|
} else if (previous < pagerAdapter.count) {
|
|
if (homeMenu.isDrawerOpen(GravityCompat.END)) {
|
|
homeMenu.closeDrawers()
|
|
} else {
|
|
mainPager.setCurrentItem(previous, true)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
KeyboardShortcutConstants.ACTION_NAVIGATION_NEXT_TAB -> {
|
|
val next = mainPager.currentItem + 1
|
|
if (next >= pagerAdapter.count && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.END) != null) {
|
|
homeMenu.openDrawer(GravityCompat.END)
|
|
setControlBarVisibleAnimate(true)
|
|
} else if (next >= 0) {
|
|
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
homeMenu.closeDrawers()
|
|
} else {
|
|
mainPager.setCurrentItem(next, true)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return handler.handleKey(this, null, keyCode, event, metaState)
|
|
}
|
|
|
|
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int,
|
|
event: KeyEvent, metaState: Int): Boolean {
|
|
if (isFragmentKeyboardShortcutHandled(handler, keyCode, event, metaState)) return true
|
|
return super.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
|
}
|
|
|
|
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int,
|
|
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
if (handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState))
|
|
return true
|
|
return super.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
}
|
|
|
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
|
when (event.keyCode) {
|
|
KeyEvent.KEYCODE_MENU -> {
|
|
if (event.action != KeyEvent.ACTION_UP) return true
|
|
if (isDrawerOpen) {
|
|
homeMenu.closeDrawers()
|
|
} else {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
return super.dispatchKeyEvent(event)
|
|
}
|
|
|
|
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
|
when (keyCode) {
|
|
KeyEvent.KEYCODE_BACK -> {
|
|
if (isDrawerOpen) {
|
|
homeMenu.closeDrawers()
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return super.onKeyUp(keyCode, event)
|
|
}
|
|
|
|
override fun triggerRefresh(position: Int): Boolean {
|
|
val f = pagerAdapter.instantiateItem(mainPager, position)
|
|
if (f.activity == null || f.isDetached) return false
|
|
if (f !is RefreshScrollTopInterface) return false
|
|
return f.triggerRefresh()
|
|
}
|
|
|
|
fun notifyAccountsChanged() {
|
|
}
|
|
|
|
@Subscribe
|
|
fun notifyUnreadCountUpdated(event: UnreadCountUpdatedEvent) {
|
|
updateUnreadCount()
|
|
}
|
|
|
|
fun updateUnreadCount() {
|
|
if (mainTabs == null || updateUnreadCountTask != null && updateUnreadCountTask!!.status == AsyncTask.Status.RUNNING)
|
|
return
|
|
updateUnreadCountTask = UpdateUnreadCountTask(this, preferences, readStateManager, mainTabs,
|
|
pagerAdapter.tabs.toTypedArray()).apply { execute() }
|
|
mainTabs.setDisplayBadge(preferences.getBoolean(SharedPreferenceConstants.KEY_UNREAD_COUNT, true))
|
|
}
|
|
|
|
val tabs: List<SupportTabSpec>
|
|
get() = pagerAdapter.tabs
|
|
|
|
override var controlBarOffset: Float
|
|
get() {
|
|
if (mainTabs.columns > 1 || !toolbar.isVisible) {
|
|
val lp = actionsButton.layoutParams
|
|
val total: Float
|
|
total = if (lp is MarginLayoutParams) {
|
|
(lp.bottomMargin + actionsButton.height).toFloat()
|
|
} else {
|
|
actionsButton.height.toFloat()
|
|
}
|
|
return 1 - actionsButton.translationY / total
|
|
}
|
|
val totalHeight = controlBarHeight.toFloat()
|
|
return 1 + if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
|
|
toolbar.translationY
|
|
} else {
|
|
-toolbar.translationY
|
|
} / totalHeight
|
|
}
|
|
set(offset) {
|
|
if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
|
|
val translationY = if (mainTabs.columns > 1 || !toolbar.isVisible) {
|
|
0
|
|
} else {
|
|
(controlBarHeight * (offset - 1)).toInt()
|
|
}
|
|
toolbar.translationY = translationY.toFloat()
|
|
windowOverlay.translationY = translationY.toFloat()
|
|
val lp = actionsButton.layoutParams
|
|
if (lp is MarginLayoutParams) {
|
|
actionsButton.translationY = (lp.bottomMargin + actionsButton.height) * (1 - offset)
|
|
} else {
|
|
actionsButton.translationY = actionsButton.height * (1 - offset)
|
|
}
|
|
notifyControlBarOffsetChanged()
|
|
} else {
|
|
val layoutparams = toolbar.layoutParams
|
|
val toolbarMarginBottom = if (layoutparams is MarginLayoutParams) {
|
|
layoutparams.bottomMargin
|
|
} else {
|
|
0
|
|
}
|
|
val translationY = if (mainTabs.columns > 1 || !toolbar.isVisible) {
|
|
0
|
|
} else {
|
|
((toolbar.height + toolbarMarginBottom) * (offset - 1)).toInt()
|
|
}
|
|
toolbar.translationY = -translationY.toFloat()
|
|
windowOverlay.translationY = -translationY.toFloat()
|
|
val lp = actionsButton.layoutParams
|
|
if (lp is MarginLayoutParams) {
|
|
actionsButton.translationY = (lp.bottomMargin + toolbar.height + actionsButton.height + toolbarMarginBottom) * (1 - offset)
|
|
} else {
|
|
actionsButton.translationY = actionsButton.height * (1 - offset)
|
|
}
|
|
notifyControlBarOffsetChanged()
|
|
}
|
|
}
|
|
|
|
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
|
|
|
}
|
|
|
|
override fun onDrawerOpened(drawerView: View) {
|
|
|
|
}
|
|
|
|
override fun onDrawerClosed(drawerView: View) {
|
|
|
|
}
|
|
|
|
override fun onDrawerStateChanged(newState: Int) {
|
|
val fragment = leftDrawerFragment
|
|
if (newState == DrawerLayout.STATE_DRAGGING && fragment is AccountsDashboardFragment) {
|
|
fragment.loadAccounts()
|
|
}
|
|
}
|
|
|
|
override fun getDrawerToggleDelegate(): ActionBarDrawerToggle.Delegate? {
|
|
return homeDrawerToggleDelegate
|
|
}
|
|
|
|
fun closeAccountsDrawer() {
|
|
if (homeMenu == null) return
|
|
homeMenu.closeDrawers()
|
|
}
|
|
|
|
private fun openSearchView(account: AccountDetails?) {
|
|
selectedAccountToSearch = account
|
|
onSearchRequested()
|
|
}
|
|
|
|
private fun handleFragmentKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler,
|
|
keyCode: Int, repeatCount: Int,
|
|
event: KeyEvent, metaState: Int): Boolean {
|
|
val fragment = keyboardShortcutRecipient
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
return fragment.handleKeyboardShortcutRepeat(handler, keyCode,
|
|
repeatCount, event, metaState)
|
|
}
|
|
return false
|
|
}
|
|
|
|
private fun handleFragmentKeyboardShortcutSingle(handler: KeyboardShortcutsHandler,
|
|
keyCode: Int, event: KeyEvent,
|
|
metaState: Int): Boolean {
|
|
val fragment = keyboardShortcutRecipient
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
return fragment.handleKeyboardShortcutSingle(handler, keyCode,
|
|
event, metaState)
|
|
}
|
|
return false
|
|
}
|
|
|
|
private fun isFragmentKeyboardShortcutHandled(handler: KeyboardShortcutsHandler,
|
|
keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
val fragment = keyboardShortcutRecipient
|
|
if (fragment is KeyboardShortcutCallback) {
|
|
return fragment.isKeyboardShortcutHandled(handler, keyCode,
|
|
event, metaState)
|
|
}
|
|
return false
|
|
}
|
|
|
|
private fun handleIntent(intent: Intent, handleExtraIntent: Boolean): Int {
|
|
// use package's class loader to prevent BadParcelException
|
|
intent.setExtrasClassLoader(classLoader)
|
|
// reset intent
|
|
setIntent(Intent(this, HomeActivity::class.java))
|
|
val action = intent.action
|
|
if (Intent.ACTION_SEARCH == action) {
|
|
val query = intent.getStringExtra(SearchManager.QUERY)
|
|
val appSearchData = intent.getBundleExtra(SearchManager.APP_DATA)
|
|
val accountKey = if (appSearchData != null && appSearchData.containsKey(EXTRA_ACCOUNT_KEY)) {
|
|
appSearchData.getParcelable(EXTRA_ACCOUNT_KEY)
|
|
} else {
|
|
Utils.getDefaultAccountKey(this)
|
|
}
|
|
if (query != null) {
|
|
IntentUtils.openSearch(this, accountKey, query)
|
|
}
|
|
return -1
|
|
}
|
|
val refreshOnStart = preferences.getBoolean(SharedPreferenceConstants.KEY_REFRESH_ON_START, false)
|
|
if (handleExtraIntent && refreshOnStart) {
|
|
twitterWrapper.refreshAll()
|
|
}
|
|
|
|
val uri = intent.data
|
|
@CustomTabType
|
|
val tabType = if (uri != null) Utils.matchTabType(uri) else null
|
|
var initialTab = -1
|
|
if (tabType != null) {
|
|
val accountKey = uri?.getQueryParameter(QUERY_PARAM_ACCOUNT_KEY)?.let(UserKey::valueOf)
|
|
val adapter = pagerAdapter
|
|
for (i in 0 until adapter.count) {
|
|
val tab = adapter.get(i)
|
|
if (tabType == Tab.getTypeAlias(tab.type)) {
|
|
val args = tab.args
|
|
if (args != null && CustomTabUtils.hasAccountKey(this, args,
|
|
activatedAccountKeys, accountKey)) {
|
|
initialTab = i
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if (initialTab == -1 && !handleExtraIntent) {
|
|
// Tab not found, open account specific page
|
|
when (tabType) {
|
|
CustomTabType.NOTIFICATIONS_TIMELINE -> {
|
|
IntentUtils.openInteractions(this, accountKey)
|
|
return -1
|
|
}
|
|
CustomTabType.DIRECT_MESSAGES -> {
|
|
IntentUtils.openDirectMessages(this, accountKey)
|
|
return -1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return initialTab
|
|
}
|
|
|
|
private fun initUnreadCount() {
|
|
for (i in 0 until mainTabs.count) {
|
|
mainTabs.setBadge(i, 0)
|
|
}
|
|
}
|
|
|
|
private fun openAccountsDrawer() {
|
|
if (homeMenu == null) return
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
}
|
|
|
|
private fun showDrawerTutorial(): Boolean {
|
|
if (preferences[drawerTutorialCompleted]) return false
|
|
val targetSize = resources.getDimensionPixelSize(R.dimen.element_size_mlarge)
|
|
val height = resources.displayMetrics.heightPixels
|
|
val listener: TapTargetView.Listener = object : TapTargetView.Listener() {
|
|
override fun onTargetClick(view: TapTargetView?) {
|
|
if (!homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
homeMenu.openDrawer(GravityCompat.START)
|
|
}
|
|
super.onTargetClick(view)
|
|
}
|
|
|
|
override fun onTargetDismissed(view: TapTargetView?, userInitiated: Boolean) {
|
|
preferences[drawerTutorialCompleted] = true
|
|
showAutoRefreshConfirm()
|
|
|
|
}
|
|
}
|
|
val target = Rect(0, 0, targetSize, targetSize)
|
|
target.offsetTo(0, height / 2 - targetSize / 2)
|
|
TapTargetView.showFor(this, TapTarget.forBounds(target,
|
|
getString(R.string.hint_accounts_dashboard_title),
|
|
getString(R.string.hint_accounts_dashboard_message))
|
|
.apply {
|
|
outerCircleColor(R.color.branding_color)
|
|
dimColor(android.R.color.black)
|
|
}, listener)
|
|
|
|
return true
|
|
}
|
|
|
|
private fun showAutoRefreshConfirm() {
|
|
if (isFinishing) return
|
|
executeAfterFragmentResumed { activity ->
|
|
val df = AutoRefreshConfirmDialogFragment()
|
|
df.show(activity.supportFragmentManager, "auto_refresh_confirm")
|
|
}
|
|
}
|
|
|
|
private fun setTabPosition(initialTab: Int) {
|
|
val rememberPosition = preferences.getBoolean(SharedPreferenceConstants.KEY_REMEMBER_POSITION, true)
|
|
if (initialTab >= 0) {
|
|
mainPager.currentItem = initialTab.coerceInOr(0 until pagerAdapter.count, 0)
|
|
} else if (rememberPosition) {
|
|
val position = preferences.getInt(SharedPreferenceConstants.KEY_SAVED_TAB_POSITION, 0)
|
|
mainPager.currentItem = position.coerceInOr(0 until pagerAdapter.count, 0)
|
|
}
|
|
}
|
|
|
|
private fun setupBars() {
|
|
val backgroundOption = currentThemeBackgroundOption
|
|
val isTransparent = ThemeUtils.isTransparentBackground(backgroundOption)
|
|
val actionBarAlpha = if (isTransparent) {
|
|
ThemeUtils.getActionBarAlpha(preferences[themeBackgroundAlphaKey])
|
|
} else {
|
|
0xFF
|
|
}
|
|
actionsButton.alpha = actionBarAlpha / 255f
|
|
}
|
|
|
|
private fun setupHomeTabs() {
|
|
pagerAdapter.clear()
|
|
pagerAdapter.addAll(CustomTabUtils.getHomeTabs(this))
|
|
val hasNoTab = pagerAdapter.count == 0
|
|
emptyTabHint.visibility = if (hasNoTab) View.VISIBLE else View.GONE
|
|
mainPager.visibility = if (hasNoTab) View.GONE else View.VISIBLE
|
|
if (pagerAdapter.count > 1 && hasMultiColumns()) {
|
|
mainPager.pageMargin = resources.getDimensionPixelOffset(R.dimen.home_page_margin)
|
|
mainPager.setPageMarginDrawable(ThemeUtils.getDrawableFromThemeAttribute(this, R.attr.dividerVertical))
|
|
pagerAdapter.hasMultipleColumns = true
|
|
pagerAdapter.preferredColumnWidth = when (preferences[multiColumnWidthKey]) {
|
|
"narrow" -> resources.getDimension(R.dimen.preferred_tab_column_width_narrow)
|
|
"wide" -> resources.getDimension(R.dimen.preferred_tab_column_width_wide)
|
|
else -> resources.getDimension(R.dimen.preferred_tab_column_width_normal)
|
|
}
|
|
mainTabs.columns = floor(1.0 / pagerAdapter.getPageWidth(0)).toInt()
|
|
} else {
|
|
mainPager.pageMargin = 0
|
|
mainPager.setPageMarginDrawable(null)
|
|
pagerAdapter.hasMultipleColumns = false
|
|
mainTabs.columns = 1
|
|
}
|
|
if (pagerAdapter.count == 1 && preferences[autoHideTabs]) {
|
|
toolbar.isVisible = false
|
|
actionsButton.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE)
|
|
}
|
|
} else if (preferences[tabPositionKey] == SharedPreferenceConstants.VALUE_TAB_POSITION_TOP) {
|
|
toolbar.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE)
|
|
}
|
|
actionsButton.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE)
|
|
}
|
|
} else {
|
|
toolbar.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE)
|
|
}
|
|
actionsButton.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
addRule(RelativeLayout.ABOVE, toolbar.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setupSlidingMenu() {
|
|
homeMenu.setDrawerShadow(R.drawable.drawer_shadow_start, GravityCompat.START)
|
|
homeMenu.addDrawerListener(drawerToggle)
|
|
homeMenu.addDrawerListener(this)
|
|
homeMenu.setShouldDisableDecider(HomeDrawerLayout.ShouldDisableDecider { e ->
|
|
val fragment = leftDrawerFragment
|
|
if (fragment is AccountsDashboardFragment) {
|
|
return@ShouldDisableDecider fragment.shouldDisableDrawerSlide(e)
|
|
}
|
|
false
|
|
})
|
|
}
|
|
|
|
private fun showPromotionOffer() {
|
|
// Skip if app doesn't support extra features
|
|
if (!extraFeaturesService.isSupported()) return
|
|
// Skip if already bought enhanced features pack or have set promotions options
|
|
if (extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FEATURES_PACK)
|
|
|| promotionsEnabledKey in preferences) {
|
|
return
|
|
}
|
|
|
|
val intent = Intent(this, PremiumDashboardActivity::class.java)
|
|
val contentIntent = PendingIntent.getActivity(this, 0, intent, 0)
|
|
val builder = NotificationChannelSpec.appNotices.notificationBuilder(this)
|
|
builder.setAutoCancel(true)
|
|
builder.setSmallIcon(R.drawable.ic_stat_gift)
|
|
builder.setTicker(getString(R.string.message_ticker_promotions_reward))
|
|
builder.setContentTitle(getString(R.string.title_promotions_reward))
|
|
builder.setContentText(getString(R.string.message_ticker_promotions_reward))
|
|
builder.setContentIntent(contentIntent)
|
|
builder.setStyle(NotificationCompat.BigTextStyle(builder)
|
|
.setBigContentTitle(getString(R.string.title_promotions_reward))
|
|
.bigText(getString(R.string.message_promotions_reward)))
|
|
builder.addAction(R.drawable.ic_action_confirm, getString(R.string.action_enable),
|
|
PendingIntent.getBroadcast(this, 0, Intent(this,
|
|
NotificationReceiver::class.java).setAction(BROADCAST_PROMOTIONS_ACCEPTED)
|
|
.putExtra(EXTRA_NOTIFICATION_ID, NOTIFICATION_ID_PROMOTIONS_OFFER),
|
|
PendingIntent.FLAG_ONE_SHOT))
|
|
builder.addAction(R.drawable.ic_action_cancel, getString(R.string.action_no_thanks),
|
|
PendingIntent.getBroadcast(this, 0, Intent(this,
|
|
NotificationReceiver::class.java).setAction(BROADCAST_PROMOTIONS_DENIED)
|
|
.putExtra(EXTRA_NOTIFICATION_ID, NOTIFICATION_ID_PROMOTIONS_OFFER),
|
|
PendingIntent.FLAG_ONE_SHOT))
|
|
notificationManager.notify(NOTIFICATION_ID_PROMOTIONS_OFFER, builder.build())
|
|
}
|
|
|
|
private fun triggerActionsClick() {
|
|
val position = mainPager.currentItem
|
|
if (pagerAdapter.count == 0) return
|
|
val fragment = pagerAdapter.instantiateItem(mainPager, position) as? IFloatingActionButtonFragment
|
|
val handled = fragment?.onActionClick("home") ?: false
|
|
if (!handled) {
|
|
startActivity(Intent(INTENT_ACTION_COMPOSE))
|
|
}
|
|
}
|
|
|
|
private fun updateActionsButton() {
|
|
if (!propertiesInitialized) return
|
|
val fragment = run {
|
|
if (pagerAdapter.count == 0) return@run null
|
|
val position = mainPager.currentItem
|
|
val f = pagerAdapter.instantiateItem(mainPager, position) as? IFloatingActionButtonFragment
|
|
if (f is Fragment && (f.isDetached || f.host == null)) {
|
|
return@run null
|
|
}
|
|
return@run f
|
|
}
|
|
val info = fragment?.getActionInfo("home") ?: run {
|
|
actionsButton.setImageResource(R.drawable.ic_action_status_compose)
|
|
actionsButton.contentDescription = getString(R.string.action_compose)
|
|
return
|
|
}
|
|
|
|
actionsButton.setImageResource(info.icon)
|
|
actionsButton.contentDescription = info.title
|
|
}
|
|
|
|
|
|
private fun hasMultiColumns(): Boolean {
|
|
if (!DeviceUtils.isDeviceTablet(this) || !DeviceUtils.isScreenTablet(this)) return false
|
|
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
|
return preferences.getBoolean("multi_column_tabs_landscape", resources.getBoolean(R.bool.default_multi_column_tabs_land))
|
|
}
|
|
return preferences.getBoolean("multi_column_tabs_portrait", resources.getBoolean(R.bool.default_multi_column_tabs_port))
|
|
}
|
|
|
|
|
|
private class AccountUpdatedListener(private val activity: HomeActivity) : OnAccountsUpdateListener {
|
|
|
|
override fun onAccountsUpdated(accounts: Array<out Account>?) {
|
|
activity.notifyAccountsChanged()
|
|
activity.updateUnreadCount()
|
|
}
|
|
}
|
|
|
|
private class UpdateUnreadCountTask(
|
|
context: Context,
|
|
private val preferences: SharedPreferences,
|
|
private val readStateManager: ReadStateManager,
|
|
indicator: TabPagerIndicator,
|
|
private val tabs: Array<SupportTabSpec>
|
|
) : AsyncTask<Any, UpdateUnreadCountTask.TabBadge, SparseIntArray>() {
|
|
|
|
private val activatedKeys = DataStoreUtils.getActivatedAccountKeys(context)
|
|
private val contextRef = WeakReference(context)
|
|
private val indicatorRef = WeakReference(indicator)
|
|
|
|
override fun doInBackground(vararg params: Any): SparseIntArray {
|
|
val result = SparseIntArray()
|
|
val context = contextRef.get() ?: return result
|
|
tabs.forEachIndexed { i, spec ->
|
|
if (spec.type == null) {
|
|
publishProgress(TabBadge(i, -1))
|
|
return@forEachIndexed
|
|
}
|
|
when (spec.type) {
|
|
CustomTabType.HOME_TIMELINE -> {
|
|
val accountKeys = Utils.getAccountKeys(context, spec.args) ?: activatedKeys
|
|
val position = accountKeys.map {
|
|
val tag = Utils.getReadPositionTagWithAccount(ReadPositionTag.HOME_TIMELINE, it)
|
|
readStateManager.getPosition(tag)
|
|
}.fold(0L, Math::max)
|
|
val count = DataStoreUtils.getStatusesCount(context, preferences,
|
|
Statuses.CONTENT_URI, spec.args, Statuses.TIMESTAMP, position,
|
|
true, accountKeys, FilterScope.HOME)
|
|
result.put(i, count)
|
|
publishProgress(TabBadge(i, count))
|
|
}
|
|
CustomTabType.NOTIFICATIONS_TIMELINE -> {
|
|
val accountKeys = Utils.getAccountKeys(context, spec.args) ?: activatedKeys
|
|
val position = accountKeys.map {
|
|
val tag = Utils.getReadPositionTagWithAccount(ReadPositionTag.ACTIVITIES_ABOUT_ME, it)
|
|
readStateManager.getPosition(tag)
|
|
}.fold(0L, Math::max)
|
|
val count = DataStoreUtils.getInteractionsCount(context, preferences,
|
|
spec.args, accountKeys, position, Activities.TIMESTAMP,
|
|
FilterScope.INTERACTIONS)
|
|
result.put(i, count)
|
|
publishProgress(TabBadge(i, count))
|
|
}
|
|
CustomTabType.DIRECT_MESSAGES -> {
|
|
val accountKeys = Utils.getAccountKeys(context, spec.args) ?: activatedKeys
|
|
val projection = (Conversations.COLUMNS + Conversations.UNREAD_COUNT).map {
|
|
TwidereQueryBuilder.mapConversationsProjection(it)
|
|
}.toTypedArray()
|
|
val unreadHaving = Expression.greaterThan(Conversations.UNREAD_COUNT, 0)
|
|
val count = context.contentResolver.getUnreadMessagesEntriesCursorReference(projection,
|
|
accountKeys, extraHaving = unreadHaving)?.use { (cur) ->
|
|
return@use cur.count
|
|
} ?: -1
|
|
result.put(i, count)
|
|
publishProgress(TabBadge(i, count))
|
|
}
|
|
else -> {
|
|
publishProgress(TabBadge(i, -1))
|
|
}
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
override fun onPostExecute(result: SparseIntArray) {
|
|
val indicator = indicatorRef.get() ?: return
|
|
indicator.clearBadge()
|
|
for (i in 0 until result.size()) {
|
|
indicator.setBadge(result.keyAt(i), result.valueAt(i))
|
|
}
|
|
}
|
|
|
|
override fun onProgressUpdate(vararg values: TabBadge) {
|
|
val indicator = indicatorRef.get() ?: return
|
|
for (value in values) {
|
|
indicator.setBadge(value.index, value.count)
|
|
}
|
|
}
|
|
|
|
internal class TabBadge(var index: Int, var count: Int)
|
|
}
|
|
|
|
class AutoRefreshConfirmDialogFragment : BaseDialogFragment() {
|
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
val builder = AlertDialog.Builder(requireContext())
|
|
builder.setTitle(R.string.auto_refresh)
|
|
builder.setMessage(R.string.message_auto_refresh_confirm)
|
|
builder.setPositiveButton(android.R.string.ok) { _, _ ->
|
|
kPreferences[defaultAutoRefreshKey] = true
|
|
}
|
|
builder.setNegativeButton(R.string.action_no_thanks) { _, _ ->
|
|
kPreferences[defaultAutoRefreshKey] = false
|
|
}
|
|
val dialog = builder.create()
|
|
dialog.onShow { it.applyTheme() }
|
|
return dialog
|
|
}
|
|
|
|
override fun onDismiss(dialog: DialogInterface) {
|
|
kPreferences[defaultAutoRefreshAskedKey] = true
|
|
super.onDismiss(dialog)
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
private val HOME_AS_UP_ATTRS = intArrayOf(android.R.attr.homeAsUpIndicator)
|
|
}
|
|
|
|
|
|
}
|