diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt index bf6d42ac272..16d89f8fcdc 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt @@ -21,6 +21,8 @@ class ContributionBoundaryCallback @Inject constructor( @param:Named(CommonsApplicationModule.IO_THREAD) private val ioThreadScheduler: Scheduler ) : BoundaryCallback() { 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() + } } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java index 1cb11161845..ebe35969505 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java @@ -5,7 +5,6 @@ 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.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; @@ -30,22 +30,24 @@ import androidx.recyclerview.widget.SimpleItemAnimator; import butterknife.BindView; import butterknife.ButterKnife; -import butterknife.OnClick; 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 +58,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 +78,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl @Inject SystemThemeUtils systemThemeUtils; + @BindView(R.id.tv_contributions_of_user) + AppCompatTextView tvContributionsOfUser; @Inject ContributionController controller; @@ -89,6 +93,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,7 +112,22 @@ 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( @@ -114,6 +136,16 @@ public View onCreateView( final View view = inflater.inflate(R.layout.fragment_contributions_list, container, false); ButterKnife.bind(this, view); contributionsListPresenter.onAttachView(this); + + if (sessionManager.getUserName().equals(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 +187,9 @@ private void initRecyclerView() { ((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) { @@ -269,15 +302,6 @@ private void setListeners() { }); } - /** - * Launch Custom Selector. - */ - @OnClick(R.id.fab_custom_gallery) - void launchCustomSelector(){ - controller.initiateCustomGalleryPickWithPermission(getActivity()); - animateFAB(isFabOpen); - } - private void animateFAB(final boolean isFabOpen) { this.isFabOpen = !isFabOpen; if (fabPlus.isShown()) { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java index 26aa3ea9941..320ba88a2d1 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java @@ -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> 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 void onAttachView(final ContributionsListContract.View view) { * 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 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() { + @NonNull + @Override + public DataSource 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(); } /** diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt new file mode 100644 index 00000000000..777bb8a21ef --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt @@ -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() { + private val compositeDisposable: CompositeDisposable = CompositeDisposable() + var userName: String? = null + + override fun loadInitial( + params: LoadInitialParams, + callback: LoadInitialCallback + ) { + fetchContributions(callback) + } + + override fun loadAfter( + params: LoadParams, + callback: LoadCallback + ) { + fetchContributions(callback) + } + + override fun loadBefore( + params: LoadParams, + callback: LoadCallback + ) { + } + + override fun getKey(item: Contribution): Int { + return item.pageId.hashCode() + } + + + /** + * Fetches contributions using the MediaWiki API + */ + private fun fetchContributions(callback: LoadCallback) { + 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() + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index 7684d739dd8..17e9581ce9e 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -75,6 +75,7 @@ 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 void onSeeMoreClicked(){ } } + @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. */ diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index ce6585b525a..49b776178fe 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -32,6 +32,7 @@ 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 boolean onOptionsItemSelected(MenuItem item) { // 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 void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 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(), diff --git a/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java index 2bd22666f49..24e6d25f075 100644 --- a/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/navtab/MoreBottomSheetFragment.java @@ -74,13 +74,20 @@ public void onAttach(@NonNull final Context context) { * 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 void onSettingsClicked() { @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) diff --git a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java index 2e0f6c2610c..71703e0d77c 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/ProfileActivity.java @@ -13,6 +13,7 @@ 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.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 boolean onSupportNavigateUp() { /** * 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 @@ private void setTabs() { List fragmentList = new ArrayList<>(); List 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 @@ void shareScreen(final Bitmap bitmap) { e.printStackTrace(); } } + + @Override + protected void onSaveInstanceState(@NonNull final Bundle outState) { + outState.putString(KEY_USERNAME, userName); + super.onSaveInstanceState(outState); + } } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java index fd286439851..36ce969fd13 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java @@ -15,7 +15,9 @@ 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.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 View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa // 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 @@ private void setAchievements() { 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 @@ private void setAchievements() { * in the form of JavaRx Single object */ private void setWikidataEditCount() { - String userName = sessionManager.getUserName(); if (StringUtils.isBlank(userName)) { return; } @@ -274,7 +295,7 @@ private void onError() { 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( @@ -314,10 +335,14 @@ private void setUploadProgress(int uploadCount){ } 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( + !sessionManager.getUserName().equals(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); @@ -481,5 +506,4 @@ private boolean checkAccount(){ } return true; } - } diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java index 4c43c9159fc..0cd6f41d3e2 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java @@ -17,6 +17,7 @@ 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.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 @@ private void setLeaderboard(String duration, String category, int limit, int off 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()) diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java index acf065330a9..4931def7a17 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java @@ -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 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 void onBindViewHolder(@NonNull LeaderboardListAdapter.ListViewHolder hold 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); + }); } } diff --git a/app/src/main/res/layout/activity_profile.xml b/app/src/main/res/layout/activity_profile.xml index 64cc0f7a9fe..47e24da276d 100644 --- a/app/src/main/res/layout/activity_profile.xml +++ b/app/src/main/res/layout/activity_profile.xml @@ -15,8 +15,6 @@ android:layout_height="wrap_content" android:background="?attr/mainBackground"> - - - + + + + + - - - + + + + + android:layout_below="@id/achievement_info" + android:layout_centerHorizontal="true"> - + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:srcCompat="@drawable/badge" /> - + android:textAlignment="center" + android:textColor="@color/achievement_badge_text" + android:textSize="75sp" + app:layout_constraintBottom_toBottomOf="@+id/achievement_badge_image" + app:layout_constraintEnd_toEndOf="@+id/achievement_badge_image" + app:layout_constraintStart_toStartOf="@+id/achievement_badge_image" + app:layout_constraintTop_toTopOf="@+id/achievement_badge_image" + app:layout_constraintVertical_bias="0.58" /> + - + + + - - + android:id="@+id/images_upload_info" + android:orientation="horizontal" + > - + android:layout_marginLeft="@dimen/activity_margin_horizontal" + android:layout_marginStart="@dimen/activity_margin_horizontal" + android:id="@+id/images_upload_text_param" + android:layout_marginTop="@dimen/achievements_activity_margin_vertical" + android:text="@string/images_uploaded" /> - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - + android:text="@string/image_reverts" /> - - - - - - - - - - - - - + + + - - + android:layout_below="@id/images_reverted_info"/> - + + + + + + + android:id="@+id/images_used_by_wiki_info" + android:orientation="horizontal"> - - - - - - - - - + android:id="@+id/images_used_by_wiki_text" + android:layout_marginLeft="@dimen/activity_margin_horizontal" + android:layout_marginStart="@dimen/activity_margin_horizontal" + android:layout_marginTop="@dimen/achievements_activity_margin_vertical" + android:text="@string/images_used_by_wiki" /> + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginRight="@dimen/activity_margin_horizontal" + android:layout_marginEnd="@dimen/activity_margin_horizontal" + android:layout_gravity="top" + app:layout_constraintLeft_toRightOf="@id/images_nearby_data" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:srcCompat="@drawable/ic_info_outline_24dp" + android:tint="@color/primaryDarkColor" /> + + - - + android:layout_centerVertical="true" + tools:text="2" + android:id="@+id/wikidata_edits" + android:layout_marginRight="@dimen/half_standard_height" /> - - - - - - - - - + + + + + + + + android:layout_marginEnd="@dimen/activity_margin_horizontal" + android:layout_marginRight="@dimen/activity_margin_horizontal" + app:layout_constraintLeft_toRightOf="@id/featured_image_icon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintRight_toLeftOf="@id/images_featured_info_icon" + android:text="@string/statistics_featured" /> + + - + - + android:layout_centerVertical="true" + tools:text="2" + android:id="@+id/image_featured" + android:layout_marginLeft="@dimen/activity_margin_horizontal" + android:layout_marginEnd="@dimen/half_standard_height" + android:layout_marginRight="@dimen/half_standard_height" /> - - - - - - - - - + + + + + + + + android:layout_marginEnd="@dimen/activity_margin_horizontal" + android:layout_marginRight="@dimen/activity_margin_horizontal" + app:layout_constraintLeft_toRightOf="@id/quality_image_icon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintRight_toLeftOf="@id/quality_images_info_icon" + android:text="@string/statistics_quality" /> - + + + - + android:layout_marginStart="@dimen/activity_margin_horizontal" + android:layout_centerVertical="true" + tools:text="2" + android:text="0" + android:id="@+id/quality_images" + android:layout_marginLeft="@dimen/activity_margin_horizontal" + android:layout_marginEnd="@dimen/half_standard_height" + android:layout_marginRight="@dimen/half_standard_height" /> - - - - - - - - - + + + + + + + + android:layout_marginEnd="@dimen/activity_margin_horizontal" + android:layout_marginRight="@dimen/activity_margin_horizontal" + app:layout_constraintLeft_toRightOf="@id/thanks_image_icon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintRight_toLeftOf="@id/thanks_received_info_icon" + android:text="@string/statistics_thanks" /> - + + + + + + + - - + + diff --git a/app/src/main/res/layout/fragment_contributions_list.xml b/app/src/main/res/layout/fragment_contributions_list.xml index 923cc83431b..410c24c8215 100644 --- a/app/src/main/res/layout/fragment_contributions_list.xml +++ b/app/src/main/res/layout/fragment_contributions_list.xml @@ -1,6 +1,7 @@ - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2acf08b8f7c..84195069708 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -527,7 +527,8 @@ Upload your first media by tapping on the add button. Unable to get coordinates. Share image via - You haven\'t made any contributions yet + You haven\'t made any contributions yet + %s has not made any contributions yet Account created! Text copied to clipboard Notification marked as read @@ -656,4 +657,7 @@ Upload your first media by tapping on the add button. LEARN MORE Wiki Loves Monuments Wiki Loves Monuments is an international photo contest for monuments organised by Wikimedia + Contributions of User: %s + Achievements of User: %s + View user page