improved timeline position after load
This commit is contained in:
parent
d728a86f17
commit
e8774425a7
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.arch.paging
|
||||||
|
|
||||||
|
fun <T> PagedListAdapterHelper<T>.setPagedListListener(listener: ((list: PagedList<T>?) -> Unit)?) {
|
||||||
|
mListener = if (listener != null) PagedListAdapterHelper.PagedListListener { pagedList ->
|
||||||
|
listener(pagedList)
|
||||||
|
} else null
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ package org.mariotaku.twidere.adapter
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.arch.paging.PagedList
|
import android.arch.paging.PagedList
|
||||||
import android.arch.paging.PagedListAdapterHelper
|
import android.arch.paging.PagedListAdapterHelper
|
||||||
|
import android.arch.paging.setPagedListListener
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.v7.recyclerview.extensions.ListAdapterConfig
|
import android.support.v7.recyclerview.extensions.ListAdapterConfig
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
@ -44,7 +45,11 @@ import org.mariotaku.twidere.annotation.TimelineStyle
|
||||||
import org.mariotaku.twidere.constant.newDocumentApiKey
|
import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||||
import org.mariotaku.twidere.exception.UnsupportedCountIndexException
|
import org.mariotaku.twidere.exception.UnsupportedCountIndexException
|
||||||
import org.mariotaku.twidere.extension.model.activityStatus
|
import org.mariotaku.twidere.extension.model.activityStatus
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.ItemCounts
|
||||||
|
import org.mariotaku.twidere.model.ObjectId
|
||||||
|
import org.mariotaku.twidere.model.ParcelableActivity
|
||||||
|
import org.mariotaku.twidere.model.ParcelableMedia
|
||||||
|
import org.mariotaku.twidere.model.placeholder.ParcelableActivityPlaceholder
|
||||||
import org.mariotaku.twidere.util.IntentUtils
|
import org.mariotaku.twidere.util.IntentUtils
|
||||||
import org.mariotaku.twidere.util.OnLinkClickHandler
|
import org.mariotaku.twidere.util.OnLinkClickHandler
|
||||||
import org.mariotaku.twidere.util.TwidereLinkify
|
import org.mariotaku.twidere.util.TwidereLinkify
|
||||||
|
@ -119,6 +124,12 @@ class ParcelableActivitiesAdapter(
|
||||||
|
|
||||||
var activityClickListener: ActivityAdapterListener? = null
|
var activityClickListener: ActivityAdapterListener? = null
|
||||||
|
|
||||||
|
var pagedListListener: ((list: PagedList<ParcelableActivity>?) -> Unit)? = null
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
pagedActivitiesHelper.setPagedListListener(value)
|
||||||
|
}
|
||||||
|
|
||||||
private val inflater = LayoutInflater.from(context)
|
private val inflater = LayoutInflater.from(context)
|
||||||
private val twidereLinkify = TwidereLinkify(OnLinkClickHandler(context, null, preferences))
|
private val twidereLinkify = TwidereLinkify(OnLinkClickHandler(context, null, preferences))
|
||||||
private val statusAdapterDelegate = DummyItemAdapter(context, twidereLinkify, this, requestManager)
|
private val statusAdapterDelegate = DummyItemAdapter(context, twidereLinkify, this, requestManager)
|
||||||
|
@ -400,18 +411,6 @@ class ParcelableActivitiesAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ParcelableActivityPlaceholder : ParcelableActivity() {
|
|
||||||
init {
|
|
||||||
id = "none"
|
|
||||||
account_key = UserKey.INVALID
|
|
||||||
user_key = UserKey.INVALID
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ITEM_VIEW_TYPE_STUB = 0
|
const val ITEM_VIEW_TYPE_STUB = 0
|
||||||
const val ITEM_VIEW_TYPE_GAP = 1
|
const val ITEM_VIEW_TYPE_GAP = 1
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.adapter
|
||||||
|
|
||||||
import android.arch.paging.PagedList
|
import android.arch.paging.PagedList
|
||||||
import android.arch.paging.PagedListAdapterHelper
|
import android.arch.paging.PagedListAdapterHelper
|
||||||
|
import android.arch.paging.setPagedListListener
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.support.v4.widget.Space
|
import android.support.v4.widget.Space
|
||||||
import android.support.v7.recyclerview.extensions.ListAdapterConfig
|
import android.support.v7.recyclerview.extensions.ListAdapterConfig
|
||||||
|
@ -99,6 +100,20 @@ class ParcelableStatusesAdapter(
|
||||||
|
|
||||||
override val itemCounts = ItemCounts(5)
|
override val itemCounts = ItemCounts(5)
|
||||||
|
|
||||||
|
override var loadMoreIndicatorPosition: Int
|
||||||
|
get() = super.loadMoreIndicatorPosition
|
||||||
|
set(value) {
|
||||||
|
super.loadMoreIndicatorPosition = value
|
||||||
|
updateItemCounts()
|
||||||
|
}
|
||||||
|
|
||||||
|
override var loadMoreSupportedPosition: Int
|
||||||
|
get() = super.loadMoreSupportedPosition
|
||||||
|
set(value) {
|
||||||
|
super.loadMoreSupportedPosition = value
|
||||||
|
updateItemCounts()
|
||||||
|
}
|
||||||
|
|
||||||
var isShowInReplyTo: Boolean = false
|
var isShowInReplyTo: Boolean = false
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field == value) return
|
if (field == value) return
|
||||||
|
@ -134,18 +149,10 @@ class ParcelableStatusesAdapter(
|
||||||
val statusStartIndex: Int
|
val statusStartIndex: Int
|
||||||
get() = getItemStartPosition(ITEM_INDEX_STATUS)
|
get() = getItemStartPosition(ITEM_INDEX_STATUS)
|
||||||
|
|
||||||
override var loadMoreIndicatorPosition: Int
|
var pagedListListener: ((list: PagedList<ParcelableStatus>?) -> Unit)? = null
|
||||||
get() = super.loadMoreIndicatorPosition
|
|
||||||
set(value) {
|
set(value) {
|
||||||
super.loadMoreIndicatorPosition = value
|
field = value
|
||||||
updateItemCounts()
|
pagedStatusesHelper.setPagedListListener(value)
|
||||||
}
|
|
||||||
|
|
||||||
override var loadMoreSupportedPosition: Int
|
|
||||||
get() = super.loadMoreSupportedPosition
|
|
||||||
set(value) {
|
|
||||||
super.loadMoreSupportedPosition = value
|
|
||||||
updateItemCounts()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||||
|
|
|
@ -60,7 +60,9 @@ import org.mariotaku.twidere.data.processor.DataSourceItemProcessor
|
||||||
import org.mariotaku.twidere.extension.model.activityStatus
|
import org.mariotaku.twidere.extension.model.activityStatus
|
||||||
import org.mariotaku.twidere.extension.queryOne
|
import org.mariotaku.twidere.extension.queryOne
|
||||||
import org.mariotaku.twidere.extension.showContextMenuForChild
|
import org.mariotaku.twidere.extension.showContextMenuForChild
|
||||||
|
import org.mariotaku.twidere.extension.view.PositionWithOffset
|
||||||
import org.mariotaku.twidere.extension.view.firstVisibleItemPosition
|
import org.mariotaku.twidere.extension.view.firstVisibleItemPosition
|
||||||
|
import org.mariotaku.twidere.extension.view.firstVisibleItemPositionWithOffset
|
||||||
import org.mariotaku.twidere.extension.view.lastVisibleItemPosition
|
import org.mariotaku.twidere.extension.view.lastVisibleItemPosition
|
||||||
import org.mariotaku.twidere.fragment.AbsContentRecyclerViewFragment
|
import org.mariotaku.twidere.fragment.AbsContentRecyclerViewFragment
|
||||||
import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment
|
import org.mariotaku.twidere.fragment.timeline.AbsTimelineFragment
|
||||||
|
@ -82,6 +84,7 @@ import org.mariotaku.twidere.view.ExtendedRecyclerView
|
||||||
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder
|
import org.mariotaku.twidere.view.holder.ActivityTitleSummaryViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.GapViewHolder
|
import org.mariotaku.twidere.view.holder.GapViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||||
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<ParcelableActivitiesAdapter, RecyclerView.LayoutManager>() {
|
abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<ParcelableActivitiesAdapter, RecyclerView.LayoutManager>() {
|
||||||
|
|
||||||
|
@ -125,12 +128,15 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
|
|
||||||
private val busEventHandler = BusEventHandler()
|
private val busEventHandler = BusEventHandler()
|
||||||
private val scrollHandler = ScrollHandler()
|
private val scrollHandler = ScrollHandler()
|
||||||
|
private val timelineBoundaryCallback = ActivitiesBoundaryCallback()
|
||||||
|
private val positionBackup: AtomicReference<PositionWithOffset> = AtomicReference()
|
||||||
private var dataController: ExtendedPagedListProvider.DataController? = null
|
private var dataController: ExtendedPagedListProvider.DataController? = null
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
registerForContextMenu(recyclerView)
|
registerForContextMenu(recyclerView)
|
||||||
adapter.activityClickListener = ActivityClickHandler()
|
adapter.activityClickListener = ActivityClickHandler()
|
||||||
|
adapter.pagedListListener = this::onPagedListChanged
|
||||||
adapter.loadMoreSupportedPosition = if (isStandalone) {
|
adapter.loadMoreSupportedPosition = if (isStandalone) {
|
||||||
LoadMorePosition.NONE
|
LoadMorePosition.NONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,26 +241,7 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLoadMoreContents(position: Int) {
|
override fun onLoadMoreContents(position: Int) {
|
||||||
if (isStandalone || !refreshEnabled || position != LoadMorePosition.END) return
|
// No-op
|
||||||
val started = getActivities(object : ContentRefreshParam {
|
|
||||||
override val accountKeys by lazy {
|
|
||||||
this@AbsActivitiesFragment.accountKeys
|
|
||||||
}
|
|
||||||
override val pagination by lazy {
|
|
||||||
val keys = accountKeys.toNulls()
|
|
||||||
val maxIds = DataStoreUtils.getRefreshOldestActivityMaxPositions(context!!, contentUri, keys)
|
|
||||||
val maxSortIds = DataStoreUtils.getRefreshOldestActivityMaxSortPositions(context!!, contentUri, keys)
|
|
||||||
return@lazy Array(keys.size) { idx ->
|
|
||||||
SinceMaxPagination.maxId(maxIds[idx], maxSortIds[idx])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val tabId: Long
|
|
||||||
get() = this@AbsActivitiesFragment.tabId
|
|
||||||
|
|
||||||
})
|
|
||||||
if (!started) return
|
|
||||||
super.onLoadMoreContents(position)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
|
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
|
||||||
|
@ -269,6 +256,9 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll to start of the timeline. This also updates read position
|
||||||
|
*/
|
||||||
override fun scrollToStart(): Boolean {
|
override fun scrollToStart(): Boolean {
|
||||||
val result = super.scrollToStart()
|
val result = super.scrollToStart()
|
||||||
if (result) saveReadPosition(0)
|
if (result) saveReadPosition(0)
|
||||||
|
@ -288,7 +278,7 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
|
|
||||||
|
|
||||||
protected open fun onDataLoaded(data: PagedList<ParcelableActivity>?) {
|
protected open fun onDataLoaded(data: PagedList<ParcelableActivity>?) {
|
||||||
val firstVisiblePosition = layoutManager.firstVisibleItemPosition
|
val firstVisiblePosition = layoutManager.firstVisibleItemPositionWithOffset
|
||||||
adapter.showAccountsColor = accountKeys.size > 1
|
adapter.showAccountsColor = accountKeys.size > 1
|
||||||
adapter.activities = data
|
adapter.activities = data
|
||||||
when {
|
when {
|
||||||
|
@ -299,12 +289,15 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
showContent()
|
showContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstVisiblePosition == 0 && !preferences[readFromBottomKey]) {
|
positionBackup.set(firstVisiblePosition)
|
||||||
val weakThis by weak(this)
|
}
|
||||||
recyclerView.post {
|
|
||||||
val f = weakThis?.takeIf { !it.isDetached } ?: return@post
|
protected open fun onPagedListChanged(data: PagedList<ParcelableActivity>?) {
|
||||||
f.scrollToStart()
|
val firstVisiblePosition = positionBackup.getAndSet(null) ?: return
|
||||||
}
|
if (firstVisiblePosition.position == 0 && !preferences[readFromBottomKey]) {
|
||||||
|
scrollToPositionWithOffset(0, 0)
|
||||||
|
} else {
|
||||||
|
scrollToPositionWithOffset(firstVisiblePosition.position, firstVisiblePosition.offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,6 +526,31 @@ abstract class AbsActivitiesFragment : AbsContentRecyclerViewFragment<Parcelable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class ActivitiesBoundaryCallback : PagedList.BoundaryCallback<ParcelableStatus>() {
|
||||||
|
override fun onItemAtEndLoaded(itemAtEnd: ParcelableStatus) {
|
||||||
|
val started = getActivities(object : ContentRefreshParam {
|
||||||
|
override val accountKeys by lazy {
|
||||||
|
this@AbsActivitiesFragment.accountKeys
|
||||||
|
}
|
||||||
|
override val pagination by lazy {
|
||||||
|
val keys = accountKeys.toNulls()
|
||||||
|
val maxIds = DataStoreUtils.getRefreshOldestActivityMaxPositions(context!!, contentUri, keys)
|
||||||
|
val maxSortIds = DataStoreUtils.getRefreshOldestActivityMaxSortPositions(context!!, contentUri, keys)
|
||||||
|
return@lazy Array(keys.size) { idx ->
|
||||||
|
SinceMaxPagination.maxId(maxIds[idx], maxSortIds[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val tabId: Long
|
||||||
|
get() = this@AbsActivitiesFragment.tabId
|
||||||
|
|
||||||
|
})
|
||||||
|
if (started) {
|
||||||
|
adapter.loadMoreIndicatorPosition = LoadMorePosition.END
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val activityColumnsLite = Activities.COLUMNS - arrayOf(Activities.SOURCES, Activities.TARGETS,
|
val activityColumnsLite = Activities.COLUMNS - arrayOf(Activities.SOURCES, Activities.TARGETS,
|
||||||
Activities.TARGET_OBJECTS, Activities.MENTIONS_JSON, Activities.CARD,
|
Activities.TARGET_OBJECTS, Activities.MENTIONS_JSON, Activities.CARD,
|
||||||
|
|
|
@ -70,6 +70,7 @@ import org.mariotaku.twidere.data.fetcher.StatusesFetcher
|
||||||
import org.mariotaku.twidere.extension.*
|
import org.mariotaku.twidere.extension.*
|
||||||
import org.mariotaku.twidere.extension.adapter.removeStatuses
|
import org.mariotaku.twidere.extension.adapter.removeStatuses
|
||||||
import org.mariotaku.twidere.extension.data.observe
|
import org.mariotaku.twidere.extension.data.observe
|
||||||
|
import org.mariotaku.twidere.extension.view.PositionWithOffset
|
||||||
import org.mariotaku.twidere.extension.view.firstVisibleItemPosition
|
import org.mariotaku.twidere.extension.view.firstVisibleItemPosition
|
||||||
import org.mariotaku.twidere.extension.view.firstVisibleItemPositionWithOffset
|
import org.mariotaku.twidere.extension.view.firstVisibleItemPositionWithOffset
|
||||||
import org.mariotaku.twidere.extension.view.lastVisibleItemPosition
|
import org.mariotaku.twidere.extension.view.lastVisibleItemPosition
|
||||||
|
@ -99,6 +100,7 @@ import org.mariotaku.twidere.view.holder.GapViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.TimelineFilterHeaderViewHolder
|
import org.mariotaku.twidere.view.holder.TimelineFilterHeaderViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||||
import org.mariotaku.twidere.view.holder.status.StatusViewHolder
|
import org.mariotaku.twidere.view.holder.status.StatusViewHolder
|
||||||
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableStatusesAdapter, LayoutManager>(),
|
abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableStatusesAdapter, LayoutManager>(),
|
||||||
IFloatingActionButtonFragment {
|
IFloatingActionButtonFragment {
|
||||||
|
@ -154,12 +156,14 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
private val busEventHandler = BusEventHandler()
|
private val busEventHandler = BusEventHandler()
|
||||||
private val scrollHandler = ScrollHandler()
|
private val scrollHandler = ScrollHandler()
|
||||||
private val timelineBoundaryCallback = StatusesBoundaryCallback()
|
private val timelineBoundaryCallback = StatusesBoundaryCallback()
|
||||||
|
private val positionBackup: AtomicReference<PositionWithOffset> = AtomicReference()
|
||||||
private var dataController: ExtendedPagedListProvider.DataController? = null
|
private var dataController: ExtendedPagedListProvider.DataController? = null
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
registerForContextMenu(recyclerView)
|
registerForContextMenu(recyclerView)
|
||||||
adapter.statusClickListener = StatusClickHandler()
|
adapter.statusClickListener = StatusClickHandler()
|
||||||
|
adapter.pagedListListener = this::onPagedListChanged
|
||||||
adapter.loadMoreSupportedPosition = if (isStandalone) {
|
adapter.loadMoreSupportedPosition = if (isStandalone) {
|
||||||
LoadMorePosition.NONE
|
LoadMorePosition.NONE
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,6 +289,9 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll to start of the timeline. This also updates read position
|
||||||
|
*/
|
||||||
override fun scrollToStart(): Boolean {
|
override fun scrollToStart(): Boolean {
|
||||||
val result = super.scrollToStart()
|
val result = super.scrollToStart()
|
||||||
if (result) saveReadPosition(0)
|
if (result) saveReadPosition(0)
|
||||||
|
@ -317,7 +324,6 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
showProgress()
|
showProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun onDataLoaded(data: PagedList<ParcelableStatus>?) {
|
protected open fun onDataLoaded(data: PagedList<ParcelableStatus>?) {
|
||||||
val firstVisiblePosition = layoutManager.firstVisibleItemPositionWithOffset
|
val firstVisiblePosition = layoutManager.firstVisibleItemPositionWithOffset
|
||||||
adapter.showAccountsColor = accountKeys.size > 1
|
adapter.showAccountsColor = accountKeys.size > 1
|
||||||
|
@ -331,18 +337,15 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
showContent()
|
showContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (firstVisiblePosition == null) return
|
positionBackup.set(firstVisiblePosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun onPagedListChanged(data: PagedList<ParcelableStatus>?) {
|
||||||
|
val firstVisiblePosition = positionBackup.getAndSet(null) ?: return
|
||||||
if (firstVisiblePosition.position == 0 && !preferences[readFromBottomKey]) {
|
if (firstVisiblePosition.position == 0 && !preferences[readFromBottomKey]) {
|
||||||
val weakThis by weak(this)
|
scrollToPositionWithOffset(0, 0)
|
||||||
recyclerView.post {
|
|
||||||
val f = weakThis?.takeIf { !it.isDetached && it.view != null } ?: return@post
|
|
||||||
f.scrollToStart()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val lm = loaderManager
|
scrollToPositionWithOffset(firstVisiblePosition.position, firstVisiblePosition.offset)
|
||||||
if (lm is LinearLayoutManager) {
|
|
||||||
lm.scrollToPositionWithOffset(firstVisiblePosition.position, firstVisiblePosition.offset)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +403,7 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
|
|
||||||
private fun setupLiveData() {
|
private fun setupLiveData() {
|
||||||
statuses = if (isStandalone) onCreateStandaloneLiveData() else onCreateDatabaseLiveData()
|
statuses = if (isStandalone) onCreateStandaloneLiveData() else onCreateDatabaseLiveData()
|
||||||
statuses?.observe(this, success = { onDataLoaded(it) }, fail = {
|
statuses?.observe(this, success = this::onDataLoaded, fail = {
|
||||||
showError(R.drawable.ic_info_error_generic, it.getErrorMessage(context!!))
|
showError(R.drawable.ic_info_error_generic, it.getErrorMessage(context!!))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -487,6 +490,19 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DefaultOnLikedListener(
|
||||||
|
private val context: Context,
|
||||||
|
private val status: ParcelableStatus,
|
||||||
|
private val accountKey: UserKey? = null
|
||||||
|
) : LikeAnimationDrawable.OnLikedListener {
|
||||||
|
|
||||||
|
override fun onLiked(): Boolean {
|
||||||
|
if (status.is_favorite) return false
|
||||||
|
CreateFavoriteTask(context, accountKey ?: status.account_key, status).promise()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal inner class BusEventHandler {
|
internal inner class BusEventHandler {
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
@ -634,19 +650,6 @@ abstract class AbsTimelineFragment : AbsContentRecyclerViewFragment<ParcelableSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultOnLikedListener(
|
|
||||||
private val context: Context,
|
|
||||||
private val status: ParcelableStatus,
|
|
||||||
private val accountKey: UserKey? = null
|
|
||||||
) : LikeAnimationDrawable.OnLikedListener {
|
|
||||||
|
|
||||||
override fun onLiked(): Boolean {
|
|
||||||
if (status.is_favorite) return false
|
|
||||||
CreateFavoriteTask(context, accountKey ?: status.account_key, status).promise()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val REQUEST_FAVORITE_SELECT_ACCOUNT = 101
|
const val REQUEST_FAVORITE_SELECT_ACCOUNT = 101
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.twidere.model.placeholder
|
||||||
|
|
||||||
|
import org.mariotaku.twidere.model.ParcelableActivity
|
||||||
|
import org.mariotaku.twidere.model.UserKey
|
||||||
|
|
||||||
|
object ParcelableActivityPlaceholder : ParcelableActivity() {
|
||||||
|
init {
|
||||||
|
id = "none"
|
||||||
|
account_key = UserKey.INVALID
|
||||||
|
user_key = UserKey.INVALID
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue