diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileDataSourceFactory.kt b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileDataSourceFactory.kt deleted file mode 100644 index 3768f83..0000000 --- a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileDataSourceFactory.kt +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2020 Conny Duck - * - * This file is part of Pixelcat. - * - * Pixelcat 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. - * - * Pixelcat 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 . - */ - -package at.connyduck.pixelcat.components.profile - -import androidx.paging.DataSource -import androidx.paging.ItemKeyedDataSource -import at.connyduck.pixelcat.db.AccountManager -import at.connyduck.pixelcat.model.Status -import at.connyduck.pixelcat.network.FediverseApi -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch - -class ProfileDataSourceFactory( - private val api: FediverseApi, - private val accountId: String?, - private val accountManager: AccountManager, - private val scope: CoroutineScope -) : DataSource.Factory() { - - override fun create(): DataSource { - val source = ProfileImageDataSource(api, accountId, accountManager, scope) - return source - } -} - -class ProfileImageDataSource( - private val api: FediverseApi, - private val accountId: String?, - private val accountManager: AccountManager, - private val scope: CoroutineScope -) : ItemKeyedDataSource() { - override fun loadInitial( - params: LoadInitialParams, - callback: LoadInitialCallback - ) { - scope.launch(context = Dispatchers.IO) { - val id = accountId ?: accountManager.activeAccount()?.accountId!! - api.accountStatuses( - id, - limit = params.requestedLoadSize, - onlyMedia = true, - excludeReblogs = true - ).fold( - { - callback.onResult(it) - }, - { - } - ) - } - } - - override fun loadAfter(params: LoadParams, callback: LoadCallback) { - scope.launch(context = Dispatchers.IO) { - val id = accountId ?: accountManager.activeAccount()?.accountId!! - api.accountStatuses( - id, - maxId = params.key, - limit = params.requestedLoadSize, - onlyMedia = true, - excludeReblogs = true - ).fold( - { - callback.onResult(it) - }, - { - } - ) - } - } - - override fun loadBefore(params: LoadParams, callback: LoadCallback) { - // we always load from top - } - - override fun getKey(item: Status) = item.id -} diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileFragment.kt b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileFragment.kt index c3ff47a..053df22 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileFragment.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileFragment.kt @@ -23,6 +23,8 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.viewModels import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope +import androidx.paging.ExperimentalPagingApi import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.MergeAdapter import at.connyduck.pixelcat.R @@ -41,6 +43,8 @@ import at.connyduck.pixelcat.util.viewBinding import at.connyduck.pixelcat.util.withArgs import com.google.android.material.snackbar.Snackbar import dagger.android.support.DaggerFragment +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch import javax.inject.Inject class ProfileFragment : DaggerFragment(R.layout.fragment_profile) { @@ -60,6 +64,7 @@ class ProfileFragment : DaggerFragment(R.layout.fragment_profile) { private val headerAdapter = ProfileHeaderAdapter() private lateinit var imageAdapter: ProfileImageAdapter + @ExperimentalPagingApi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { if (activity is MainActivity) { @@ -124,12 +129,9 @@ class ProfileFragment : DaggerFragment(R.layout.fragment_profile) { } } ) - viewModel.profileImages.observe( - viewLifecycleOwner, - Observer { - imageAdapter.submitList(it) - } - ) + lifecycleScope.launch { + viewModel.imageFlow.collectLatest { imageAdapter.submitData(it) } + } } private fun onAccountChanged(account: Account?) { diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImageAdapter.kt b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImageAdapter.kt index bb70402..e2ad621 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImageAdapter.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImageAdapter.kt @@ -21,7 +21,7 @@ package at.connyduck.pixelcat.components.profile import android.view.LayoutInflater import android.view.ViewGroup -import androidx.paging.PagedListAdapter +import androidx.paging.PagingDataAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import at.connyduck.pixelcat.R @@ -34,7 +34,7 @@ import coil.api.load class ProfileImageAdapter( private val imageSizePx: Int -) : PagedListAdapter( +) : PagingDataAdapter( object : DiffUtil.ItemCallback() { override fun areItemsTheSame(old: Status, new: Status): Boolean { return false diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImagePagingSource.kt b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImagePagingSource.kt new file mode 100644 index 0000000..29f4c40 --- /dev/null +++ b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileImagePagingSource.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 Conny Duck + * + * This file is part of Pixelcat. + * + * Pixelcat 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. + * + * Pixelcat 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 . + */ + +package at.connyduck.pixelcat.components.profile + +import androidx.paging.PagingSource +import at.connyduck.pixelcat.db.AccountManager +import at.connyduck.pixelcat.model.Status +import at.connyduck.pixelcat.network.FediverseApi + +class ProfileImagePagingSource( + private val api: FediverseApi, + private val accountId: String?, + private val accountManager: AccountManager +) : PagingSource() { + + override suspend fun load(params: LoadParams): LoadResult { + + if (params is LoadParams.Prepend) { + // we only load from top + return LoadResult.Page(data = emptyList(), nextKey = null, prevKey = null) + } + + val id = accountId ?: accountManager.activeAccount()?.accountId!! + + return api.accountStatuses( + id, + maxId = params.key, + limit = params.loadSize, + onlyMedia = true, + excludeReblogs = true + ).fold( + { + LoadResult.Page(data = it, prevKey = null, nextKey = it.lastOrNull()?.id) + }, + { + LoadResult.Error(it) + } + ) + } +} diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileViewModel.kt b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileViewModel.kt index 27a1c0e..a9c8b8c 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileViewModel.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/components/profile/ProfileViewModel.kt @@ -22,16 +22,18 @@ package at.connyduck.pixelcat.components.profile import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import androidx.paging.PagedList +import androidx.paging.ExperimentalPagingApi +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.cachedIn import at.connyduck.pixelcat.components.util.Error import at.connyduck.pixelcat.components.util.Success import at.connyduck.pixelcat.components.util.UiState import at.connyduck.pixelcat.db.AccountManager import at.connyduck.pixelcat.model.Account import at.connyduck.pixelcat.model.Relationship -import at.connyduck.pixelcat.model.Status import at.connyduck.pixelcat.network.FediverseApi -import com.bumptech.glide.util.Executors +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.launch import javax.inject.Inject @@ -42,7 +44,14 @@ class ProfileViewModel @Inject constructor( val profile = MutableLiveData>() val relationship = MutableLiveData>() - val profileImages = MutableLiveData>() + + @OptIn(FlowPreview::class) + @ExperimentalPagingApi + val imageFlow = Pager( + config = PagingConfig(pageSize = 10, enablePlaceholders = false), + pagingSourceFactory = { ProfileImagePagingSource(fediverseApi, accountId, accountManager) } + ).flow + .cachedIn(viewModelScope) val isSelf: Boolean get() = accountId == null @@ -54,7 +63,6 @@ class ProfileViewModel @Inject constructor( if (!isSelf) { loadRelationship(reload) } - loadImages(reload) } fun setAccountInfo(accountId: String?) { @@ -92,22 +100,6 @@ class ProfileViewModel @Inject constructor( } } - private fun loadImages(reload: Boolean = false) { - if (profileImages.value == null || reload) { - profileImages.value = PagedList.Builder( - ProfileImageDataSource( - fediverseApi, - accountId, - accountManager, - viewModelScope - ), - 20 - ).setNotifyExecutor(Executors.mainThreadExecutor()) - .setFetchExecutor(java.util.concurrent.Executors.newSingleThreadExecutor()) - .build() - } - } - private suspend fun getAccountId(): String { return accountId ?: accountManager.activeAccount()?.accountId!! } diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/db/AccountManager.kt b/app/src/main/kotlin/at/connyduck/pixelcat/db/AccountManager.kt index 589b7fe..2c3a12d 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/db/AccountManager.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/db/AccountManager.kt @@ -17,8 +17,6 @@ * along with this program. If not, see . */ - - package at.connyduck.pixelcat.db import android.util.Log diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/AccountEntity.kt b/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/AccountEntity.kt index 23e8028..4da8bf9 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/AccountEntity.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/AccountEntity.kt @@ -17,8 +17,6 @@ * along with this program. If not, see . */ - - package at.connyduck.pixelcat.db.entitity import androidx.room.Embedded diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/TimelineStatusEntity.kt b/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/TimelineStatusEntity.kt index 6b924d8..c633952 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/TimelineStatusEntity.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/db/entitity/TimelineStatusEntity.kt @@ -17,8 +17,6 @@ * along with this program. If not, see . */ - - package at.connyduck.pixelcat.db.entitity import androidx.room.Embedded diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/model/Attachment.kt b/app/src/main/kotlin/at/connyduck/pixelcat/model/Attachment.kt index 4555fe4..dca8044 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/model/Attachment.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/model/Attachment.kt @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - package at.connyduck.pixelcat.model import android.os.Parcelable diff --git a/app/src/main/kotlin/at/connyduck/pixelcat/model/Status.kt b/app/src/main/kotlin/at/connyduck/pixelcat/model/Status.kt index 406bf7f..833fbfc 100644 --- a/app/src/main/kotlin/at/connyduck/pixelcat/model/Status.kt +++ b/app/src/main/kotlin/at/connyduck/pixelcat/model/Status.kt @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - package at.connyduck.pixelcat.model import com.squareup.moshi.Json