Fix PrivateMessageDataSource making way to many requests

This commit is contained in:
Balazs Toldi 2023-08-18 13:18:21 +02:00
parent 3e17e3364d
commit bae68d4a99
No known key found for this signature in database
GPG Key ID: 6C7D440036F99D58
4 changed files with 65 additions and 158 deletions

View File

@ -110,7 +110,7 @@ public class PrivateMessageFragment extends Fragment implements FragmentCommunic
}
mAdapter = new PrivateMessageRecycleViewAdapter(mActivity, mRetrofit.getRetrofit(), mCustomThemeWrapper, mAccessToken, mLemmyPrivateMessageAPI, () -> mMessageViewModel.retryLoadingMore());
mAdapter = new PrivateMessageRecycleViewAdapter(mActivity, mRetrofit.getRetrofit(), mCustomThemeWrapper, mAccessToken, mLemmyPrivateMessageAPI, () -> mMessageViewModel.refresh());
mLinearLayoutManager = new LinearLayoutManagerBugFixed(mActivity);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAdapter);
@ -133,19 +133,10 @@ public class PrivateMessageFragment extends Fragment implements FragmentCommunic
PrivateMessageViewModel.Factory factory = new PrivateMessageViewModel.Factory(mRetrofit.getRetrofit(),
getResources().getConfiguration().locale, mAccessToken, mLemmyPrivateMessageAPI);
mMessageViewModel = new ViewModelProvider(this, factory).get(PrivateMessageViewModel.class);
mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages));
mMessageViewModel.getPrivateMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages));
mMessageViewModel.hasMessage().observe(getViewLifecycleOwner(), hasMessage -> {
mSwipeRefreshLayout.setRefreshing(false);
if (hasMessage) {
mFetchMessageInfoLinearLayout.setVisibility(View.GONE);
} else {
mFetchMessageInfoLinearLayout.setOnClickListener(null);
showErrorView(R.string.no_messages);
}
});
mMessageViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> {
mMessageViewModel.getInitialLoadState().observe(getViewLifecycleOwner(), networkState -> {
if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) {
mSwipeRefreshLayout.setRefreshing(false);
} else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) {
@ -161,9 +152,6 @@ public class PrivateMessageFragment extends Fragment implements FragmentCommunic
}
});
mMessageViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> {
mAdapter.setNetworkState(networkState);
});
mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh);
@ -216,14 +204,14 @@ public class PrivateMessageFragment extends Fragment implements FragmentCommunic
private void onRefresh() {
mMessageViewModel.refresh();
mAdapter.setNetworkState(null);
mSwipeRefreshLayout.setRefreshing(false);
}
public PrivateMessage getMessageByIndex(int index) {
if (mMessageViewModel == null || index < 0) {
return null;
}
PagedList<PrivateMessage> messages = mMessageViewModel.getMessages().getValue();
PagedList<PrivateMessage> messages = mMessageViewModel.getPrivateMessages().getValue();
if (messages == null) {
return null;
}

View File

@ -3,61 +3,62 @@ package eu.toldi.infinityforlemmy.privatemessage
import androidx.lifecycle.MutableLiveData
import androidx.paging.PageKeyedDataSource
import eu.toldi.infinityforlemmy.NetworkState
import retrofit2.Retrofit
import java.util.Locale
class PrivateMessageDataSource(
private val retrofit: Retrofit,
private val locale: Locale,
private val accessToken: String,
private val mLemmyPrivateMessageAPI: LemmyPrivateMessageAPI
) :
PageKeyedDataSource<Int, PrivateMessage>() {
private val mLemmyPrivateMessageAPI: LemmyPrivateMessageAPI,
private val accessToken: String
) : PageKeyedDataSource<Int, PrivateMessage>() {
val paginationNetworkStateLiveData: MutableLiveData<NetworkState> = MutableLiveData()
val initialLoadStateLiveData: MutableLiveData<NetworkState>
private val hasPostLiveData: MutableLiveData<Boolean>
private var params: LoadParams<Int>? = null
private var callback: LoadCallback<Int, PrivateMessage>? = null
private val page = 1
init {
initialLoadStateLiveData = MutableLiveData()
hasPostLiveData = MutableLiveData()
}
fun hasPostLiveData(): MutableLiveData<Boolean> {
return hasPostLiveData
}
fun retryLoadingMore() {
loadAfter(params!!, callback!!)
}
val initialLoadStateLiveData = MutableLiveData<NetworkState>()
override fun loadInitial(
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, PrivateMessage>
) {
initialLoadStateLiveData.postValue(NetworkState.LOADING)
mLemmyPrivateMessageAPI.fetchPrivateMessages(accessToken, page, object :
mLemmyPrivateMessageAPI.fetchPrivateMessages(accessToken, 1, object :
LemmyPrivateMessageAPI.PrivateMessageFetchedListener {
override fun onPrivateMessageFetchedSuccess(privateMessages: List<PrivateMessage>) {
hasPostLiveData.postValue(true)
initialLoadStateLiveData.postValue(NetworkState.LOADED)
if (privateMessages.isEmpty()) {
callback.onResult(ArrayList(), null, null)
} else {
callback.onResult(privateMessages, null, 2)
}
initialLoadStateLiveData.postValue(NetworkState.LOADED)
}
override fun onPrivateMessageFetchedError() {
initialLoadStateLiveData.postValue(
NetworkState(
NetworkState.Status.FAILED,
"Error fetch messages"
"Error fetching messages"
)
)
}
})
}
override fun loadAfter(
params: LoadParams<Int>,
callback: LoadCallback<Int, PrivateMessage>
) {
mLemmyPrivateMessageAPI.fetchPrivateMessages(accessToken, params.key, object :
LemmyPrivateMessageAPI.PrivateMessageFetchedListener {
override fun onPrivateMessageFetchedSuccess(privateMessages: List<PrivateMessage>) {
initialLoadStateLiveData.postValue(NetworkState.LOADED)
if (privateMessages.isEmpty()) {
callback.onResult(ArrayList(), null)
} else {
callback.onResult(privateMessages, params.key + 1)
}
}
override fun onPrivateMessageFetchedError() {
initialLoadStateLiveData.postValue(
NetworkState(
NetworkState.Status.FAILED,
"Error fetching messages"
)
)
}
@ -68,35 +69,10 @@ class PrivateMessageDataSource(
params: LoadParams<Int>,
callback: LoadCallback<Int, PrivateMessage>
) {
}
override fun loadAfter(
params: LoadParams<Int>,
callback: LoadCallback<Int, PrivateMessage>
) {
this.params = params
this.callback = callback
paginationNetworkStateLiveData.postValue(NetworkState.LOADING)
mLemmyPrivateMessageAPI.fetchPrivateMessages(accessToken, params.key, object :
LemmyPrivateMessageAPI.PrivateMessageFetchedListener {
override fun onPrivateMessageFetchedSuccess(privateMessages: List<PrivateMessage>) {
hasPostLiveData.postValue(true)
if (privateMessages.isEmpty()) {
callback.onResult(ArrayList(), null)
} else {
callback.onResult(privateMessages, params.key + 1)
}
paginationNetworkStateLiveData.postValue(NetworkState.LOADED)
}
override fun onPrivateMessageFetchedError() {
paginationNetworkStateLiveData.postValue(
NetworkState(
NetworkState.Status.FAILED,
"Error fetch messages"
)
)
}
})
fun refresh() {
invalidate()
}
}

View File

@ -2,36 +2,19 @@ package eu.toldi.infinityforlemmy.privatemessage
import androidx.lifecycle.MutableLiveData
import androidx.paging.DataSource
import retrofit2.Retrofit
import java.util.Locale
internal class PrivateMessageDataSourceFactory(
retrofit: Retrofit,
locale: Locale,
accessToken: String,
private var mLemmyPrivateMessageAPI: LemmyPrivateMessageAPI
class PrivateMessageDataSourceFactory(
private val mLemmyPrivateMessageAPI: LemmyPrivateMessageAPI,
private val accessToken: String
) : DataSource.Factory<Int, PrivateMessage>() {
private val mPrivateMessageDataSource: PrivateMessageDataSource =
PrivateMessageDataSource(retrofit, locale, accessToken, mLemmyPrivateMessageAPI)
private val messageDataSourceLiveData: MutableLiveData<PrivateMessageDataSource> =
MutableLiveData<PrivateMessageDataSource>()
val dataSourceLiveData = MutableLiveData<PrivateMessageDataSource>()
override fun create(): DataSource<Int, PrivateMessage> {
messageDataSourceLiveData.postValue(mPrivateMessageDataSource)
return mPrivateMessageDataSource
val dataSource = PrivateMessageDataSource(mLemmyPrivateMessageAPI, accessToken)
dataSourceLiveData.postValue(dataSource)
return dataSource
}
fun getMessageDataSourceLiveData(): MutableLiveData<PrivateMessageDataSource> {
return messageDataSourceLiveData
}
fun getMessageDataSource(): PrivateMessageDataSource {
return mPrivateMessageDataSource
}
fun changeLemmPrivateMessageAPI(lemmyPrivateMessageAPI: LemmyPrivateMessageAPI) {
this.mLemmyPrivateMessageAPI = lemmyPrivateMessageAPI
}
}

View File

@ -1,76 +1,38 @@
package eu.toldi.infinityforlemmy.privatemessage
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import eu.toldi.infinityforlemmy.NetworkState
import retrofit2.Retrofit
import java.util.Locale
class PrivateMessageViewModel(
retrofit: Retrofit,
locale: Locale,
accessToken: String,
lemmyPrivateMessageAPI: LemmyPrivateMessageAPI
) :
ViewModel() {
private val messageDataSourceFactory: PrivateMessageDataSourceFactory
val paginationNetworkState: LiveData<NetworkState>
val initialLoadingState: LiveData<NetworkState>
private val hasMessageLiveData: LiveData<Boolean>
val messages: LiveData<PagedList<PrivateMessage>>
private val whereLiveData: MutableLiveData<LemmyPrivateMessageAPI> = MutableLiveData()
private val mLemmyPrivateMessageAPI: LemmyPrivateMessageAPI,
private val accessToken: String
) : ViewModel() {
init {
messageDataSourceFactory =
PrivateMessageDataSourceFactory(retrofit, locale, accessToken, lemmyPrivateMessageAPI)
initialLoadingState = Transformations.switchMap(
messageDataSourceFactory.getMessageDataSourceLiveData(),
PrivateMessageDataSource::initialLoadStateLiveData
)
paginationNetworkState = Transformations.switchMap(
messageDataSourceFactory.getMessageDataSourceLiveData(),
PrivateMessageDataSource::paginationNetworkStateLiveData
)
hasMessageLiveData = Transformations.switchMap(
messageDataSourceFactory.getMessageDataSourceLiveData(),
PrivateMessageDataSource::hasPostLiveData
)
private val dataSourceFactory =
PrivateMessageDataSourceFactory(mLemmyPrivateMessageAPI, accessToken)
whereLiveData.postValue(lemmyPrivateMessageAPI)
val pagedListConfig: PagedList.Config = PagedList.Config.Builder()
val privateMessages = LivePagedListBuilder(
dataSourceFactory, PagedList.Config.Builder()
.setPageSize(20)
.setEnablePlaceholders(false)
.setPageSize(25)
.build()
messages = Transformations.switchMap<LemmyPrivateMessageAPI, PagedList<PrivateMessage>>(
whereLiveData
) { newWhere: LemmyPrivateMessageAPI? ->
messageDataSourceFactory.changeLemmPrivateMessageAPI(whereLiveData.value!!)
LivePagedListBuilder(
messageDataSourceFactory,
pagedListConfig
).build()
}
)
.build()
}
fun hasMessage(): LiveData<Boolean> {
return hasMessageLiveData
val initialLoadState = Transformations.switchMap(dataSourceFactory.dataSourceLiveData) {
it.initialLoadStateLiveData
}
fun refresh() {
messageDataSourceFactory.getMessageDataSource().invalidate()
dataSourceFactory.dataSourceLiveData.value?.refresh()
}
fun retryLoadingMore() {
messageDataSourceFactory.getMessageDataSource().retryLoadingMore()
}
class Factory(
private val retrofit: Retrofit,
@ -82,10 +44,8 @@ class PrivateMessageViewModel(
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return PrivateMessageViewModel(
retrofit,
locale,
lemmyPrivateMessageAPI,
accessToken,
lemmyPrivateMessageAPI
) as T
}
}