mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +01:00 
			
		
		
		
	* Fixes #3389 - Show User profiles * Don't show dummy achievements data - show data only when loaded
This commit is contained in:
		
							parent
							
								
									7ce80aa804
								
							
						
					
					
						commit
						88b21a678e
					
				
					 20 changed files with 358 additions and 48 deletions
				
			
		|  | @ -21,6 +21,8 @@ class ContributionBoundaryCallback @Inject constructor( | |||
|     @param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler | ||||
| ) : BoundaryCallback<Contribution>() { | ||||
|     private val compositeDisposable: CompositeDisposable = CompositeDisposable() | ||||
|     lateinit var userName: String | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * It is triggered when the list has no items User's Contributions are then fetched from the | ||||
|  | @ -55,7 +57,7 @@ class ContributionBoundaryCallback @Inject constructor( | |||
|     fun fetchContributions() { | ||||
|         if (sessionManager.userName != null) { | ||||
|             compositeDisposable.add( | ||||
|                 mediaClient.getMediaListForUser(sessionManager.userName!!) | ||||
|                 mediaClient.getMediaListForUser(userName!!) | ||||
|                     .map { mediaList -> | ||||
|                         mediaList.map { | ||||
|                             Contribution(media = it, state = Contribution.STATE_COMPLETED) | ||||
|  | @ -88,4 +90,11 @@ class ContributionBoundaryCallback @Inject constructor( | |||
|                 } | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Clean up | ||||
|      */ | ||||
|     fun dispose() { | ||||
|         compositeDisposable.dispose() | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ import static android.view.View.VISIBLE; | |||
| import static fr.free.nrw.commons.di.NetworkingModule.NAMED_LANGUAGE_WIKI_PEDIA_WIKI_SITE; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.content.res.Configuration; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
|  | @ -21,6 +20,7 @@ import android.widget.ProgressBar; | |||
| import android.widget.TextView; | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.widget.AppCompatTextView; | ||||
| import androidx.fragment.app.FragmentManager; | ||||
| import androidx.recyclerview.widget.GridLayoutManager; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
|  | @ -35,17 +35,20 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||
| import fr.free.nrw.commons.Media; | ||||
| import fr.free.nrw.commons.R; | ||||
| import fr.free.nrw.commons.Utils; | ||||
| import fr.free.nrw.commons.customselector.ui.selector.CustomSelectorActivity; | ||||
| import fr.free.nrw.commons.auth.SessionManager; | ||||
| import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; | ||||
| import fr.free.nrw.commons.utils.DialogUtil; | ||||
| import fr.free.nrw.commons.media.MediaClient; | ||||
| import fr.free.nrw.commons.utils.SystemThemeUtils; | ||||
| import fr.free.nrw.commons.utils.ViewUtil; | ||||
| import java.util.Locale; | ||||
| import java.util.Objects; | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.wikipedia.dataclient.WikiSite; | ||||
| import timber.log.Timber; | ||||
| import fr.free.nrw.commons.profile.ProfileActivity; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Created by root on 01.06.2018. | ||||
|  | @ -56,7 +59,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|     WikipediaInstructionsDialogFragment.Callback { | ||||
| 
 | ||||
|     private static final String RV_STATE = "rv_scroll_state"; | ||||
|        | ||||
| 
 | ||||
|     @BindView(R.id.contributionsList) | ||||
|     RecyclerView rvContributionsList; | ||||
|     @BindView(R.id.loadingContributionsProgressBar) | ||||
|  | @ -76,6 +79,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
| 
 | ||||
|     @Inject | ||||
|     SystemThemeUtils systemThemeUtils; | ||||
|     @BindView(R.id.tv_contributions_of_user) | ||||
|     AppCompatTextView tvContributionsOfUser; | ||||
| 
 | ||||
|     @Inject | ||||
|     ContributionController controller; | ||||
|  | @ -89,6 +94,9 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|     @Inject | ||||
|     ContributionsListPresenter contributionsListPresenter; | ||||
| 
 | ||||
|     @Inject | ||||
|     SessionManager sessionManager; | ||||
| 
 | ||||
|     private Animation fab_close; | ||||
|     private Animation fab_open; | ||||
|     private Animation rotate_forward; | ||||
|  | @ -105,8 +113,23 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|     private final int SPAN_COUNT_PORTRAIT = 1; | ||||
| 
 | ||||
|     private int contributionsSize; | ||||
|     String userName; | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void onCreate(@Nullable @org.jetbrains.annotations.Nullable final Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         //Now that we are allowing this fragment to be started for | ||||
|         // any userName- we expect it to be passed as an argument | ||||
|         if (getArguments() != null) { | ||||
|             userName = getArguments().getString(ProfileActivity.KEY_USERNAME); | ||||
|         } | ||||
| 
 | ||||
|         if (StringUtils.isEmpty(userName)) { | ||||
|             userName = sessionManager.getUserName(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public View onCreateView( | ||||
|         final LayoutInflater inflater, @Nullable final ViewGroup container, | ||||
|  | @ -114,6 +137,16 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|         final View view = inflater.inflate(R.layout.fragment_contributions_list, container, false); | ||||
|         ButterKnife.bind(this, view); | ||||
|         contributionsListPresenter.onAttachView(this); | ||||
| 
 | ||||
|         if (Objects.equals(sessionManager.getUserName(), userName)) { | ||||
|             tvContributionsOfUser.setVisibility(GONE); | ||||
|             fab_layout.setVisibility(VISIBLE); | ||||
|         } else { | ||||
|             tvContributionsOfUser.setVisibility(VISIBLE); | ||||
|             tvContributionsOfUser.setText(getString(R.string.contributions_of_user, userName)); | ||||
|             fab_layout.setVisibility(GONE); | ||||
|         } | ||||
| 
 | ||||
|         initAdapter(); | ||||
|         return view; | ||||
|     } | ||||
|  | @ -155,8 +188,9 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl | |||
|             ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); | ||||
|         } | ||||
| 
 | ||||
|         contributionsListPresenter.setup(); | ||||
|         contributionsListPresenter.contributionList.observe(this.getViewLifecycleOwner(), list -> { | ||||
|         contributionsListPresenter.setup(userName, | ||||
|             Objects.equals(sessionManager.getUserName(), userName)); | ||||
|         contributionsListPresenter.contributionList.observe(getViewLifecycleOwner(), list -> { | ||||
|             contributionsSize = list.size(); | ||||
|             adapter.submitList(list); | ||||
|             if (callback != null) { | ||||
|  |  | |||
|  | @ -1,6 +1,9 @@ | |||
| package fr.free.nrw.commons.contributions; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.lifecycle.LiveData; | ||||
| import androidx.paging.DataSource; | ||||
| import androidx.paging.DataSource.Factory; | ||||
| import androidx.paging.LivePagedListBuilder; | ||||
| import androidx.paging.PagedList; | ||||
| import fr.free.nrw.commons.contributions.ContributionsListContract.UserActionListener; | ||||
|  | @ -20,17 +23,20 @@ public class ContributionsListPresenter implements UserActionListener { | |||
|     private final Scheduler ioThreadScheduler; | ||||
| 
 | ||||
|     private final CompositeDisposable compositeDisposable; | ||||
|     private final ContributionsRemoteDataSource contributionsRemoteDataSource; | ||||
| 
 | ||||
|     LiveData<PagedList<Contribution>> contributionList; | ||||
| 
 | ||||
|     @Inject | ||||
|     ContributionsListPresenter( | ||||
|         final ContributionBoundaryCallback contributionBoundaryCallback, | ||||
|         final ContributionsRemoteDataSource contributionsRemoteDataSource, | ||||
|         final ContributionsRepository repository, | ||||
|         @Named(CommonsApplicationModule.IO_THREAD) final Scheduler ioThreadScheduler) { | ||||
|         this.contributionBoundaryCallback = contributionBoundaryCallback; | ||||
|         this.repository = repository; | ||||
|         this.ioThreadScheduler = ioThreadScheduler; | ||||
|         this.contributionsRemoteDataSource=contributionsRemoteDataSource; | ||||
|         compositeDisposable = new CompositeDisposable(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -43,19 +49,44 @@ public class ContributionsListPresenter implements UserActionListener { | |||
|      * the live data object. This method can be tweaked to update the lazy loading behavior of the | ||||
|      * contributions list | ||||
|      */ | ||||
|     void setup() { | ||||
|     void setup(String userName, boolean isSelf) { | ||||
|         final PagedList.Config pagedListConfig = | ||||
|             (new PagedList.Config.Builder()) | ||||
|                 .setPrefetchDistance(50) | ||||
|                 .setPageSize(10).build(); | ||||
|         contributionList = (new LivePagedListBuilder(repository.fetchContributions(), | ||||
|             pagedListConfig) | ||||
|             .setBoundaryCallback(contributionBoundaryCallback)).build(); | ||||
|         Factory<Integer, Contribution> factory; | ||||
|         boolean shouldSetBoundaryCallback; | ||||
|         if (!isSelf) { | ||||
|             //We don't want to persist contributions for other user's, therefore | ||||
|             // creating a new DataSource for them | ||||
|             contributionsRemoteDataSource.setUserName(userName); | ||||
|             factory = new Factory<Integer, Contribution>() { | ||||
|                 @NonNull | ||||
|                 @Override | ||||
|                 public DataSource<Integer, Contribution> create() { | ||||
|                     return contributionsRemoteDataSource; | ||||
|                 } | ||||
|             }; | ||||
|             shouldSetBoundaryCallback = false; | ||||
|         } else { | ||||
|             contributionBoundaryCallback.setUserName(userName); | ||||
|             shouldSetBoundaryCallback = true; | ||||
|             factory = repository.fetchContributions(); | ||||
|         } | ||||
| 
 | ||||
|         LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, pagedListConfig); | ||||
|         if (shouldSetBoundaryCallback) { | ||||
|             livePagedListBuilder.setBoundaryCallback(contributionBoundaryCallback); | ||||
|         } | ||||
| 
 | ||||
|         contributionList = livePagedListBuilder.build(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDetachView() { | ||||
|         compositeDisposable.clear(); | ||||
|         contributionsRemoteDataSource.dispose(); | ||||
|         contributionBoundaryCallback.dispose(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -0,0 +1,73 @@ | |||
| package fr.free.nrw.commons.contributions | ||||
| 
 | ||||
| import androidx.paging.ItemKeyedDataSource | ||||
| import fr.free.nrw.commons.di.CommonsApplicationModule | ||||
| import fr.free.nrw.commons.media.MediaClient | ||||
| import io.reactivex.Scheduler | ||||
| import io.reactivex.disposables.CompositeDisposable | ||||
| import timber.log.Timber | ||||
| import javax.inject.Inject | ||||
| import javax.inject.Named | ||||
| 
 | ||||
| /** | ||||
|  * Data-Source which acts as mediator for contributions-data from the API | ||||
|  */ | ||||
| class ContributionsRemoteDataSource @Inject constructor( | ||||
|     private val mediaClient: MediaClient, | ||||
|     @param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler | ||||
| ) : ItemKeyedDataSource<Int, Contribution>() { | ||||
|     private val compositeDisposable: CompositeDisposable = CompositeDisposable() | ||||
|     var userName: String? = null | ||||
| 
 | ||||
|     override fun loadInitial( | ||||
|         params: LoadInitialParams<Int>, | ||||
|         callback: LoadInitialCallback<Contribution> | ||||
|     ) { | ||||
|         fetchContributions(callback) | ||||
|     } | ||||
| 
 | ||||
|     override fun loadAfter( | ||||
|         params: LoadParams<Int>, | ||||
|         callback: LoadCallback<Contribution> | ||||
|     ) { | ||||
|         fetchContributions(callback) | ||||
|     } | ||||
| 
 | ||||
|     override fun loadBefore( | ||||
|         params: LoadParams<Int>, | ||||
|         callback: LoadCallback<Contribution> | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     override fun getKey(item: Contribution): Int { | ||||
|         return item.pageId.hashCode() | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Fetches contributions using the MediaWiki API | ||||
|      */ | ||||
|     private fun fetchContributions(callback: LoadCallback<Contribution>) { | ||||
|         compositeDisposable.add( | ||||
|             mediaClient.getMediaListForUser(userName!!) | ||||
|                 .map { mediaList -> | ||||
|                     mediaList.map { | ||||
|                         Contribution(media = it, state = Contribution.STATE_COMPLETED) | ||||
|                     } | ||||
|                 } | ||||
|                 .subscribeOn(ioThreadScheduler) | ||||
|                 .subscribe({ | ||||
|                     callback.onResult(it) | ||||
|                 }) { error: Throwable -> | ||||
|                     Timber.e( | ||||
|                         "Failed to fetch contributions: %s", | ||||
|                         error.message | ||||
|                     ) | ||||
|                 } | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fun dispose() { | ||||
|         compositeDisposable.dispose() | ||||
|     } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ashish
						Ashish