mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Bug Fixs & Enhancement of Achievement Screen (#5666)
* Rename AchievementFragment from `.java` to `.kt` * Migrated AchievementFragment to kotlin * Revamped Achievement Screen * fixed AchievementFragment Unit Test * fixed Level on MoreBottomSheetFragment * Implemented Badge and Minor Code Refactor * Fixed the badge issue & made the badge clickable * Removed Redundant XML Code & Converted badges to green color and added values inside it * Fixed : showSnackBarWithRetry Test * Fixed : Theme issues on Light Mode --------- Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
parent
ae52267a27
commit
a8387f01c9
9 changed files with 942 additions and 1130 deletions
|
|
@ -47,7 +47,7 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
||||||
implementation "com.google.android.material:material:1.9.0"
|
implementation "com.google.android.material:material:1.12.0"
|
||||||
implementation 'com.karumi:dexter:5.0.0'
|
implementation 'com.karumi:dexter:5.0.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,18 @@ class MoreBottomSheetFragment : BottomSheetDialogFragment() {
|
||||||
private fun setUserName() {
|
private fun setUserName() {
|
||||||
val store = BasicKvStore(requireContext(), getUserName())
|
val store = BasicKvStore(requireContext(), getUserName())
|
||||||
val level = store.getString("userAchievementsLevel", "0")
|
val level = store.getString("userAchievementsLevel", "0")
|
||||||
binding?.moreProfile?.text = if (level == "0") {
|
if (level == "0"){
|
||||||
"${getUserName()} (${getString(R.string.see_your_achievements)})"
|
binding?.moreProfile?.text = getString(
|
||||||
|
R.string.profileLevel,
|
||||||
|
getUserName(),
|
||||||
|
getString(R.string.see_your_achievements) // Second argument
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
"${getUserName()} (${getString(R.string.level)} $level)"
|
binding?.moreProfile?.text = getString(
|
||||||
|
R.string.profileLevel,
|
||||||
|
getUserName(),
|
||||||
|
level
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.FileProvider;
|
import androidx.core.content.FileProvider;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
import fr.free.nrw.commons.ViewPagerAdapter;
|
import fr.free.nrw.commons.ViewPagerAdapter;
|
||||||
|
|
|
||||||
|
|
@ -1,492 +0,0 @@
|
||||||
package fr.free.nrw.commons.profile.achievements;
|
|
||||||
|
|
||||||
import android.accounts.Account;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Toast;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.view.ContextThemeWrapper;
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
|
||||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.Utils;
|
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
|
||||||
import fr.free.nrw.commons.databinding.FragmentAchievementsBinding;
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
|
||||||
import fr.free.nrw.commons.kvstore.BasicKvStore;
|
|
||||||
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
|
|
||||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
|
||||||
import fr.free.nrw.commons.utils.DialogUtil;
|
|
||||||
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;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Objects;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* fragment for sharing feedback on uploaded activity
|
|
||||||
*/
|
|
||||||
public class AchievementsFragment extends CommonsDaggerSupportFragment {
|
|
||||||
|
|
||||||
private static final double BADGE_IMAGE_WIDTH_RATIO = 0.4;
|
|
||||||
private static final double BADGE_IMAGE_HEIGHT_RATIO = 0.3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Help link URLs
|
|
||||||
*/
|
|
||||||
private static final String IMAGES_UPLOADED_URL = "https://commons.wikimedia.org/wiki/Commons:Project_scope";
|
|
||||||
private static final String IMAGES_REVERT_URL = "https://commons.wikimedia.org/wiki/Commons:Deletion_policy#Reasons_for_deletion";
|
|
||||||
private static final String IMAGES_USED_URL = "https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Images";
|
|
||||||
private static final String IMAGES_NEARBY_PLACES_URL = "https://www.wikidata.org/wiki/Property:P18";
|
|
||||||
private static final String IMAGES_FEATURED_URL = "https://commons.wikimedia.org/wiki/Commons:Featured_pictures";
|
|
||||||
private static final String QUALITY_IMAGE_URL = "https://commons.wikimedia.org/wiki/Commons:Quality_images";
|
|
||||||
private static final String THANKS_URL = "https://www.mediawiki.org/wiki/Extension:Thanks";
|
|
||||||
|
|
||||||
private LevelController.LevelInfo levelInfo;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
SessionManager sessionManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
OkHttpJsonApiClient okHttpJsonApiClient;
|
|
||||||
|
|
||||||
private FragmentAchievementsBinding binding;
|
|
||||||
|
|
||||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
|
||||||
|
|
||||||
// To keep track of the number of wiki edits made by a user
|
|
||||||
private int numberOfEdits = 0;
|
|
||||||
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @param savedInstanceState Data bundle
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
binding = FragmentAchievementsBinding.inflate(inflater, container, false);
|
|
||||||
View rootView = binding.getRoot();
|
|
||||||
|
|
||||||
binding.achievementInfo.setOnClickListener(view -> showInfoDialog());
|
|
||||||
binding.imagesUploadInfo.setOnClickListener(view -> showUploadInfo());
|
|
||||||
binding.imagesRevertedInfo.setOnClickListener(view -> showRevertedInfo());
|
|
||||||
binding.imagesUsedByWikiInfo.setOnClickListener(view -> showUsedByWikiInfo());
|
|
||||||
binding.imagesNearbyInfo.setOnClickListener(view -> showImagesViaNearbyInfo());
|
|
||||||
binding.imagesFeaturedInfo.setOnClickListener(view -> showFeaturedImagesInfo());
|
|
||||||
binding.thanksReceivedInfo.setOnClickListener(view -> showThanksReceivedInfo());
|
|
||||||
binding.qualityImagesInfo.setOnClickListener(view -> showQualityImagesInfo());
|
|
||||||
|
|
||||||
// DisplayMetrics used to fetch the size of the screen
|
|
||||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
|
||||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
|
||||||
int height = displayMetrics.heightPixels;
|
|
||||||
int width = displayMetrics.widthPixels;
|
|
||||||
|
|
||||||
// Used for the setting the size of imageView at runtime
|
|
||||||
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams)
|
|
||||||
binding.achievementBadgeImage.getLayoutParams();
|
|
||||||
params.height = (int) (height * BADGE_IMAGE_HEIGHT_RATIO);
|
|
||||||
params.width = (int) (width * BADGE_IMAGE_WIDTH_RATIO);
|
|
||||||
binding.achievementBadgeImage.requestLayout();
|
|
||||||
binding.progressBar.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
// Set the initial value of WikiData edits to 0
|
|
||||||
binding.wikidataEdits.setText("0");
|
|
||||||
if(sessionManager.getUserName() == null || sessionManager.getUserName().equals(userName)){
|
|
||||||
binding.tvAchievementsOfUser.setVisibility(View.GONE);
|
|
||||||
}else{
|
|
||||||
binding.tvAchievementsOfUser.setVisibility(View.VISIBLE);
|
|
||||||
binding.tvAchievementsOfUser.setText(getString(R.string.achievements_of_user,userName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Achievements currently unimplemented in Beta flavor. Skip all API calls.
|
|
||||||
if(ConfigUtils.isBetaFlavour()) {
|
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
|
||||||
binding.imagesUsedByWikiText.setText(R.string.no_image);
|
|
||||||
binding.imagesRevertedText.setText(R.string.no_image_reverted);
|
|
||||||
binding.imagesUploadTextParam.setText(R.string.no_image_uploaded);
|
|
||||||
binding.wikidataEdits.setText("0");
|
|
||||||
binding.imageFeatured.setText("0");
|
|
||||||
binding.qualityImages.setText("0");
|
|
||||||
binding.achievementLevel.setText("0");
|
|
||||||
setMenuVisibility(true);
|
|
||||||
return rootView;
|
|
||||||
}
|
|
||||||
setWikidataEditCount();
|
|
||||||
setAchievements();
|
|
||||||
return rootView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
binding = null;
|
|
||||||
super.onDestroyView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMenuVisibility(boolean visible) {
|
|
||||||
super.setMenuVisibility(visible);
|
|
||||||
|
|
||||||
// Whenever this fragment is revealed in a menu,
|
|
||||||
// notify Beta users the page data is unavailable
|
|
||||||
if(ConfigUtils.isBetaFlavour() && visible) {
|
|
||||||
Context ctx = null;
|
|
||||||
if(getContext() != null) {
|
|
||||||
ctx = getContext();
|
|
||||||
} else if(getView() != null && getView().getContext() != null) {
|
|
||||||
ctx = getView().getContext();
|
|
||||||
}
|
|
||||||
if(ctx != null) {
|
|
||||||
Toast.makeText(ctx,
|
|
||||||
R.string.achievements_unavailable_beta,
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To invoke the AlertDialog on clicking info button
|
|
||||||
*/
|
|
||||||
protected void showInfoDialog(){
|
|
||||||
launchAlert(
|
|
||||||
getResources().getString(R.string.Achievements),
|
|
||||||
getResources().getString(R.string.achievements_info_message));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To call the API to get results in form Single<JSONObject>
|
|
||||||
* which then calls parseJson when results are fetched
|
|
||||||
*/
|
|
||||||
private void setAchievements() {
|
|
||||||
binding.progressBar.setVisibility(View.VISIBLE);
|
|
||||||
if (checkAccount()) {
|
|
||||||
try{
|
|
||||||
|
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
|
||||||
.getAchievements(Objects.requireNonNull(userName))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
response -> {
|
|
||||||
if (response != null) {
|
|
||||||
setUploadCount(Achievements.from(response));
|
|
||||||
} else {
|
|
||||||
Timber.d("success");
|
|
||||||
binding.layoutImageReverts.setVisibility(View.INVISIBLE);
|
|
||||||
binding.achievementBadgeImage.setVisibility(View.INVISIBLE);
|
|
||||||
// If the number of edits made by the user are more than 150,000
|
|
||||||
// in some cases such high number of wiki edit counts cause the
|
|
||||||
// achievements calculator to fail in some cases, for more details
|
|
||||||
// refer Issue: #3295
|
|
||||||
if (numberOfEdits <= 150000) {
|
|
||||||
showSnackBarWithRetry(false);
|
|
||||||
} else {
|
|
||||||
showSnackBarWithRetry(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
t -> {
|
|
||||||
Timber.e(t, "Fetching achievements statistics failed");
|
|
||||||
if (numberOfEdits <= 150000) {
|
|
||||||
showSnackBarWithRetry(false);
|
|
||||||
} else {
|
|
||||||
showSnackBarWithRetry(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
catch (Exception e){
|
|
||||||
Timber.d(e+"success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To call the API to fetch the count of wiki data edits
|
|
||||||
* in the form of JavaRx Single object<JSONobject>
|
|
||||||
*/
|
|
||||||
private void setWikidataEditCount() {
|
|
||||||
if (StringUtils.isBlank(userName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
|
||||||
.getWikidataEdits(userName)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(edits -> {
|
|
||||||
numberOfEdits = edits;
|
|
||||||
binding.wikidataEdits.setText(String.valueOf(edits));
|
|
||||||
}, e -> {
|
|
||||||
Timber.e("Error:" + e);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a snack bar which has an action button which on click dismisses the snackbar and invokes the
|
|
||||||
* listener passed
|
|
||||||
* @param tooManyAchievements if this value is true it means that the number of achievements of the
|
|
||||||
* user are so high that it wrecks havoc with the Achievements calculator due to which request may time
|
|
||||||
* out. Well this is the Ultimate Achievement
|
|
||||||
*/
|
|
||||||
private void showSnackBarWithRetry(boolean tooManyAchievements) {
|
|
||||||
if (tooManyAchievements) {
|
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
|
||||||
ViewUtil.showDismissibleSnackBar(getActivity().findViewById(android.R.id.content),
|
|
||||||
R.string.achievements_fetch_failed_ultimate_achievement, R.string.retry, view -> setAchievements());
|
|
||||||
} else {
|
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
|
||||||
ViewUtil.showDismissibleSnackBar(getActivity().findViewById(android.R.id.content),
|
|
||||||
R.string.achievements_fetch_failed, R.string.retry, view -> setAchievements());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a generic error toast when error occurs while loading achievements or uploads
|
|
||||||
*/
|
|
||||||
private void onError() {
|
|
||||||
ViewUtil.showLongToast(getActivity(), getResources().getString(R.string.error_occurred));
|
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* used to the count of images uploaded by user
|
|
||||||
*/
|
|
||||||
private void setUploadCount(Achievements achievements) {
|
|
||||||
if (checkAccount()) {
|
|
||||||
compositeDisposable.add(okHttpJsonApiClient
|
|
||||||
.getUploadCount(Objects.requireNonNull(userName))
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(
|
|
||||||
uploadCount -> setAchievementsUploadCount(achievements, uploadCount),
|
|
||||||
t -> {
|
|
||||||
Timber.e(t, "Fetching upload count failed");
|
|
||||||
onError();
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* used to set achievements upload count and call hideProgressbar
|
|
||||||
* @param uploadCount
|
|
||||||
*/
|
|
||||||
private void setAchievementsUploadCount(Achievements achievements, int uploadCount) {
|
|
||||||
// Create a new instance of Achievements with updated imagesUploaded
|
|
||||||
Achievements updatedAchievements = new Achievements(
|
|
||||||
achievements.getUniqueUsedImages(),
|
|
||||||
achievements.getArticlesUsingImages(),
|
|
||||||
achievements.getThanksReceived(),
|
|
||||||
achievements.getFeaturedImages(),
|
|
||||||
achievements.getQualityImages(),
|
|
||||||
uploadCount, // Update imagesUploaded with new value
|
|
||||||
achievements.getRevertCount()
|
|
||||||
);
|
|
||||||
|
|
||||||
hideProgressBar(updatedAchievements);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* used to the uploaded images progressbar
|
|
||||||
* @param uploadCount
|
|
||||||
*/
|
|
||||||
private void setUploadProgress(int uploadCount){
|
|
||||||
if (uploadCount==0){
|
|
||||||
setZeroAchievements();
|
|
||||||
}else {
|
|
||||||
binding.imagesUploadedProgressbar.setVisibility(View.VISIBLE);
|
|
||||||
binding.imagesUploadedProgressbar.setProgress
|
|
||||||
(100*uploadCount/levelInfo.getMaxUploadCount());
|
|
||||||
binding.tvUploadedImages.setText
|
|
||||||
(uploadCount + "/" + levelInfo.getMaxUploadCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setZeroAchievements() {
|
|
||||||
String message = !Objects.equals(sessionManager.getUserName(), userName) ?
|
|
||||||
getString(R.string.no_achievements_yet, userName) :
|
|
||||||
getString(R.string.you_have_no_achievements_yet);
|
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
|
||||||
null,
|
|
||||||
message,
|
|
||||||
getString(R.string.ok),
|
|
||||||
() -> {},
|
|
||||||
true);
|
|
||||||
// binding.imagesUploadedProgressbar.setVisibility(View.INVISIBLE);
|
|
||||||
// binding.imageRevertsProgressbar.setVisibility(View.INVISIBLE);
|
|
||||||
// binding.imagesUsedByWikiProgressBar.setVisibility(View.INVISIBLE);
|
|
||||||
binding.achievementBadgeImage.setVisibility(View.INVISIBLE);
|
|
||||||
binding.imagesUsedByWikiText.setText(R.string.no_image);
|
|
||||||
binding.imagesRevertedText.setText(R.string.no_image_reverted);
|
|
||||||
binding.imagesUploadTextParam.setText(R.string.no_image_uploaded);
|
|
||||||
binding.achievementBadgeImage.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* used to set the non revert image percentage
|
|
||||||
* @param notRevertPercentage
|
|
||||||
*/
|
|
||||||
private void setImageRevertPercentage(int notRevertPercentage){
|
|
||||||
binding.imageRevertsProgressbar.setVisibility(View.VISIBLE);
|
|
||||||
binding.imageRevertsProgressbar.setProgress(notRevertPercentage);
|
|
||||||
final String revertPercentage = Integer.toString(notRevertPercentage);
|
|
||||||
binding.tvRevertedImages.setText(revertPercentage + "%");
|
|
||||||
binding.imagesRevertLimitText.setText(getResources().getString(R.string.achievements_revert_limit_message)+ levelInfo.getMinNonRevertPercentage() + "%");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used the inflate the fetched statistics of the images uploaded by user
|
|
||||||
* and assign badge and level. Also stores the achievements level of the user in BasicKvStore to display in menu
|
|
||||||
* @param achievements
|
|
||||||
*/
|
|
||||||
private void inflateAchievements(Achievements achievements) {
|
|
||||||
// binding.imagesUsedByWikiProgressBar.setVisibility(View.VISIBLE);
|
|
||||||
binding.thanksReceived.setText(String.valueOf(achievements.getThanksReceived()));
|
|
||||||
binding.imagesUsedByWikiProgressBar.setProgress
|
|
||||||
(100 * achievements.getUniqueUsedImages() / levelInfo.getMaxUniqueImages());
|
|
||||||
binding.tvWikiPb.setText(achievements.getUniqueUsedImages() + "/"
|
|
||||||
+ levelInfo.getMaxUniqueImages());
|
|
||||||
binding.imageFeatured.setText(String.valueOf(achievements.getFeaturedImages()));
|
|
||||||
binding.qualityImages.setText(String.valueOf(achievements.getQualityImages()));
|
|
||||||
String levelUpInfoString = getString(R.string.level).toUpperCase(Locale.ROOT);
|
|
||||||
levelUpInfoString += " " + levelInfo.getLevelNumber();
|
|
||||||
binding.achievementLevel.setText(levelUpInfoString);
|
|
||||||
binding.achievementBadgeImage.setImageDrawable(VectorDrawableCompat.create(getResources(), R.drawable.badge,
|
|
||||||
new ContextThemeWrapper(getActivity(), levelInfo.getLevelStyle()).getTheme()));
|
|
||||||
binding.achievementBadgeText.setText(Integer.toString(levelInfo.getLevelNumber()));
|
|
||||||
BasicKvStore store = new BasicKvStore(this.getContext(), userName);
|
|
||||||
store.putString("userAchievementsLevel", Integer.toString(levelInfo.getLevelNumber()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* to hide progressbar
|
|
||||||
*/
|
|
||||||
private void hideProgressBar(Achievements achievements) {
|
|
||||||
if (binding.progressBar != null) {
|
|
||||||
levelInfo = LevelController.LevelInfo.from(achievements.getImagesUploaded(),
|
|
||||||
achievements.getUniqueUsedImages(),
|
|
||||||
achievements.getNotRevertPercentage());
|
|
||||||
inflateAchievements(achievements);
|
|
||||||
setUploadProgress(achievements.getImagesUploaded());
|
|
||||||
setImageRevertPercentage(achievements.getNotRevertPercentage());
|
|
||||||
binding.progressBar.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showUploadInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.images_uploaded),
|
|
||||||
getResources().getString(R.string.images_uploaded_explanation),
|
|
||||||
IMAGES_UPLOADED_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showRevertedInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.image_reverts),
|
|
||||||
getResources().getString(R.string.images_reverted_explanation),
|
|
||||||
IMAGES_REVERT_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showUsedByWikiInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.images_used_by_wiki),
|
|
||||||
getResources().getString(R.string.images_used_explanation),
|
|
||||||
IMAGES_USED_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showImagesViaNearbyInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.statistics_wikidata_edits),
|
|
||||||
getResources().getString(R.string.images_via_nearby_explanation),
|
|
||||||
IMAGES_NEARBY_PLACES_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showFeaturedImagesInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.statistics_featured),
|
|
||||||
getResources().getString(R.string.images_featured_explanation),
|
|
||||||
IMAGES_FEATURED_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showThanksReceivedInfo(){
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.statistics_thanks),
|
|
||||||
getResources().getString(R.string.thanks_received_explanation),
|
|
||||||
THANKS_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showQualityImagesInfo() {
|
|
||||||
launchAlertWithHelpLink(
|
|
||||||
getResources().getString(R.string.statistics_quality),
|
|
||||||
getResources().getString(R.string.quality_images_info),
|
|
||||||
QUALITY_IMAGE_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* takes title and message as input to display alerts
|
|
||||||
* @param title
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
private void launchAlert(String title, String message){
|
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
getString(R.string.ok),
|
|
||||||
() -> {},
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch Alert with a READ MORE button and clicking it open a custom webpage
|
|
||||||
*/
|
|
||||||
private void launchAlertWithHelpLink(String title, String message, String helpLinkUrl) {
|
|
||||||
DialogUtil.showAlertDialog(getActivity(),
|
|
||||||
title,
|
|
||||||
message,
|
|
||||||
getString(R.string.ok),
|
|
||||||
getString(R.string.read_help_link),
|
|
||||||
() -> {},
|
|
||||||
() -> Utils.handleWebUrl(requireContext(), Uri.parse(helpLinkUrl)),
|
|
||||||
null,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check to ensure that user is logged in
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean checkAccount(){
|
|
||||||
Account currentAccount = sessionManager.getCurrentAccount();
|
|
||||||
if (currentAccount == null) {
|
|
||||||
Timber.d("Current account is null");
|
|
||||||
ViewUtil.showLongToast(getActivity(), getResources().getString(R.string.user_not_logged_in));
|
|
||||||
sessionManager.forceLogin(getActivity());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,566 @@
|
||||||
|
package fr.free.nrw.commons.profile.achievements
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewTreeObserver
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||||
|
import com.google.android.material.badge.BadgeDrawable
|
||||||
|
import com.google.android.material.badge.BadgeUtils
|
||||||
|
import com.google.android.material.badge.ExperimentalBadgeUtils
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
|
import fr.free.nrw.commons.Utils
|
||||||
|
import fr.free.nrw.commons.auth.SessionManager
|
||||||
|
import fr.free.nrw.commons.databinding.FragmentAchievementsBinding
|
||||||
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
|
||||||
|
import fr.free.nrw.commons.kvstore.BasicKvStore
|
||||||
|
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
|
||||||
|
import fr.free.nrw.commons.profile.ProfileActivity
|
||||||
|
import fr.free.nrw.commons.profile.achievements.LevelController.LevelInfo.Companion.from
|
||||||
|
import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour
|
||||||
|
import fr.free.nrw.commons.utils.DialogUtil.showAlertDialog
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtil.showDismissibleSnackBar
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtil.showLongToast
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import org.apache.commons.lang3.StringUtils
|
||||||
|
import timber.log.Timber
|
||||||
|
import java.util.Objects
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class AchievementsFragment : CommonsDaggerSupportFragment(){
|
||||||
|
private lateinit var levelInfo: LevelController.LevelInfo
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var sessionManager: SessionManager
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var okHttpJsonApiClient: OkHttpJsonApiClient
|
||||||
|
|
||||||
|
private var _binding: FragmentAchievementsBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
// To keep track of the number of wiki edits made by a user
|
||||||
|
private var numberOfEdits: Int = 0
|
||||||
|
|
||||||
|
private var userName: String? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
arguments?.let {
|
||||||
|
userName = it.getString(ProfileActivity.KEY_USERNAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentAchievementsBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
binding.achievementInfo.setOnClickListener { showInfoDialog() }
|
||||||
|
binding.imagesUploadInfoIcon.setOnClickListener { showUploadInfo() }
|
||||||
|
binding.imagesRevertedInfoIcon.setOnClickListener { showRevertedInfo() }
|
||||||
|
binding.imagesUsedByWikiInfoIcon.setOnClickListener { showUsedByWikiInfo() }
|
||||||
|
binding.wikidataEditsIcon.setOnClickListener { showImagesViaNearbyInfo() }
|
||||||
|
binding.featuredImageIcon.setOnClickListener { showFeaturedImagesInfo() }
|
||||||
|
binding.thanksImageIcon.setOnClickListener { showThanksReceivedInfo() }
|
||||||
|
binding.qualityImageIcon.setOnClickListener { showQualityImagesInfo() }
|
||||||
|
|
||||||
|
// DisplayMetrics used to fetch the size of the screen
|
||||||
|
val displayMetrics = DisplayMetrics()
|
||||||
|
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||||
|
val height = displayMetrics.heightPixels
|
||||||
|
val width = displayMetrics.widthPixels
|
||||||
|
|
||||||
|
// Used for the setting the size of imageView at runtime
|
||||||
|
// TODO REMOVE
|
||||||
|
val params = binding.achievementBadgeImage.layoutParams as ConstraintLayout.LayoutParams
|
||||||
|
params.height = (height * BADGE_IMAGE_HEIGHT_RATIO).toInt()
|
||||||
|
params.width = (width * BADGE_IMAGE_WIDTH_RATIO).toInt()
|
||||||
|
binding.achievementBadgeImage.requestLayout()
|
||||||
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
setHasOptionsMenu(true)
|
||||||
|
if (sessionManager.userName == null || sessionManager.userName == userName) {
|
||||||
|
binding.tvAchievementsOfUser.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.tvAchievementsOfUser.visibility = View.VISIBLE
|
||||||
|
binding.tvAchievementsOfUser.text = getString(R.string.achievements_of_user, userName)
|
||||||
|
}
|
||||||
|
if (isBetaFlavour) {
|
||||||
|
binding.layout.visibility = View.GONE
|
||||||
|
setMenuVisibility(true)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setWikidataEditCount()
|
||||||
|
setAchievements()
|
||||||
|
return binding.root
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun setMenuVisibility(visible: Boolean) {
|
||||||
|
super.setMenuVisibility(visible)
|
||||||
|
|
||||||
|
// Whenever this fragment is revealed in a menu,
|
||||||
|
// notify Beta users the page data is unavailable
|
||||||
|
if (isBetaFlavour && visible) {
|
||||||
|
val ctx = context ?: view?.context
|
||||||
|
ctx?.let {
|
||||||
|
Toast.makeText(it, R.string.achievements_unavailable_beta, Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To invoke the AlertDialog on clicking info button
|
||||||
|
*/
|
||||||
|
fun showInfoDialog() {
|
||||||
|
launchAlert(
|
||||||
|
resources.getString(R.string.Achievements),
|
||||||
|
resources.getString(R.string.achievements_info_message)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To call the API to get results in form Single<JSONObject>
|
||||||
|
* which then calls parseJson when results are fetched
|
||||||
|
*/
|
||||||
|
|
||||||
|
private fun setAchievements() {
|
||||||
|
binding.progressBar.visibility = View.VISIBLE
|
||||||
|
if (checkAccount()) {
|
||||||
|
try {
|
||||||
|
compositeDisposable.add(
|
||||||
|
okHttpJsonApiClient
|
||||||
|
.getAchievements(userName ?: return)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{ response ->
|
||||||
|
if (response != null) {
|
||||||
|
setUploadCount(Achievements.from(response))
|
||||||
|
} else {
|
||||||
|
Timber.d("Success")
|
||||||
|
// TODO Create a Method to Hide all the Statistics
|
||||||
|
// binding.layoutImageReverts.visibility = View.INVISIBLE
|
||||||
|
// binding.achievementBadgeImage.visibility = View.INVISIBLE
|
||||||
|
// If the number of edits made by the user are more than 150,000
|
||||||
|
// in some cases such high number of wiki edit counts cause the
|
||||||
|
// achievements calculator to fail in some cases, for more details
|
||||||
|
// refer Issue: #3295
|
||||||
|
if (numberOfEdits <= 150_000) {
|
||||||
|
showSnackBarWithRetry(false)
|
||||||
|
} else {
|
||||||
|
showSnackBarWithRetry(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ throwable ->
|
||||||
|
Timber.e(throwable, "Fetching achievements statistics failed")
|
||||||
|
if (numberOfEdits <= 150_000) {
|
||||||
|
showSnackBarWithRetry(false)
|
||||||
|
} else {
|
||||||
|
showSnackBarWithRetry(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.d("Exception: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To call the API to fetch the count of wiki data edits
|
||||||
|
* in the form of JavaRx Single object<JSONobject>
|
||||||
|
</JSONobject> */
|
||||||
|
|
||||||
|
private fun setWikidataEditCount() {
|
||||||
|
if (StringUtils.isBlank(userName)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
compositeDisposable.add(
|
||||||
|
okHttpJsonApiClient
|
||||||
|
.getWikidataEdits(userName)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({ edits: Int ->
|
||||||
|
numberOfEdits = edits
|
||||||
|
showBadgesWithCount(view = binding.wikidataEditsIcon, count = edits)
|
||||||
|
}, { e: Throwable ->
|
||||||
|
Timber.e("Error:$e")
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a snack bar which has an action button which on click dismisses the snackbar and invokes the
|
||||||
|
* listener passed
|
||||||
|
* @param tooManyAchievements if this value is true it means that the number of achievements of the
|
||||||
|
* user are so high that it wrecks havoc with the Achievements calculator due to which request may time
|
||||||
|
* out. Well this is the Ultimate Achievement
|
||||||
|
*/
|
||||||
|
private fun showSnackBarWithRetry(tooManyAchievements: Boolean) {
|
||||||
|
if (tooManyAchievements) {
|
||||||
|
if (view == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
showDismissibleSnackBar(
|
||||||
|
requireView().findViewById(android.R.id.content),
|
||||||
|
R.string.achievements_fetch_failed_ultimate_achievement, R.string.retry
|
||||||
|
) { setAchievements() }
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (view == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
showDismissibleSnackBar(
|
||||||
|
requireView().findViewById(android.R.id.content),
|
||||||
|
R.string.achievements_fetch_failed, R.string.retry
|
||||||
|
) { setAchievements() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a generic error toast when error occurs while loading achievements or uploads
|
||||||
|
*/
|
||||||
|
private fun onError() {
|
||||||
|
showLongToast(requireActivity(), resources.getString(R.string.error_occurred))
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to the count of images uploaded by user
|
||||||
|
*/
|
||||||
|
|
||||||
|
private fun setUploadCount(achievements: Achievements) {
|
||||||
|
if (checkAccount()) {
|
||||||
|
compositeDisposable.add(okHttpJsonApiClient
|
||||||
|
.getUploadCount(Objects.requireNonNull<String>(userName))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{ uploadCount: Int? ->
|
||||||
|
setAchievementsUploadCount(
|
||||||
|
achievements,
|
||||||
|
uploadCount ?:0
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{ t: Throwable? ->
|
||||||
|
Timber.e(t, "Fetching upload count failed")
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to set achievements upload count and call hideProgressbar
|
||||||
|
* @param uploadCount
|
||||||
|
*/
|
||||||
|
private fun setAchievementsUploadCount(achievements: Achievements, uploadCount: Int) {
|
||||||
|
// Create a new instance of Achievements with updated imagesUploaded
|
||||||
|
val updatedAchievements = Achievements(
|
||||||
|
achievements.uniqueUsedImages,
|
||||||
|
achievements.articlesUsingImages,
|
||||||
|
achievements.thanksReceived,
|
||||||
|
achievements.featuredImages,
|
||||||
|
achievements.qualityImages,
|
||||||
|
uploadCount, // Update imagesUploaded with new value
|
||||||
|
achievements.revertCount
|
||||||
|
)
|
||||||
|
|
||||||
|
hideProgressBar(updatedAchievements)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to the uploaded images progressbar
|
||||||
|
* @param uploadCount
|
||||||
|
*/
|
||||||
|
private fun setUploadProgress(uploadCount: Int) {
|
||||||
|
if (uploadCount == 0) {
|
||||||
|
setZeroAchievements()
|
||||||
|
} else {
|
||||||
|
binding.imagesUploadedProgressbar.visibility = View.VISIBLE
|
||||||
|
binding.imagesUploadedProgressbar.progress =
|
||||||
|
100 * uploadCount / levelInfo.maxUploadCount
|
||||||
|
binding.imageUploadedTVCount.text = uploadCount.toString() + "/" + levelInfo.maxUploadCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setZeroAchievements() {
|
||||||
|
val message = if (sessionManager.userName != userName) {
|
||||||
|
getString(R.string.no_achievements_yet, userName )
|
||||||
|
} else {
|
||||||
|
getString(R.string.you_have_no_achievements_yet)
|
||||||
|
}
|
||||||
|
showAlertDialog(
|
||||||
|
requireActivity(),
|
||||||
|
null,
|
||||||
|
message,
|
||||||
|
getString(R.string.ok),
|
||||||
|
{},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
// binding.imagesUploadedProgressbar.setVisibility(View.INVISIBLE);
|
||||||
|
// binding.imageRevertsProgressbar.setVisibility(View.INVISIBLE);
|
||||||
|
// binding.imagesUsedByWikiProgressBar.setVisibility(View.INVISIBLE);
|
||||||
|
//binding.achievementBadgeImage.visibility = View.INVISIBLE // TODO
|
||||||
|
binding.imagesUsedCount.setText(R.string.no_image)
|
||||||
|
binding.imagesRevertedText.setText(R.string.no_image_reverted)
|
||||||
|
binding.imagesUploadTextParam.setText(R.string.no_image_uploaded)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to set the non revert image percentage
|
||||||
|
* @param notRevertPercentage
|
||||||
|
*/
|
||||||
|
private fun setImageRevertPercentage(notRevertPercentage: Int) {
|
||||||
|
binding.imageRevertsProgressbar.visibility = View.VISIBLE
|
||||||
|
binding.imageRevertsProgressbar.progress = notRevertPercentage
|
||||||
|
val revertPercentage = notRevertPercentage.toString()
|
||||||
|
binding.imageRevertTVCount.text = "$revertPercentage%"
|
||||||
|
binding.imagesRevertLimitText.text =
|
||||||
|
resources.getString(R.string.achievements_revert_limit_message) + levelInfo.minNonRevertPercentage + "%"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used the inflate the fetched statistics of the images uploaded by user
|
||||||
|
* and assign badge and level. Also stores the achievements level of the user in BasicKvStore to display in menu
|
||||||
|
* @param achievements
|
||||||
|
*/
|
||||||
|
private fun inflateAchievements(achievements: Achievements) {
|
||||||
|
|
||||||
|
// Thanks Received Badge
|
||||||
|
showBadgesWithCount(view = binding.thanksImageIcon, count = achievements.thanksReceived)
|
||||||
|
|
||||||
|
// Featured Images Badge
|
||||||
|
showBadgesWithCount(view = binding.featuredImageIcon, count = achievements.featuredImages)
|
||||||
|
|
||||||
|
// Quality Images Badge
|
||||||
|
showBadgesWithCount(view = binding.qualityImageIcon, count = achievements.qualityImages)
|
||||||
|
|
||||||
|
binding.imagesUsedByWikiProgressBar.progress =
|
||||||
|
100 * achievements.uniqueUsedImages / levelInfo.maxUniqueImages
|
||||||
|
binding.imagesUsedCount.text = (achievements.uniqueUsedImages.toString() + "/"
|
||||||
|
+ levelInfo.maxUniqueImages)
|
||||||
|
|
||||||
|
binding.achievementLevel.text = getString(R.string.level,levelInfo.levelNumber)
|
||||||
|
binding.achievementBadgeImage.setImageDrawable(
|
||||||
|
VectorDrawableCompat.create(
|
||||||
|
resources, R.drawable.badge,
|
||||||
|
ContextThemeWrapper(activity, levelInfo.levelStyle).theme
|
||||||
|
)
|
||||||
|
)
|
||||||
|
binding.achievementBadgeText.text = levelInfo.levelNumber.toString()
|
||||||
|
val store = BasicKvStore(requireContext(), userName)
|
||||||
|
store.putString("userAchievementsLevel", levelInfo.levelNumber.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used to show badge on any view (button, imageView, etc)
|
||||||
|
* @param view The View on which the badge will be displayed eg (button, imageView, etc)
|
||||||
|
* @param count The number to be displayed inside the badge.
|
||||||
|
* @param backgroundColor The badge background color. Default is R.attr.colorPrimary
|
||||||
|
* @param badgeTextColor The badge text color. Default is R.attr.colorPrimary
|
||||||
|
* @param badgeGravity The position of the badge [TOP_END,TOP_START,BOTTOM_END,BOTTOM_START]. Default is TOP_END
|
||||||
|
* @return if the number is 0, then it will not create badge for it and hide the view
|
||||||
|
* @see https://developer.android.com/reference/com/google/android/material/badge/BadgeDrawable
|
||||||
|
*/
|
||||||
|
|
||||||
|
private fun showBadgesWithCount(
|
||||||
|
view: View,
|
||||||
|
count: Int,
|
||||||
|
backgroundColor: Int = R.attr.colorPrimary,
|
||||||
|
badgeTextColor: Int = R.attr.textEnabled,
|
||||||
|
badgeGravity: Int = BadgeDrawable.TOP_END
|
||||||
|
) {
|
||||||
|
//https://stackoverflow.com/a/67742035
|
||||||
|
if (count == 0) {
|
||||||
|
view.visibility = View.GONE
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
view.viewTreeObserver.addOnGlobalLayoutListener(object :
|
||||||
|
ViewTreeObserver.OnGlobalLayoutListener {
|
||||||
|
/**
|
||||||
|
* Callback method to be invoked when the global layout state or the visibility of views
|
||||||
|
* within the view tree changes
|
||||||
|
*/
|
||||||
|
@ExperimentalBadgeUtils
|
||||||
|
override fun onGlobalLayout() {
|
||||||
|
view.visibility = View.VISIBLE
|
||||||
|
val badgeDrawable = BadgeDrawable.create(requireActivity())
|
||||||
|
badgeDrawable.number = count
|
||||||
|
badgeDrawable.badgeGravity = badgeGravity
|
||||||
|
badgeDrawable.badgeTextColor = badgeTextColor
|
||||||
|
badgeDrawable.backgroundColor = backgroundColor
|
||||||
|
BadgeUtils.attachBadgeDrawable(badgeDrawable, view)
|
||||||
|
view.getViewTreeObserver().removeOnGlobalLayoutListener(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to hide progressbar
|
||||||
|
*/
|
||||||
|
private fun hideProgressBar(achievements: Achievements) {
|
||||||
|
if (binding.progressBar != null) {
|
||||||
|
levelInfo = from(
|
||||||
|
achievements.imagesUploaded,
|
||||||
|
achievements.uniqueUsedImages,
|
||||||
|
achievements.notRevertPercentage
|
||||||
|
)
|
||||||
|
inflateAchievements(achievements)
|
||||||
|
setUploadProgress(achievements.imagesUploaded)
|
||||||
|
setImageRevertPercentage(achievements.notRevertPercentage)
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showUploadInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.images_uploaded),
|
||||||
|
resources.getString(R.string.images_uploaded_explanation),
|
||||||
|
IMAGES_UPLOADED_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showRevertedInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.image_reverts),
|
||||||
|
resources.getString(R.string.images_reverted_explanation),
|
||||||
|
IMAGES_REVERT_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showUsedByWikiInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.images_used_by_wiki),
|
||||||
|
resources.getString(R.string.images_used_explanation),
|
||||||
|
IMAGES_USED_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showImagesViaNearbyInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.statistics_wikidata_edits),
|
||||||
|
resources.getString(R.string.images_via_nearby_explanation),
|
||||||
|
IMAGES_NEARBY_PLACES_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showFeaturedImagesInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.statistics_featured),
|
||||||
|
resources.getString(R.string.images_featured_explanation),
|
||||||
|
IMAGES_FEATURED_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showThanksReceivedInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.statistics_thanks),
|
||||||
|
resources.getString(R.string.thanks_received_explanation),
|
||||||
|
THANKS_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showQualityImagesInfo() {
|
||||||
|
launchAlertWithHelpLink(
|
||||||
|
resources.getString(R.string.statistics_quality),
|
||||||
|
resources.getString(R.string.quality_images_info),
|
||||||
|
QUALITY_IMAGE_URL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* takes title and message as input to display alerts
|
||||||
|
* @param title
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
private fun launchAlert(title: String, message: String) {
|
||||||
|
showAlertDialog(
|
||||||
|
requireActivity(),
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
getString(R.string.ok),
|
||||||
|
{},
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch Alert with a READ MORE button and clicking it open a custom webpage
|
||||||
|
*/
|
||||||
|
private fun launchAlertWithHelpLink(title: String, message: String, helpLinkUrl: String) {
|
||||||
|
showAlertDialog(
|
||||||
|
requireActivity(),
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
getString(R.string.ok),
|
||||||
|
getString(R.string.read_help_link),
|
||||||
|
{},
|
||||||
|
{ Utils.handleWebUrl(requireContext(), Uri.parse(helpLinkUrl)) },
|
||||||
|
null,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* check to ensure that user is logged in
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private fun checkAccount(): Boolean {
|
||||||
|
val currentAccount = sessionManager.currentAccount
|
||||||
|
if (currentAccount == null) {
|
||||||
|
Timber.d("Current account is null")
|
||||||
|
showLongToast(requireActivity(), resources.getString(R.string.user_not_logged_in))
|
||||||
|
sessionManager.forceLogin(activity)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
companion object{
|
||||||
|
private const val BADGE_IMAGE_WIDTH_RATIO = 0.4
|
||||||
|
private const val BADGE_IMAGE_HEIGHT_RATIO = 0.3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help link URLs
|
||||||
|
*/
|
||||||
|
private const val IMAGES_UPLOADED_URL = "https://commons.wikimedia.org/wiki/Commons:Project_scope"
|
||||||
|
private const val IMAGES_REVERT_URL = "https://commons.wikimedia.org/wiki/Commons:Deletion_policy#Reasons_for_deletion"
|
||||||
|
private const val IMAGES_USED_URL = "https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Images"
|
||||||
|
private const val IMAGES_NEARBY_PLACES_URL = "https://www.wikidata.org/wiki/Property:P18"
|
||||||
|
private const val IMAGES_FEATURED_URL = "https://commons.wikimedia.org/wiki/Commons:Featured_pictures"
|
||||||
|
private const val QUALITY_IMAGE_URL = "https://commons.wikimedia.org/wiki/Commons:Quality_images"
|
||||||
|
private const val THANKS_URL = "https://www.mediawiki.org/wiki/Extension:Thanks"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/drawer_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/achievementBackground">
|
android:background="?attr/achievementBackground"
|
||||||
|
android:fillViewport="true"
|
||||||
|
tools:ignore="ContentDescription" >
|
||||||
|
|
||||||
<ScrollView
|
<!-- TODO Add ContentDescription For ALL Images Added ignore to suppress Lints -->
|
||||||
android:layout_width="wrap_content"
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/tv_achievements_of_user"
|
android:id="@+id/tv_achievements_of_user"
|
||||||
|
|
@ -22,51 +22,34 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="Achievements of user : Ashish" />
|
tools:text="Achievements of user : Ashish" />
|
||||||
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="?attr/achievementBackground"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="?android:textAppearanceLarge"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:text="@string/level"
|
|
||||||
android:id="@+id/achievement_level"
|
|
||||||
android:textAllCaps="true"/>
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/achievement_info"
|
android:id="@+id/achievement_info"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/activity_margin_vertical"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
android:layout_alignParentEnd="true"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_achievements_of_user"
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
app:srcCompat="@drawable/ic_info_outline_24dp"
|
||||||
android:layout_marginVertical="@dimen/activity_margin_vertical"
|
app:tint="@color/black"
|
||||||
app:tint="@color/black" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/badge_layout"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/achievement_info"
|
|
||||||
android:layout_centerHorizontal="true">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/achievement_badge_image"
|
android:id="@+id/achievement_badge_image"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="150dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="150dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/badge"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:srcCompat="@drawable/badge" />
|
tools:layout_height="100dp"
|
||||||
|
tools:layout_width="100dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/achievement_badge_text"
|
android:id="@+id/achievement_badge_text"
|
||||||
|
|
@ -75,566 +58,311 @@
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="@color/achievement_badge_text"
|
android:textColor="@color/achievement_badge_text"
|
||||||
android:textSize="75sp"
|
android:textSize="75sp"
|
||||||
|
tools:text="1"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/achievement_badge_image"
|
app:layout_constraintBottom_toBottomOf="@+id/achievement_badge_image"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/achievement_badge_image"
|
app:layout_constraintEnd_toEndOf="@+id/achievement_badge_image"
|
||||||
app:layout_constraintStart_toStartOf="@+id/achievement_badge_image"
|
app:layout_constraintStart_toStartOf="@+id/achievement_badge_image"
|
||||||
app:layout_constraintTop_toTopOf="@+id/achievement_badge_image"
|
app:layout_constraintTop_toTopOf="@+id/achievement_badge_image"
|
||||||
app:layout_constraintVertical_bias="0.58" />
|
app:layout_constraintVertical_bias="0.58" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/layout_image_uploaded"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/badge_layout"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/images_upload_info"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="?android:textAppearanceMedium"
|
android:id="@+id/achievement_level"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/level"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/achievement_badge_image" />
|
||||||
|
|
||||||
|
<!-- Images Uploaded -->
|
||||||
|
<TextView
|
||||||
android:id="@+id/images_upload_text_param"
|
android:id="@+id/images_upload_text_param"
|
||||||
android:layout_marginTop="@dimen/achievements_activity_margin_vertical"
|
style="?android:textAppearanceMedium"
|
||||||
android:text="@string/images_uploaded" />
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:text="@string/images_uploaded"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/achievement_level" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="@dimen/quarter_standard_height"
|
android:id="@+id/images_upload_info_icon"
|
||||||
android:layout_height="@dimen/quarter_standard_height"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/images_upload_text_param"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/images_upload_text_param"
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
app:srcCompat="@drawable/ic_info_outline_24dp"
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
app:tint="@color/black" />
|
||||||
|
|
||||||
|
<!-- Image's Uploaded Progress Bar -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_images_Uploaded"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
app:tint="@color/primaryLightColor" />
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/images_upload_text_param">
|
||||||
|
|
||||||
</LinearLayout>
|
<ProgressBar
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="@dimen/dimen_40"
|
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="32dp">
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
|
||||||
android:id="@+id/images_uploaded_progressbar"
|
android:id="@+id/images_uploaded_progressbar"
|
||||||
android:layout_width="@dimen/dimen_40"
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:indeterminate="false"
|
|
||||||
android:layout_marginEnd="@dimen/large_gap"
|
|
||||||
app:showAnimationBehavior="outward"
|
|
||||||
app:indicatorColor="@color/primaryColor"
|
|
||||||
app:indicatorSize="32dp"
|
|
||||||
app:trackThickness="@dimen/progressbar_stroke"
|
|
||||||
app:trackColor="#B7B6B6"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tv_uploaded_images"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:padding="@dimen/progressbar_padding"
|
|
||||||
android:gravity="center"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="@color/secondaryColor"
|
|
||||||
app:autoSizeMaxTextSize="@dimen/progressbar_text"
|
|
||||||
app:autoSizeMinTextSize="2sp"
|
|
||||||
app:autoSizeStepGranularity="1sp"
|
|
||||||
app:autoSizeTextType="uniform" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/layout_image_reverts"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/tiny_margin"
|
android:layout_centerInParent="true"
|
||||||
android:layout_below="@+id/layout_image_uploaded"
|
android:progressDrawable="@android:drawable/progress_horizontal"
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
android:progressBackgroundTintMode="multiply"
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
android:progressTint="#5ce65c"
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
tools:progress="50" />
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/images_reverted_info"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/imageUploadedTVCount"
|
||||||
style="?android:textAppearanceMedium"
|
style="?android:textAppearanceMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
tools:text="10/15" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:id="@+id/materialDivider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/rl_images_Uploaded" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Image's Not Reverted -->
|
||||||
|
<TextView
|
||||||
android:id="@+id/images_reverted_text"
|
android:id="@+id/images_reverted_text"
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:text="@string/image_reverts" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/medium_width"
|
|
||||||
android:layout_height="@dimen/medium_height"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal" app:tint="@color/primaryLightColor" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/achievements_revert_limit_message"
|
|
||||||
android:textSize="@dimen/small_text"
|
|
||||||
android:id="@+id/images_revert_limit_text"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_below="@id/images_reverted_info"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="@dimen/dimen_40"
|
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="32dp">
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
|
||||||
android:id="@+id/image_reverts_progressbar"
|
|
||||||
android:layout_width="@dimen/dimen_40"
|
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:indeterminate="false"
|
|
||||||
android:layout_marginEnd="@dimen/large_gap"
|
|
||||||
app:showAnimationBehavior="outward"
|
|
||||||
app:indicatorColor="@color/primaryColor"
|
|
||||||
app:indicatorSize="32dp"
|
|
||||||
app:trackThickness="@dimen/progressbar_stroke"
|
|
||||||
app:trackColor="#B7B6B6"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tv_reverted_images"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:padding="@dimen/progressbar_padding"
|
|
||||||
android:gravity="center"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="@color/secondaryColor"
|
|
||||||
app:autoSizeMaxTextSize="@dimen/progressbar_text"
|
|
||||||
app:autoSizeMinTextSize="2sp"
|
|
||||||
app:autoSizeStepGranularity="1sp"
|
|
||||||
app:autoSizeTextType="uniform" />
|
|
||||||
</FrameLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/layout_image_used_by_wiki"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/tiny_margin"
|
|
||||||
android:layout_below="@+id/layout_image_reverts"
|
|
||||||
android:layout_marginBottom="@dimen/activity_margin_vertical"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/images_used_by_wiki_info"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
style="?android:textAppearanceMedium"
|
style="?android:textAppearanceMedium"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/images_used_by_wiki_text"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
android:layout_marginTop="@dimen/achievements_activity_margin_vertical"
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
android:text="@string/images_used_by_wiki" />
|
android:text="@string/image_reverts"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/materialDivider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/images_revert_limit_text"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
android:text="@string/achievements_revert_limit_message"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/images_reverted_text"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/images_reverted_info_icon"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/images_reverted_text"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/images_reverted_text" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="@dimen/medium_width"
|
android:id="@+id/images_reverted_info_icon"
|
||||||
android:layout_height="@dimen/medium_height"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/images_revert_limit_text"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/images_revert_limit_text"
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
app:srcCompat="@drawable/ic_info_outline_24dp"
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
app:tint="@color/black" />
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
app:tint="@color/primaryLightColor" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
<!-- Image's Not Reverted Progress Bar -->
|
||||||
|
<RelativeLayout
|
||||||
<FrameLayout
|
android:id="@+id/rl_images_reverted"
|
||||||
android:layout_width="@dimen/dimen_40"
|
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="32dp">
|
|
||||||
|
|
||||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
|
||||||
android:id="@+id/images_used_by_wiki_progress_bar"
|
|
||||||
android:layout_width="@dimen/dimen_40"
|
|
||||||
android:layout_height="@dimen/dimen_40"
|
|
||||||
android:indeterminate="false"
|
|
||||||
android:layout_marginEnd="@dimen/large_gap"
|
|
||||||
app:showAnimationBehavior="outward"
|
|
||||||
app:indicatorColor="@color/primaryColor"
|
|
||||||
app:indicatorSize="32dp"
|
|
||||||
app:trackThickness="@dimen/progressbar_stroke"
|
|
||||||
app:trackColor="#B7B6B6"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
|
||||||
android:id="@+id/tv_wiki_pb"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:padding="@dimen/progressbar_padding"
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
android:gravity="center"
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
android:maxLines="1"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:textColor="@color/secondaryColor"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:autoSizeMaxTextSize="@dimen/progressbar_text"
|
app:layout_constraintTop_toBottomOf="@+id/images_reverted_text">
|
||||||
app:autoSizeMinTextSize="2sp"
|
|
||||||
app:autoSizeStepGranularity="1sp"
|
|
||||||
app:autoSizeTextType="uniform" />
|
|
||||||
|
|
||||||
</FrameLayout>
|
<ProgressBar
|
||||||
|
android:id="@+id/image_reverts_progressbar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:progressDrawable="@android:drawable/progress_horizontal"
|
||||||
|
android:progressBackgroundTintMode="multiply"
|
||||||
|
android:progressTint="#5ce65c"
|
||||||
|
tools:progress="50" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/imageRevertTVCount"
|
||||||
|
style="?android:textAppearanceMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
tools:text="10/15" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:id="@+id/materialDivider1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/rl_images_reverted" />
|
||||||
|
|
||||||
|
<!-- Image Used -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/images_used_tv"
|
||||||
|
style="?android:textAppearanceMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:text="@string/images_used_by_wiki"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/materialDivider1" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/images_used_by_wiki_info_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/images_used_tv"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/images_used_tv"
|
||||||
|
app:srcCompat="@drawable/ic_info_outline_24dp"
|
||||||
|
app:tint="@color/black" />
|
||||||
|
|
||||||
|
<!-- Image's Used Progress Bar -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/rl_images_used"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/images_used_tv">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/images_used_by_wiki_progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:progressDrawable="@android:drawable/progress_horizontal"
|
||||||
|
android:progressBackgroundTintMode="multiply"
|
||||||
|
android:progressTint="#5ce65c"
|
||||||
|
tools:progress="50" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/imagesUsedCount"
|
||||||
|
style="?android:textAppearanceMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
tools:text="10/15" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:id="@+id/materialDivider2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/rl_images_used" />
|
||||||
|
|
||||||
|
<!-- Statistics -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_statistics"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
||||||
|
android:text="@string/badges"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/materialDivider2" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/badgesItems"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
||||||
|
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="@dimen/activity_margin_horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tv_statistics">
|
||||||
|
|
||||||
|
<!--Nearby Places Statistics-->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/wikidata_edits_icon"
|
||||||
|
android:layout_width="@dimen/dimen_40"
|
||||||
|
android:layout_height="@dimen/dimen_40"
|
||||||
|
android:layout_marginEnd="@dimen/large_gap"
|
||||||
|
app:srcCompat="@drawable/ic_custom_map_marker" />
|
||||||
|
|
||||||
|
<!--Featured Image Statistics-->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/featured_image_icon"
|
||||||
|
android:layout_width="@dimen/dimen_40"
|
||||||
|
android:layout_height="@dimen/dimen_40"
|
||||||
|
android:layout_marginEnd="@dimen/large_gap"
|
||||||
|
app:srcCompat="@drawable/featured" />
|
||||||
|
|
||||||
|
<!--Quality Image Statistics-->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/quality_image_icon"
|
||||||
|
android:layout_width="@dimen/dimen_40"
|
||||||
|
android:layout_height="@dimen/dimen_40"
|
||||||
|
android:layout_marginEnd="@dimen/large_gap"
|
||||||
|
app:srcCompat="@drawable/ic_quality_images_logo" />
|
||||||
|
|
||||||
|
<!--Thank Image Statistics-->
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/thanks_image_icon"
|
||||||
|
android:layout_width="@dimen/dimen_40"
|
||||||
|
android:layout_height="@dimen/dimen_40"
|
||||||
|
android:layout_marginEnd="@dimen/large_gap"
|
||||||
|
app:srcCompat="@drawable/ic_thanks" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/layout_statistics"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/statistics"
|
|
||||||
style="?android:textAppearanceLarge"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_vertical"
|
|
||||||
android:textAllCaps="true"/>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/images_nearby_info"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@+id/wikidata_edits"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/wikidata_edits_icon"
|
|
||||||
android:layout_width="@dimen/overflow_icon_dimen"
|
|
||||||
android:layout_height="@dimen/overflow_icon_dimen"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/ic_custom_map_marker_dark" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:id="@+id/images_nearby_data"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/wikidata_edits_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintRight_toLeftOf="@id/images_nearby_info_icon"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:text="@string/statistics_wikidata_edits" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/medium_width"
|
|
||||||
android:layout_height="@dimen/medium_height"
|
|
||||||
android:id="@+id/images_nearby_info_icon"
|
|
||||||
android:layout_marginTop="@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_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintVertical_bias="0.5"
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:tint="@color/primaryLightColor" />
|
android:visibility="gone"/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginEnd="@dimen/half_standard_height"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
tools:text="2"
|
|
||||||
android:id="@+id/wikidata_edits"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/images_featured_info"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@+id/image_featured"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/overflow_icon_dimen"
|
|
||||||
android:layout_height="@dimen/overflow_icon_dimen"
|
|
||||||
android:id="@+id/featured_image_icon"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/featured"
|
|
||||||
android:scaleType="centerCrop" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:id="@+id/images_featured_data"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
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" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/medium_width"
|
|
||||||
android:layout_height="@dimen/medium_height"
|
|
||||||
android:id="@+id/images_featured_info_icon"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/images_featured_data"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
|
||||||
app:tint="@color/primaryLightColor" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
tools:text="2"
|
|
||||||
android:id="@+id/image_featured"
|
|
||||||
android:layout_marginEnd="@dimen/half_standard_height"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/quality_images_info"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@+id/quality_images"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/overflow_icon_dimen"
|
|
||||||
android:layout_height="@dimen/overflow_icon_dimen"
|
|
||||||
android:id="@+id/quality_image_icon"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/ic_quality_images_logo"
|
|
||||||
android:scaleType="centerInside" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:id="@+id/quality_images_data"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
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" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/medium_width"
|
|
||||||
android:layout_height="@dimen/medium_height"
|
|
||||||
android:id="@+id/quality_images_info_icon"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/quality_images_data"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
|
||||||
app:tint="@color/primaryLightColor" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
tools:text="2"
|
|
||||||
android:text="0"
|
|
||||||
android:id="@+id/quality_images"
|
|
||||||
android:layout_marginEnd="@dimen/half_standard_height"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginRight="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/thanks_received_info"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_toStartOf="@+id/thanks_received"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/overflow_icon_dimen"
|
|
||||||
android:layout_height="@dimen/overflow_icon_dimen"
|
|
||||||
android:id="@+id/thanks_image_icon"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:srcCompat="@drawable/ic_thanks"
|
|
||||||
android:scaleType="centerCrop" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:id="@+id/thanks_received_data"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginLeft="@dimen/activity_margin_horizontal"
|
|
||||||
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" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="@dimen/medium_width"
|
|
||||||
android:layout_height="@dimen/medium_height"
|
|
||||||
android:id="@+id/thanks_received_info_icon"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginEnd="@dimen/activity_margin_horizontal"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/thanks_received_data"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
app:srcCompat="@drawable/ic_info_outline_24dp"
|
|
||||||
app:tint="@color/primaryLightColor" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="?android:textAppearanceMedium"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_marginTop="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_marginStart="@dimen/activity_margin_horizontal"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
tools:text="2"
|
|
||||||
android:id="@+id/thanks_received"
|
|
||||||
android:layout_marginEnd="@dimen/half_standard_height"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
||||||
|
|
|
||||||
|
|
@ -371,11 +371,13 @@
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="Achievements">Achievements</string>
|
<string name="Achievements">Achievements</string>
|
||||||
<string name="Profile">Profile</string>
|
<string name="Profile">Profile</string>
|
||||||
|
<string name="badges">Badges</string>
|
||||||
<string name="statistics">Statistics</string>
|
<string name="statistics">Statistics</string>
|
||||||
<string name="statistics_thanks">Thanks Received</string>
|
<string name="statistics_thanks">Thanks Received</string>
|
||||||
<string name="statistics_featured">Featured Images</string>
|
<string name="statistics_featured">Featured Images</string>
|
||||||
<string name="statistics_wikidata_edits">Images via \"Nearby Places\"</string>
|
<string name="statistics_wikidata_edits">Images via \"Nearby Places\"</string>
|
||||||
<string name="level">Level</string>
|
<string name="level">Level %d</string>
|
||||||
|
<string name="profileLevel">%s (Level %s)</string>
|
||||||
<string name="images_uploaded">Images Uploaded</string>
|
<string name="images_uploaded">Images Uploaded</string>
|
||||||
<string name="image_reverts">Images Not Reverted</string>
|
<string name="image_reverts">Images Not Reverted</string>
|
||||||
<string name="images_used_by_wiki">Images Used</string>
|
<string name="images_used_by_wiki">Images Used</string>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="DarkAppTheme" parent="Theme.AppCompat.NoActionBar">
|
<style name="DarkAppTheme" parent="Theme.MaterialComponents.NoActionBar.Bridge">
|
||||||
<item name="contributionsListBackground">@color/contributionListDarkBackground</item>
|
<item name="contributionsListBackground">@color/contributionListDarkBackground</item>
|
||||||
<item name="tabBackground">@color/contributionListDarkBackground</item>
|
<item name="tabBackground">@color/contributionListDarkBackground</item>
|
||||||
<item name="tabIndicatorColor">@color/white</item>
|
<item name="tabIndicatorColor">@color/white</item>
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
<item name="android:splitMotionEvents">false</item>
|
<item name="android:splitMotionEvents">false</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="LightAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="LightAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
|
||||||
<item name="contributionsListBackground">@color/white</item>
|
<item name="contributionsListBackground">@color/white</item>
|
||||||
<item name="tabBackground">@color/card_light_grey</item>
|
<item name="tabBackground">@color/card_light_grey</item>
|
||||||
<item name="tabIndicatorColor">@color/primaryDarkColor</item>
|
<item name="tabIndicatorColor">@color/primaryDarkColor</item>
|
||||||
|
|
@ -73,6 +73,7 @@
|
||||||
<item name="drawerHeaderBackground">@color/drawerHeader_background_light</item>
|
<item name="drawerHeaderBackground">@color/drawerHeader_background_light</item>
|
||||||
<item name="tutorialBackground">@color/tutorial_background_light</item>
|
<item name="tutorialBackground">@color/tutorial_background_light</item>
|
||||||
<item name="icon">@color/secondaryTextColor</item>
|
<item name="icon">@color/secondaryTextColor</item>
|
||||||
|
<item name="colorPrimary">@color/primaryDarkColor</item>
|
||||||
<item name="colorPrimaryDark">@color/primaryDarkColor</item>
|
<item name="colorPrimaryDark">@color/primaryDarkColor</item>
|
||||||
<item name="colorAccent">@color/primaryColor</item>
|
<item name="colorAccent">@color/primaryColor</item>
|
||||||
<item name="colorButtonNormal">@color/primaryColor</item>
|
<item name="colorButtonNormal">@color/primaryColor</item>
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ class AchievementsFragmentUnitTests {
|
||||||
fragmentTransaction.commitNowAllowingStateLoss()
|
fragmentTransaction.commitNowAllowingStateLoss()
|
||||||
|
|
||||||
layoutInflater = LayoutInflater.from(activity)
|
layoutInflater = LayoutInflater.from(activity)
|
||||||
view = fragment.onCreateView(layoutInflater, activity.findViewById(R.id.container), null)!!
|
view = fragment.onCreateView(layoutInflater, activity.findViewById(R.id.container), null)
|
||||||
|
|
||||||
achievements = Achievements(0, 0, 0, 0, 0, 0, 0)
|
achievements = Achievements(0, 0, 0, 0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue