deletes favorites when unfavorited

fixed #736
This commit is contained in:
Mariotaku Lee 2017-03-28 22:48:05 +08:00
parent 1fc37b253e
commit d621430fab
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
4 changed files with 127 additions and 95 deletions

View File

@ -47,6 +47,18 @@ import java.util.*
*/ */
abstract class ParcelableStatusesFragment : AbsStatusesFragment() { abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
override var refreshing: Boolean
get() {
if (context == null || isDetached) return false
return loaderManager.hasRunningLoadersSafe()
}
set(value) {
super.refreshing = value
}
protected open val savedStatusesFileArgs: Array<String>?
get() = null
private var lastId: String? = null private var lastId: String? = null
private var page = 1 private var page = 1
private var pageDelta: Int = 0 private var pageDelta: Int = 0
@ -58,22 +70,19 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
} }
} }
fun deleteStatus(statusId: String) { override fun onStart() {
val list = adapterData ?: return super.onStart()
val dataToRemove = HashSet<ParcelableStatus>() bus.register(this)
for (i in 0 until list.size) { }
val status = list[i]
if (status.id == statusId || status.retweet_id == statusId) { override fun onStop() {
dataToRemove.add(status) bus.unregister(this)
} else if (status.my_retweet_id == statusId) { super.onStop()
status.my_retweet_id = null }
status.retweet_count = status.retweet_count - 1
} override fun onSaveInstanceState(outState: Bundle) {
} super.onSaveInstanceState(outState)
if (list is MutableList) { outState.putInt(EXTRA_PAGE, page)
list.removeAll(dataToRemove)
}
adapterData = list
} }
override fun getStatuses(param: RefreshTaskParam): Boolean { override fun getStatuses(param: RefreshTaskParam): Boolean {
@ -99,16 +108,6 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
return true return true
} }
override fun onStart() {
super.onStart()
bus.register(this)
}
override fun onStop() {
bus.unregister(this)
super.onStop()
}
override fun hasMoreData(data: List<ParcelableStatus>?): Boolean { override fun hasMoreData(data: List<ParcelableStatus>?): Boolean {
if (data == null || data.isEmpty()) return false if (data == null || data.isEmpty()) return false
val tmpLastId = lastId val tmpLastId = lastId
@ -164,6 +163,43 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
getStatuses(param) getStatuses(param)
} }
override fun triggerRefresh(): Boolean {
super.triggerRefresh()
val accountKeys = accountKeys
if (adapter.getStatusCount(true) > 0) {
val firstStatus = adapter.getStatus(0, true)
val sinceIds = Array(accountKeys.size) {
return@Array if (firstStatus.account_key == accountKeys[it]) firstStatus.id else null
}
getStatuses(BaseRefreshTaskParam(accountKeys, null, sinceIds))
} else {
getStatuses(BaseRefreshTaskParam(accountKeys, null, null))
}
return true
}
override fun onHasMoreDataChanged(hasMoreData: Boolean) {
pageDelta = if (hasMoreData) 1 else 0
}
fun removeStatus(statusId: String) {
val list = adapterData ?: return
val dataToRemove = HashSet<ParcelableStatus>()
for (i in 0 until list.size) {
val status = list[i]
if (status.id == statusId || status.retweet_id == statusId) {
dataToRemove.add(status)
} else if (status.my_retweet_id == statusId) {
status.my_retweet_id = null
status.retweet_count = status.retweet_count - 1
}
}
if (list is MutableList) {
list.removeAll(dataToRemove)
}
adapterData = list
}
fun replaceStatusStates(status: ParcelableStatus?) { fun replaceStatusStates(status: ParcelableStatus?) {
if (status == null) return if (status == null) return
val lm = layoutManager val lm = layoutManager
@ -182,41 +218,6 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
adapter.notifyItemRangeChanged(rangeStart, rangeEnd) adapter.notifyItemRangeChanged(rangeStart, rangeEnd)
} }
override fun triggerRefresh(): Boolean {
super.triggerRefresh()
val accountKeys = accountKeys
if (adapter.getStatusCount(true) > 0) {
val firstStatus = adapter.getStatus(0, true)
val sinceIds = Array(accountKeys.size) {
return@Array if (firstStatus.account_key == accountKeys[it]) firstStatus.id else null
}
getStatuses(BaseRefreshTaskParam(accountKeys, null, sinceIds))
} else {
getStatuses(BaseRefreshTaskParam(accountKeys, null, null))
}
return true
}
override var refreshing: Boolean
get() {
if (context == null || isDetached) return false
return loaderManager.hasRunningLoadersSafe()
}
set(value) {
super.refreshing = value
}
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
outState!!.putInt(EXTRA_PAGE, page)
}
protected open val savedStatusesFileArgs: Array<String>?
get() = null
override fun onHasMoreDataChanged(hasMoreData: Boolean) {
pageDelta = if (hasMoreData) 1 else 0
}
private fun updateFavoritedStatus(status: ParcelableStatus) { private fun updateFavoritedStatus(status: ParcelableStatus) {
replaceStatusStates(status) replaceStatusStates(status)
@ -234,28 +235,44 @@ abstract class ParcelableStatusesFragment : AbsStatusesFragment() {
adapterData = data adapterData = data
} }
protected open fun notifyFavoriteTask(event: FavoriteTaskEvent) {
if (event.isSucceeded) {
updateFavoritedStatus(event.status!!)
}
}
protected open fun notifyStatusDestroyed(event: StatusDestroyedEvent) {
removeStatus(event.status.id)
}
protected open fun notifyStatusListChanged(event: StatusListChangedEvent) {
adapter.notifyDataSetChanged()
}
protected open fun notifyStatusRetweeted(event: StatusRetweetedEvent) {
updateRetweetedStatuses(event.status)
}
protected inner class ParcelableStatusesBusCallback { protected inner class ParcelableStatusesBusCallback {
@Subscribe @Subscribe
fun notifyFavoriteTask(event: FavoriteTaskEvent) { fun onFavoriteTaskEvent(event: FavoriteTaskEvent) {
if (event.isSucceeded) { notifyFavoriteTask(event)
updateFavoritedStatus(event.status!!)
}
} }
@Subscribe @Subscribe
fun notifyStatusDestroyed(event: StatusDestroyedEvent) { fun onStatusDestroyedEvent(event: StatusDestroyedEvent) {
deleteStatus(event.status.id) notifyStatusDestroyed(event)
} }
@Subscribe @Subscribe
fun notifyStatusListChanged(event: StatusListChangedEvent) { fun onStatusListChangedEvent(event: StatusListChangedEvent) {
adapter.notifyDataSetChanged() notifyStatusListChanged(event)
} }
@Subscribe @Subscribe
fun notifyStatusRetweeted(event: StatusRetweetedEvent) { fun onStatusRetweetedEvent(event: StatusRetweetedEvent) {
updateRetweetedStatuses(event.status) notifyStatusRetweeted(event)
} }
} }

View File

@ -27,6 +27,7 @@ import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.loader.UserFavoritesLoader import org.mariotaku.twidere.loader.UserFavoritesLoader
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.model.event.FavoriteTaskEvent
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
import java.util.* import java.util.*
@ -35,23 +36,6 @@ import java.util.*
*/ */
class UserFavoritesFragment : ParcelableStatusesFragment() { class UserFavoritesFragment : ParcelableStatusesFragment() {
override fun onCreateStatusesLoader(context: Context,
args: Bundle,
fromUser: Boolean): Loader<List<ParcelableStatus>?> {
refreshing = true
val accountKey = Utils.getAccountKey(context, args)
val maxId = args.getString(EXTRA_MAX_ID)
val sinceId = args.getString(EXTRA_SINCE_ID)
val page = args.getInt(EXTRA_PAGE, -1)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME)
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return UserFavoritesLoader(context, accountKey, userKey, screenName, sinceId, maxId,
page, adapterData, savedStatusesFileArgs, tabPosition, fromUser,
loadingMore)
}
override val savedStatusesFileArgs: Array<String>? override val savedStatusesFileArgs: Array<String>?
get() { get() {
val args = arguments!! val args = arguments!!
@ -71,7 +55,6 @@ class UserFavoritesFragment : ParcelableStatusesFragment() {
return result.toTypedArray() return result.toTypedArray()
} }
override val readPositionTagWithArguments: String? override val readPositionTagWithArguments: String?
get() { get() {
val args = arguments!! val args = arguments!!
@ -91,6 +74,39 @@ class UserFavoritesFragment : ParcelableStatusesFragment() {
return sb.toString() return sb.toString()
} }
@TimelineType @TimelineType
override val timelineType: String = TimelineType.OTHER override val timelineType: String = TimelineType.OTHER
override fun onCreateStatusesLoader(context: Context, args: Bundle, fromUser: Boolean):
Loader<List<ParcelableStatus>?> {
refreshing = true
val accountKey = Utils.getAccountKey(context, args)
val maxId = args.getString(EXTRA_MAX_ID)
val sinceId = args.getString(EXTRA_SINCE_ID)
val page = args.getInt(EXTRA_PAGE, -1)
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
val screenName = args.getString(EXTRA_SCREEN_NAME)
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
return UserFavoritesLoader(context, accountKey, userKey, screenName, sinceId, maxId,
page, adapterData, savedStatusesFileArgs, tabPosition, fromUser,
loadingMore)
}
override fun notifyFavoriteTask(event: FavoriteTaskEvent) {
if (event.action == FavoriteTaskEvent.Action.DESTROY && event.isSucceeded) {
event.status?.let { status ->
val args = arguments!!
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
if (status.account_key == userKey) {
removeStatus(event.statusId)
triggerRefresh()
return
}
}
}
super.notifyFavoriteTask(event)
}
} }

View File

@ -96,8 +96,7 @@ class DestroyFavoriteTask(
override fun afterExecute(callback: Any?, result: SingleResponse<ParcelableStatus>) { override fun afterExecute(callback: Any?, result: SingleResponse<ParcelableStatus>) {
destroyingFavoriteIds.removeElement(AsyncTwitterWrapper.calculateHashCode(accountKey, statusId)) destroyingFavoriteIds.removeElement(AsyncTwitterWrapper.calculateHashCode(accountKey, statusId))
val taskEvent = FavoriteTaskEvent(FavoriteTaskEvent.Action.DESTROY, val taskEvent = FavoriteTaskEvent(FavoriteTaskEvent.Action.DESTROY, accountKey, statusId)
accountKey, statusId)
taskEvent.isFinished = true taskEvent.isFinished = true
if (result.hasData()) { if (result.hasData()) {
val status = result.data val status = result.data

View File

@ -58,10 +58,6 @@
android:icon="@drawable/ic_action_delete" android:icon="@drawable/ic_action_delete"
android:title="@string/action_delete" android:title="@string/action_delete"
android:visible="false"/> android:visible="false"/>
<item
android:id="@id/open_in_browser"
android:icon="@drawable/ic_action_web"
android:title="@string/action_open_in_browser"/>
<item <item
android:id="@id/copy_url" android:id="@id/copy_url"
android:icon="@drawable/ic_action_link" android:icon="@drawable/ic_action_link"
@ -70,5 +66,9 @@
android:id="@id/open_with_account" android:id="@id/open_with_account"
android:icon="@drawable/ic_action_accounts" android:icon="@drawable/ic_action_accounts"
android:title="@string/open_with_account"/> android:title="@string/open_with_account"/>
<item
android:id="@id/open_in_browser"
android:icon="@drawable/ic_action_web"
android:title="@string/action_open_in_browser"/>
</menu> </menu>