mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +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()
|
||||
}
|
||||
}
|
||||
|
|
@ -75,6 +75,7 @@ import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
|||
import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.nearby.Label;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||
import io.reactivex.Single;
|
||||
|
|
@ -1014,6 +1015,15 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.mediaDetailAuthor)
|
||||
public void onAuthorViewClicked() {
|
||||
if (media == null || media.getUser() == null) {
|
||||
return;
|
||||
}
|
||||
ProfileActivity.startYourself(getActivity(), media.getUser(), !Objects
|
||||
.equals(sessionManager.getUserName(), media.getUser()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Progress Bar and Update delete button text.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import fr.free.nrw.commons.contributions.Contribution;
|
|||
import fr.free.nrw.commons.contributions.MainActivity;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.utils.DownloadUtils;
|
||||
import fr.free.nrw.commons.utils.ImageUtils;
|
||||
|
|
@ -201,6 +202,11 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
// Set avatar
|
||||
setAvatar(m);
|
||||
return true;
|
||||
case R.id.menu_view_user_page:
|
||||
if (m != null && m.getUser() != null) {
|
||||
ProfileActivity.startYourself(getActivity(), m.getUser(),
|
||||
!Objects.equals(sessionManager.getUserName(), m.getUser()));
|
||||
}
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
|
@ -258,7 +264,9 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
|||
menu.findItem(R.id.menu_download_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_bookmark_current_image).setEnabled(true).setVisible(true);
|
||||
menu.findItem(R.id.menu_set_as_wallpaper).setEnabled(true).setVisible(true);
|
||||
|
||||
if (m.getUser() != null) {
|
||||
menu.findItem(R.id.menu_view_user_page).setEnabled(true).setVisible(true);
|
||||
}
|
||||
// Initialize bookmark object
|
||||
bookmark = new Bookmark(
|
||||
m.getFilename(),
|
||||
|
|
|
|||
|
|
@ -74,13 +74,20 @@ public class MoreBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
* Set the username in navigationHeader.
|
||||
*/
|
||||
private void setUserName() {
|
||||
AccountManager accountManager = AccountManager.get(getActivity());
|
||||
Account[] allAccounts = accountManager.getAccountsByType(BuildConfig.ACCOUNT_TYPE);
|
||||
moreProfile.setText(getUserName());
|
||||
}
|
||||
|
||||
private String getUserName(){
|
||||
final AccountManager accountManager = AccountManager.get(getActivity());
|
||||
final Account[] allAccounts = accountManager.getAccountsByType(BuildConfig.ACCOUNT_TYPE);
|
||||
if (allAccounts.length != 0) {
|
||||
moreProfile.setText(allAccounts[0].name);
|
||||
return allAccounts[0].name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@OnClick(R.id.more_logout)
|
||||
public void onLogoutClicked() {
|
||||
new AlertDialog.Builder(getActivity())
|
||||
|
|
@ -136,9 +143,7 @@ public class MoreBottomSheetFragment extends BottomSheetDialogFragment {
|
|||
|
||||
@OnClick(R.id.more_profile)
|
||||
public void onProfileClicked() {
|
||||
final Intent intent = new Intent(getActivity(), ProfileActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
getActivity().startActivity(intent);
|
||||
ProfileActivity.startYourself(getActivity(), getUserName(), false);
|
||||
}
|
||||
|
||||
@OnClick(R.id.more_peer_review)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
|
@ -25,6 +26,7 @@ import fr.free.nrw.commons.R;
|
|||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.ViewPagerAdapter;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.contributions.ContributionsListFragment;
|
||||
import fr.free.nrw.commons.profile.achievements.AchievementsFragment;
|
||||
import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
|
|
@ -49,9 +51,6 @@ public class ProfileActivity extends BaseActivity {
|
|||
@BindView(R.id.tab_layout)
|
||||
TabLayout tabLayout;
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
|
||||
|
|
@ -59,15 +58,32 @@ public class ProfileActivity extends BaseActivity {
|
|||
private AchievementsFragment achievementsFragment;
|
||||
private LeaderboardFragment leaderboardFragment;
|
||||
|
||||
public static final String KEY_USERNAME ="username";
|
||||
public static final String KEY_SHOULD_SHOW_CONTRIBUTIONS ="shouldShowContributions";
|
||||
|
||||
String userName;
|
||||
private boolean shouldShowContributions;
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(final Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
if (savedInstanceState != null) {
|
||||
userName = savedInstanceState.getString(KEY_USERNAME);
|
||||
shouldShowContributions = savedInstanceState.getBoolean(KEY_SHOULD_SHOW_CONTRIBUTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_profile);
|
||||
ButterKnife.bind(this);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
setTitle(sessionManager.getUserName());
|
||||
|
||||
userName = getIntent().getStringExtra(KEY_USERNAME);
|
||||
shouldShowContributions = getIntent().getBooleanExtra(KEY_SHOULD_SHOW_CONTRIBUTIONS, false);
|
||||
|
||||
supportFragmentManager = getSupportFragmentManager();
|
||||
viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
|
||||
viewPager.setAdapter(viewPagerAdapter);
|
||||
|
|
@ -87,11 +103,15 @@ public class ProfileActivity extends BaseActivity {
|
|||
|
||||
/**
|
||||
* Creates a way to change current activity to AchievementActivity
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public static void startYourself(Context context) {
|
||||
public static void startYourself(final Context context, final String userName,
|
||||
final boolean shouldShowContributions) {
|
||||
Intent intent = new Intent(context, ProfileActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
intent.putExtra(KEY_USERNAME, userName);
|
||||
intent.putExtra(KEY_SHOULD_SHOW_CONTRIBUTIONS, shouldShowContributions);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
|
|
@ -102,11 +122,28 @@ public class ProfileActivity extends BaseActivity {
|
|||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
List<String> titleList = new ArrayList<>();
|
||||
achievementsFragment = new AchievementsFragment();
|
||||
Bundle achievementsBundle = new Bundle();
|
||||
achievementsBundle.putString(KEY_USERNAME, userName);
|
||||
achievementsFragment.setArguments(achievementsBundle);
|
||||
fragmentList.add(achievementsFragment);
|
||||
|
||||
titleList.add(getResources().getString(R.string.achievements_tab_title).toUpperCase());
|
||||
leaderboardFragment = new LeaderboardFragment();
|
||||
Bundle leaderBoardBundle = new Bundle();
|
||||
leaderBoardBundle.putString(KEY_USERNAME, userName);
|
||||
leaderboardFragment.setArguments(leaderBoardBundle);
|
||||
|
||||
fragmentList.add(leaderboardFragment);
|
||||
titleList.add(getResources().getString(R.string.leaderboard_tab_title).toUpperCase());
|
||||
|
||||
if (shouldShowContributions) {
|
||||
ContributionsListFragment contributionsListFragment = new ContributionsListFragment();
|
||||
Bundle contributionsListBundle = new Bundle();
|
||||
contributionsListBundle.putString(KEY_USERNAME, userName);
|
||||
contributionsListFragment.setArguments(contributionsListBundle);
|
||||
fragmentList.add(contributionsListFragment);
|
||||
titleList.add(getString(R.string.contributions_fragment).toUpperCase());
|
||||
}
|
||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||
viewPagerAdapter.notifyDataSetChanged();
|
||||
|
||||
|
|
@ -191,4 +228,10 @@ public class ProfileActivity extends BaseActivity {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull final Bundle outState) {
|
||||
outState.putString(KEY_USERNAME, userName);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,7 +15,9 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
import butterknife.BindView;
|
||||
|
|
@ -28,6 +30,7 @@ import fr.free.nrw.commons.auth.SessionManager;
|
|||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
|
@ -114,6 +117,9 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
@BindView(R.id.wikidata_edits)
|
||||
TextView wikidataEditsText;
|
||||
|
||||
@BindView(R.id.tv_achievements_of_user)
|
||||
AppCompatTextView tvAchievementsOfUser;
|
||||
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
|
||||
|
|
@ -128,6 +134,16 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
// menu item for action bar
|
||||
private MenuItem item;
|
||||
|
||||
private String userName;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
userName = getArguments().getString(ProfileActivity.KEY_USERNAME);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method helps in the creation Achievement screen and
|
||||
* dynamically set the size of imageView
|
||||
|
|
@ -157,6 +173,12 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
// Set the initial value of WikiData edits to 0
|
||||
wikidataEditsText.setText("0");
|
||||
if(sessionManager.getUserName().equals(userName)){
|
||||
tvAchievementsOfUser.setVisibility(View.GONE);
|
||||
}else{
|
||||
tvAchievementsOfUser.setVisibility(View.VISIBLE);
|
||||
tvAchievementsOfUser.setText(getString(R.string.achievements_of_user,userName));
|
||||
}
|
||||
setWikidataEditCount();
|
||||
setAchievements();
|
||||
return rootView;
|
||||
|
|
@ -182,7 +204,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
try{
|
||||
|
||||
compositeDisposable.add(okHttpJsonApiClient
|
||||
.getAchievements(Objects.requireNonNull(sessionManager.getCurrentAccount()).name)
|
||||
.getAchievements(Objects.requireNonNull(userName))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
|
|
@ -225,7 +247,6 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
* in the form of JavaRx Single object<JSONobject>
|
||||
*/
|
||||
private void setWikidataEditCount() {
|
||||
String userName = sessionManager.getUserName();
|
||||
if (StringUtils.isBlank(userName)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -274,7 +295,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
private void setUploadCount(Achievements achievements) {
|
||||
if (checkAccount()) {
|
||||
compositeDisposable.add(okHttpJsonApiClient
|
||||
.getUploadCount(Objects.requireNonNull(sessionManager.getCurrentAccount()).name)
|
||||
.getUploadCount(Objects.requireNonNull(userName))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
|
|
@ -304,7 +325,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
if (uploadCount==0){
|
||||
setZeroAchievements();
|
||||
}else {
|
||||
|
||||
imagesUploadedProgressbar.setVisibility(View.VISIBLE);
|
||||
imagesUploadedProgressbar.setProgress
|
||||
(100*uploadCount/levelInfo.getMaxUploadCount());
|
||||
imagesUploadedProgressbar.setProgressTextFormatPattern
|
||||
|
|
@ -314,10 +335,14 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
}
|
||||
|
||||
private void setZeroAchievements() {
|
||||
AlertDialog.Builder builder=new AlertDialog.Builder(getActivity())
|
||||
.setMessage(getString(R.string.no_achievements_yet))
|
||||
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
|
||||
});
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
|
||||
.setMessage(
|
||||
!Objects.equals(sessionManager.getUserName(), userName) ?
|
||||
getString(R.string.no_achievements_yet, userName) :
|
||||
getString(R.string.you_have_no_achievements_yet)
|
||||
)
|
||||
.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
imagesUploadedProgressbar.setVisibility(View.INVISIBLE);
|
||||
|
|
@ -336,6 +361,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
* @param notRevertPercentage
|
||||
*/
|
||||
private void setImageRevertPercentage(int notRevertPercentage){
|
||||
imageRevertsProgressbar.setVisibility(View.VISIBLE);
|
||||
imageRevertsProgressbar.setProgress(notRevertPercentage);
|
||||
String revertPercentage = Integer.toString(notRevertPercentage);
|
||||
imageRevertsProgressbar.setProgressTextFormatPattern(revertPercentage + "%%");
|
||||
|
|
@ -348,6 +374,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
* @param achievements
|
||||
*/
|
||||
private void inflateAchievements(Achievements achievements) {
|
||||
imagesUsedByWikiProgressBar.setVisibility(View.VISIBLE);
|
||||
thanksReceived.setText(String.valueOf(achievements.getThanksReceived()));
|
||||
imagesUsedByWikiProgressBar.setProgress
|
||||
(100 * achievements.getUniqueUsedImages() / levelInfo.getMaxUniqueImages());
|
||||
|
|
@ -481,5 +508,4 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import android.widget.Button;
|
|||
import android.widget.ProgressBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.MergeAdapter;
|
||||
|
|
@ -27,6 +28,7 @@ import fr.free.nrw.commons.R;
|
|||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
|
@ -104,6 +106,16 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
|||
*/
|
||||
private boolean scrollToRank;
|
||||
|
||||
private String userName;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
userName = getArguments().getString(ProfileActivity.KEY_USERNAME);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_leaderboard, container, false);
|
||||
|
|
@ -220,7 +232,7 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment {
|
|||
if (checkAccount()) {
|
||||
try {
|
||||
compositeDisposable.add(okHttpJsonApiClient
|
||||
.getLeaderboard(Objects.requireNonNull(sessionManager.getCurrentAccount()).name,
|
||||
.getLeaderboard(Objects.requireNonNull(userName),
|
||||
duration, category, null, null)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package fr.free.nrw.commons.profile.leaderboard;
|
||||
|
||||
import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.USER_LINK_PREFIX;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
|
|
@ -14,6 +14,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||
|
||||
/**
|
||||
* This class extends RecyclerView.Adapter and creates the List section of the leaderboard
|
||||
|
|
@ -81,9 +82,13 @@ public class LeaderboardListAdapter extends PagedListAdapter<LeaderboardList, Le
|
|||
count.setText(getItem(position).getCategoryCount().toString());
|
||||
|
||||
/*
|
||||
Open the user profile in a webview when a username is clicked on leaderboard
|
||||
Now that we have our in app profile-section, lets take the user there
|
||||
*/
|
||||
holder.itemView.setOnClickListener(view -> Utils.handleWebUrl(holder.getContext(), Uri.parse(
|
||||
String.format("%s%s", USER_LINK_PREFIX, getItem(position).getUsername()))));
|
||||
holder.itemView.setOnClickListener(view -> {
|
||||
if (view.getContext() instanceof ProfileActivity) {
|
||||
((Activity) (view.getContext())).finish();
|
||||
}
|
||||
ProfileActivity.startYourself(view.getContext(), getItem(position).getUsername(), true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="?attr/mainBackground">
|
||||
|
||||
<include layout="@layout/toolbar"/>
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -15,6 +15,14 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tv_achievements_of_user"
|
||||
style="@style/MediaDetailTextLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
tools:text="Achievements of user : Ashish" />
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -136,6 +144,7 @@
|
|||
app:progress_start_color="#3A3381"
|
||||
app:progress_stroke_width="@dimen/progressbar_stroke"
|
||||
app:progress_text_format_pattern="573/110"
|
||||
android:visibility="gone"
|
||||
app:progress_text_color="@color/secondaryColor"
|
||||
app:style="solid_line" />
|
||||
|
||||
|
|
@ -203,6 +212,7 @@
|
|||
android:layout_marginRight="@dimen/large_gap"
|
||||
android:layout_marginEnd="@dimen/large_gap"
|
||||
android:progress="50"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/image_reverts_progressbar"
|
||||
app:progress_end_color="#8C8B98"
|
||||
app:progress_start_color="#3A3381"
|
||||
|
|
@ -270,6 +280,7 @@
|
|||
app:progress_end_color="#8C8B98"
|
||||
app:progress_start_color="#3A3381"
|
||||
app:progress_stroke_width="2.5dp"
|
||||
android:visibility="gone"
|
||||
app:progress_text_color="@color/secondaryColor"
|
||||
app:progress_text_format_pattern="12/24"
|
||||
app:style="solid_line" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
@ -26,11 +27,28 @@
|
|||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contributionsList"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/tv_contributions_of_user"
|
||||
style="@style/MediaDetailTextLabel"
|
||||
tools:text="Contributions of user : Ashish"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/contributionsList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/tv_contributions_of_user" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/fab_layout"
|
||||
|
|
|
|||
|
|
@ -30,4 +30,9 @@
|
|||
android:title="@string/menu_set_avatar"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_view_user_page"
|
||||
android:title="@string/menu_view_user_page"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
|
@ -527,7 +527,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="coordinates_picking_unsuccessful">Unable to get coordinates.</string>
|
||||
|
||||
<string name="share_image_via">Share image via</string>
|
||||
<string name="no_achievements_yet">You haven\'t made any contributions yet</string>
|
||||
<string name="you_have_no_achievements_yet">You haven\'t made any contributions yet</string>
|
||||
<string name="no_achievements_yet">%s has not made any contributions yet</string>
|
||||
<string name="account_created">Account created!</string>
|
||||
<string name="text_copy">Text copied to clipboard</string>
|
||||
<string name="notification_mark_read">Notification marked as read</string>
|
||||
|
|
@ -656,4 +657,7 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="learn_more">LEARN MORE</string>
|
||||
<string name="wlm_campaign_title">Wiki Loves Monuments</string>
|
||||
<string name="wlm_campaign_description">Wiki Loves Monuments is an international photo contest for monuments organised by Wikimedia</string>
|
||||
<string name="contributions_of_user">Contributions of User: %s</string>
|
||||
<string name="achievements_of_user">Achievements of User: %s</string>
|
||||
<string name="menu_view_user_page">View user page</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ class ContributionBoundaryCallbackTest {
|
|||
MockitoAnnotations.initMocks(this)
|
||||
scheduler = Schedulers.trampoline()
|
||||
contributionBoundaryCallback =
|
||||
ContributionBoundaryCallback(repository, sessionManager, mediaClient, scheduler);
|
||||
ContributionBoundaryCallback(repository, sessionManager, mediaClient, scheduler)
|
||||
contributionBoundaryCallback.userName = "test"
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ class ContributionsListPresenterTest {
|
|||
@Mock
|
||||
internal lateinit var repository: ContributionsRepository
|
||||
|
||||
@Mock
|
||||
internal lateinit var remoteDataSource: ContributionsRemoteDataSource
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
|
|
@ -49,7 +52,12 @@ class ContributionsListPresenterTest {
|
|||
MockitoAnnotations.initMocks(this)
|
||||
scheduler = Schedulers.trampoline()
|
||||
contributionsListPresenter =
|
||||
ContributionsListPresenter(contributionBoundaryCallback, repository, scheduler);
|
||||
ContributionsListPresenter(
|
||||
contributionBoundaryCallback,
|
||||
remoteDataSource,
|
||||
repository,
|
||||
scheduler
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class ProfileActivityTest {
|
|||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testStartYourself() {
|
||||
ProfileActivity.startYourself(activity)
|
||||
ProfileActivity.startYourself(activity, "test", false)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -11,12 +11,14 @@ import androidx.fragment.app.FragmentTransaction
|
|||
import com.dinuscxj.progressbar.CircleProgressBar
|
||||
import fr.free.nrw.commons.TestAppAdapter
|
||||
import fr.free.nrw.commons.TestCommonsApplication
|
||||
import fr.free.nrw.commons.auth.SessionManager
|
||||
import fr.free.nrw.commons.profile.ProfileActivity
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.powermock.reflect.Whitebox
|
||||
import org.robolectric.Robolectric
|
||||
|
|
@ -85,6 +87,9 @@ class AchievementsFragmentUnitTests {
|
|||
@Mock
|
||||
private lateinit var progressBar: ProgressBar
|
||||
|
||||
@Mock
|
||||
private lateinit var sessionManager: SessionManager
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
|
@ -131,6 +136,10 @@ class AchievementsFragmentUnitTests {
|
|||
Whitebox.setInternalState(fragment, "progressBar", progressBar)
|
||||
Whitebox.setInternalState(fragment, "imagesRevertLimitText", imagesRevertLimitText)
|
||||
Whitebox.setInternalState(fragment, "item", menuItem)
|
||||
Whitebox.setInternalState(fragment, "sessionManager", sessionManager)
|
||||
|
||||
Mockito.`when`(sessionManager.userName).thenReturn("Test")
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue