mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-29 22:03:55 +01:00
Include previous Wikimedia hackathon (2018) task, peer review, to codebase (#2602)
* Add new activity to manifest * Create review activity layout base * Add a new menu item to drawer for peer review * Add a top menu with randomizer icon to review activity * Add strings for review button * Add activity to ActivityBuilderModule for injection * Add a new drawer item to start review acitivty * Create base of the Review Activity * Add fragment pager * Add new fragment for injection * Create a fragment pager layout * Wikimedia hackathon 2018 (#1533) * First draft of fn to get random recent image * Use log entries for requests to beta, try to connect refresh button FIXME: runs http request on main thread, breaks * Tweak button connection * Add ReviewController class * Fix fragments * Wmhack2018 (#1534) * tiny fixes * Load pictures into activities * Re-use same class for all review fragments (#1537) And try to add pager indicator * [WIP] category check * [WIP] add on-click actions to ReviewActivity * [WIP] add SendThankTask * Make it beautiful * Add some category stuff back in to review (#1538) * Use standalone category extraction code in MediaDataExtractor * Add categories to category review page * Change category question text sizes * Call randomizer whenever the activity is ready * Add progressbar * [WIP] add DeleteTask.askReasonAndExecute * Fix refresh button string * Typo: "nominate *for* deletion" * Add formatting to categories and put them in the same textView * Pass context and adapters as parameters to controller * Add actions to controller * Make everyting work * Add another fragment to thank * Fix npe * Add missing execute method * Some codes * Add a funy text * More random recent image selection (#1542) time-based randomness is biased - if someone uploaded 100 images in hour, one week ago, and I select a random point in time, their last image is way more likely to come up than anything else. With this, there is still bias towards choosing one of the last N in any burst of uploads (where N is the number of recent changes fetched) but it's a bit better than before. * Create Revision class * Add meaningluf strings * Error handling for review image/category fetch (#1543) * Add information layout for username and filename * Use Single to get firstRevision * try to add username and filename * Ensure caption is shown on every review fragment * Fix build * Fixes missing import * Change button text,show current category, add skip image button * Modify texts, fix night mode issues * Positive Wording * fix landscape issue * Add checkbox popup,rewording * Spelling Correction * Fix merge * Remove commented out code, use lambda * Simplify toolbar include
This commit is contained in:
parent
a1a65d0832
commit
a32ba452ec
33 changed files with 1594 additions and 33 deletions
|
|
@ -0,0 +1,129 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
// Example code:
|
||||
// CheckCategoryTask deleteTask = new CheckCategoryTask(getActivity(), media);
|
||||
|
||||
// TODO: refactor; see DeleteTask and SendThankTask
|
||||
public class CheckCategoryTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Inject
|
||||
MediaWikiApi mwApi;
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
|
||||
public static final int NOTIFICATION_CHECK_CATEGORY = 0x101;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private NotificationCompat.Builder notificationBuilder;
|
||||
private Context context;
|
||||
private Media media;
|
||||
|
||||
public CheckCategoryTask(Context context, Media media){
|
||||
this.context = context;
|
||||
this.media = media;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute(){
|
||||
ApplicationlessInjection
|
||||
.getInstance(context.getApplicationContext())
|
||||
.getCommonsApplicationComponent()
|
||||
.inject(this);
|
||||
|
||||
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationBuilder = new NotificationCompat.Builder(context);
|
||||
Toast toast = new Toast(context);
|
||||
toast.setGravity(Gravity.CENTER,0,0);
|
||||
toast = Toast.makeText(context, context.getString(R.string.check_category_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void ...voids) {
|
||||
publishProgress(0);
|
||||
|
||||
String editToken;
|
||||
String authCookie;
|
||||
String summary = context.getString(R.string.check_category_edit_summary);
|
||||
|
||||
authCookie = sessionManager.getAuthCookie();
|
||||
mwApi.setAuthCookie(authCookie);
|
||||
|
||||
try {
|
||||
editToken = mwApi.getEditToken();
|
||||
if (editToken.equals("+\\")) {
|
||||
return false;
|
||||
}
|
||||
publishProgress(1);
|
||||
|
||||
mwApi.appendEdit(editToken, "\n{{subst:chc}}\n", media.getFilename(), summary);
|
||||
publishProgress(2);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate (Integer... values){
|
||||
super.onProgressUpdate(values);
|
||||
|
||||
int[] messages = new int[]{R.string.getting_edit_token, R.string.check_category_adding_template};
|
||||
String message = "";
|
||||
if (0 < values[0] && values[0] < messages.length) {
|
||||
message = context.getString(messages[values[0]]);
|
||||
}
|
||||
|
||||
notificationBuilder.setContentTitle(context.getString(R.string.check_category_notification_title, media.getDisplayTitle()))
|
||||
.setStyle(new NotificationCompat.BigTextStyle()
|
||||
.bigText(message))
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setProgress(messages.length, values[0], false)
|
||||
.setOngoing(true);
|
||||
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
String message = "";
|
||||
String title = "";
|
||||
|
||||
if (result){
|
||||
title = context.getString(R.string.check_category_success_title);
|
||||
message = context.getString(R.string.check_category_success_message, media.getDisplayTitle());
|
||||
}
|
||||
else {
|
||||
title = context.getString(R.string.check_category_failure_title);
|
||||
message = context.getString(R.string.check_category_failure_message, media.getDisplayTitle());
|
||||
}
|
||||
|
||||
notificationBuilder.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||
.setContentTitle(title)
|
||||
.setStyle(new NotificationCompat.BigTextStyle()
|
||||
.bigText(message))
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setProgress(0,0,false)
|
||||
.setOngoing(false)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
|
||||
}
|
||||
}
|
||||
166
app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java
Normal file
166
app/src/main/java/fr/free/nrw/commons/review/ReviewActivity.java
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
import com.viewpagerindicator.CirclePageIndicator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.auth.AuthenticatedActivity;
|
||||
import fr.free.nrw.commons.mwapi.MediaResult;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class ReviewActivity extends AuthenticatedActivity {
|
||||
|
||||
@BindView(R.id.toolbar)
|
||||
Toolbar toolbar;
|
||||
@BindView(R.id.navigation_view)
|
||||
NavigationView navigationView;
|
||||
@BindView(R.id.drawer_layout)
|
||||
DrawerLayout drawerLayout;
|
||||
|
||||
@BindView(R.id.reviewPager)
|
||||
ReviewViewPager reviewPager;
|
||||
|
||||
@BindView(R.id.skip_image)
|
||||
Button skip_image_button;
|
||||
|
||||
@Inject MediaWikiApi mwApi;
|
||||
|
||||
public ReviewPagerAdapter reviewPagerAdapter;
|
||||
|
||||
public ReviewController reviewController;
|
||||
|
||||
@BindView(R.id.reviewPagerIndicator)
|
||||
public CirclePageIndicator pagerIndicator;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onAuthCookieAcquired(String authCookie) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAuthFailure() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_review);
|
||||
ButterKnife.bind(this);
|
||||
initDrawer();
|
||||
|
||||
reviewController = new ReviewController(this);
|
||||
|
||||
reviewPagerAdapter = new ReviewPagerAdapter(getSupportFragmentManager());
|
||||
reviewPager.setAdapter(reviewPagerAdapter);
|
||||
reviewPagerAdapter.getItem(0);
|
||||
pagerIndicator.setViewPager(reviewPager);
|
||||
|
||||
runRandomizer(); //Run randomizer whenever everything is ready so that a first random image will be added
|
||||
|
||||
skip_image_button.setOnClickListener(view -> runRandomizer());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean runRandomizer() {
|
||||
ProgressBar progressBar = reviewPagerAdapter.reviewImageFragments[reviewPager.getCurrentItem()].progressBar;
|
||||
if (progressBar != null) {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
reviewPager.setCurrentItem(0);
|
||||
Observable.fromCallable(() -> {
|
||||
String result = "";
|
||||
try {
|
||||
Media media = mwApi.getRecentRandomImage();
|
||||
if (media != null) {
|
||||
result = media.getFilename();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Timber.e("Error fetching recent random image: " + e.toString());
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::updateImage);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updateImage(String fileName) {
|
||||
if (fileName.length() == 0) {
|
||||
ViewUtil.showShortSnackbar(drawerLayout, R.string.error_review);
|
||||
return;
|
||||
}
|
||||
reviewController.onImageRefreshed(fileName); //file name is updated
|
||||
mwApi.firstRevisionOfFile("File:" + fileName)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(revision -> {
|
||||
reviewController.firstRevision = revision;
|
||||
reviewPagerAdapter.updateFileInformation(fileName, revision);
|
||||
});
|
||||
reviewPager.setCurrentItem(0);
|
||||
Observable.fromCallable(() -> {
|
||||
MediaResult media = mwApi.fetchMediaByFilename("File:" + fileName);
|
||||
return MediaDataExtractorUtil.extractCategories(media.getWikiSource());
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::updateCategories, this::categoryFetchError);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void categoryFetchError(Throwable throwable) {
|
||||
Timber.e(throwable, "Error fetching categories");
|
||||
ViewUtil.showShortSnackbar(drawerLayout, R.string.error_review_categories);
|
||||
}
|
||||
|
||||
private void updateCategories(ArrayList<String> categories) {
|
||||
reviewController.onCategoriesRefreshed(categories);
|
||||
reviewPagerAdapter.updateCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* References ReviewPagerAdapter to null before the activity is destroyed
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumers should be simply using this method to use this activity.
|
||||
* @param context
|
||||
* @param title Page title
|
||||
*/
|
||||
public static void startYourself(Context context, String title) {
|
||||
Intent reviewActivity = new Intent(context, ReviewActivity.class);
|
||||
context.startActivity(reviewActivity);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.delete.DeleteTask;
|
||||
import fr.free.nrw.commons.mwapi.Revision;
|
||||
|
||||
public class ReviewController {
|
||||
private String fileName;
|
||||
@Nullable
|
||||
public Revision firstRevision; // TODO: maybe we can expand this class to include fileName
|
||||
protected static ArrayList<String> categories;
|
||||
|
||||
private ReviewPagerAdapter reviewPagerAdapter;
|
||||
private ViewPager viewPager;
|
||||
private ReviewActivity reviewActivity;
|
||||
|
||||
ReviewController(Context context) {
|
||||
reviewActivity = (ReviewActivity)context;
|
||||
reviewPagerAdapter = reviewActivity.reviewPagerAdapter;
|
||||
viewPager = ((ReviewActivity)context).reviewPager;
|
||||
}
|
||||
|
||||
public void onImageRefreshed(String fileName) {
|
||||
this.fileName = fileName;
|
||||
ReviewController.categories = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void onCategoriesRefreshed(ArrayList<String> categories) {
|
||||
ReviewController.categories = categories;
|
||||
}
|
||||
|
||||
public void swipeToNext() {
|
||||
int nextPos = viewPager.getCurrentItem()+1;
|
||||
if (nextPos <= 3) {
|
||||
viewPager.setCurrentItem(nextPos);
|
||||
} else {
|
||||
reviewActivity.runRandomizer();
|
||||
}
|
||||
}
|
||||
|
||||
public void reportSpam() {
|
||||
DeleteTask.askReasonAndExecute(new Media("File:"+fileName),
|
||||
reviewActivity,
|
||||
reviewActivity.getResources().getString(R.string.review_spam_report_question),
|
||||
reviewActivity.getResources().getString(R.string.review_spam_report_problem));
|
||||
}
|
||||
|
||||
public void reportPossibleCopyRightViolation() {
|
||||
DeleteTask.askReasonAndExecute(new Media("File:"+fileName),
|
||||
reviewActivity,
|
||||
reviewActivity.getResources().getString(R.string.review_c_violation_report_question),
|
||||
reviewActivity.getResources().getString(R.string.review_c_violation_report_problem));
|
||||
}
|
||||
|
||||
public void reportWrongCategory() {
|
||||
new CheckCategoryTask(reviewActivity, new Media("File:"+fileName)).execute();
|
||||
swipeToNext();
|
||||
}
|
||||
|
||||
public void sendThanks() {
|
||||
new SendThankTask(reviewActivity, new Media("File:"+fileName), firstRevision).execute();
|
||||
swipeToNext();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.mwapi.Revision;
|
||||
|
||||
public class ReviewImageFragment extends CommonsDaggerSupportFragment {
|
||||
|
||||
public static final int SPAM = 0;
|
||||
public static final int COPYRIGHT = 1;
|
||||
public static final int CATEGORY = 2;
|
||||
public static final int THANKS = 3;
|
||||
|
||||
private int position;
|
||||
private String fileName;
|
||||
private String catString;
|
||||
|
||||
private View textViewQuestionContext;
|
||||
private View imageCaption;
|
||||
private View textViewQuestion;
|
||||
private SimpleDraweeView simpleDraweeView;
|
||||
|
||||
private Button yesButton;
|
||||
private Button noButton;
|
||||
|
||||
public ProgressBar progressBar;
|
||||
private Revision revision;
|
||||
|
||||
|
||||
public void update(int position, String fileName, Revision revision) {
|
||||
this.position = position;
|
||||
this.fileName = fileName;
|
||||
this.revision = revision;
|
||||
|
||||
fillImageCaption();
|
||||
|
||||
if (simpleDraweeView != null) {
|
||||
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCategories(Iterable<String> categories) {
|
||||
if (categories != null && isAdded()) {
|
||||
catString = TextUtils.join(", ", categories);
|
||||
if (catString != null && !catString.equals("") && textViewQuestionContext != null) {
|
||||
catString = "<b>" + catString + "</b>";
|
||||
String stringToConvertHtml = String.format(getResources().getString(R.string.review_category_explanation), catString);
|
||||
((TextView) textViewQuestionContext).setText(Html.fromHtml(stringToConvertHtml));
|
||||
} else if (textViewQuestionContext != null) {
|
||||
((TextView) textViewQuestionContext).setText(getResources().getString(R.string.review_no_category));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
position = getArguments().getInt("position");
|
||||
View layoutView = inflater.inflate(R.layout.fragment_review_image, container,
|
||||
false);
|
||||
progressBar = layoutView.findViewById(R.id.progressBar);
|
||||
textViewQuestion = layoutView.findViewById(R.id.reviewQuestion);
|
||||
textViewQuestionContext = layoutView.findViewById(R.id.reviewQuestionContext);
|
||||
imageCaption = layoutView.findViewById(R.id.imageCaption);
|
||||
yesButton = layoutView.findViewById(R.id.yesButton);
|
||||
noButton = layoutView.findViewById(R.id.noButton);
|
||||
|
||||
fillImageCaption();
|
||||
|
||||
String question, explanation, yesButtonText, noButtonText;
|
||||
switch (position) {
|
||||
case COPYRIGHT:
|
||||
question = getString(R.string.review_copyright);
|
||||
explanation = getString(R.string.review_copyright_explanation);
|
||||
yesButtonText = getString(R.string.review_copyright_yes_button_text);
|
||||
noButtonText = getString(R.string.review_copyright_no_button_text);
|
||||
yesButton.setOnClickListener(view -> {
|
||||
((ReviewActivity) getActivity()).reviewController.reportPossibleCopyRightViolation();
|
||||
});
|
||||
break;
|
||||
case CATEGORY:
|
||||
question = getString(R.string.review_category);
|
||||
explanation = getString(R.string.review_no_category);
|
||||
yesButtonText = getString(R.string.review_category_yes_button_text);
|
||||
noButtonText = getString(R.string.review_category_no_button_text);
|
||||
yesButton.setOnClickListener(view -> {
|
||||
((ReviewActivity) getActivity()).reviewController.reportWrongCategory();
|
||||
});
|
||||
break;
|
||||
case SPAM:
|
||||
question = getString(R.string.review_spam);
|
||||
explanation = getString(R.string.review_spam_explanation);
|
||||
yesButtonText = getString(R.string.review_spam_yes_button_text);
|
||||
noButtonText = getString(R.string.review_spam_no_button_text);
|
||||
yesButton.setOnClickListener(view -> {
|
||||
((ReviewActivity) getActivity()).reviewController.reportSpam();
|
||||
});
|
||||
break;
|
||||
case THANKS:
|
||||
question = getString(R.string.review_thanks);
|
||||
explanation = getString(R.string.review_thanks_explanation, ((ReviewActivity) getActivity()).reviewController.firstRevision.username);
|
||||
yesButtonText = getString(R.string.review_thanks_yes_button_text);
|
||||
noButtonText = getString(R.string.review_thanks_no_button_text);
|
||||
yesButton.setTextColor(Color.parseColor("#228b22"));
|
||||
noButton.setTextColor(Color.parseColor("#116aaa"));
|
||||
yesButton.setOnClickListener(view -> {
|
||||
((ReviewActivity) getActivity()).reviewController.sendThanks();
|
||||
});
|
||||
break;
|
||||
default :
|
||||
question = "How did we get here?";
|
||||
explanation = "No idea.";
|
||||
yesButtonText = "yes";
|
||||
noButtonText = "no";
|
||||
}
|
||||
|
||||
noButton.setOnClickListener(view -> {
|
||||
((ReviewActivity) getActivity()).reviewController.swipeToNext();
|
||||
});
|
||||
|
||||
((TextView) textViewQuestion).setText(question);
|
||||
((TextView) textViewQuestionContext).setText(explanation);
|
||||
yesButton.setText(yesButtonText);
|
||||
noButton.setText(noButtonText);
|
||||
|
||||
if(position==CATEGORY){
|
||||
updateCategories(ReviewController.categories);
|
||||
}
|
||||
|
||||
simpleDraweeView = layoutView.findViewById(R.id.imageView);
|
||||
|
||||
if (fileName != null) {
|
||||
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
return layoutView;
|
||||
}
|
||||
|
||||
private void fillImageCaption() {
|
||||
if (imageCaption != null && fileName != null && revision != null) {
|
||||
((TextView) imageCaption).setText(fileName + " is uploaded by: " + revision.username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter;
|
||||
import fr.free.nrw.commons.mwapi.Revision;
|
||||
|
||||
public class ReviewPagerAdapter extends FragmentStatePagerAdapter {
|
||||
ReviewImageFragment[] reviewImageFragments;
|
||||
|
||||
|
||||
public ReviewPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
reviewImageFragments = new ReviewImageFragment[] {
|
||||
new ReviewImageFragment(),
|
||||
new ReviewImageFragment(),
|
||||
new ReviewImageFragment(),
|
||||
new ReviewImageFragment()
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return reviewImageFragments.length;
|
||||
}
|
||||
|
||||
public void updateFileInformation(String fileName, Revision revision) {
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
ReviewImageFragment fragment = reviewImageFragments[i];
|
||||
fragment.update(i, fileName, revision);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCategories() {
|
||||
ReviewImageFragment categoryFragment = reviewImageFragments[ReviewImageFragment.CATEGORY];
|
||||
categoryFragment.updateCategories(ReviewController.categories);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("position", position);
|
||||
reviewImageFragments[position].setArguments(bundle);
|
||||
return reviewImageFragments[position];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
public class ReviewViewPager extends ViewPager {
|
||||
|
||||
public ReviewViewPager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ReviewViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
// Never allow swiping to switch between pages
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
// Never allow swiping to switch between pages
|
||||
return false;
|
||||
}
|
||||
}
|
||||
138
app/src/main/java/fr/free/nrw/commons/review/SendThankTask.java
Normal file
138
app/src/main/java/fr/free/nrw/commons/review/SendThankTask.java
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.auth.SessionManager;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import fr.free.nrw.commons.mwapi.Revision;
|
||||
import timber.log.Timber;
|
||||
|
||||
// example code:
|
||||
//
|
||||
// media = new Media("File:Iru.png");
|
||||
// Observable.fromCallable(() -> mwApi.firstRevisionOfFile(media.getFilename()))
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(revision -> {
|
||||
// SendThankTask task = new SendThankTask(getActivity(), media, revision);
|
||||
// task.execute();
|
||||
// });
|
||||
|
||||
public class SendThankTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Inject
|
||||
MediaWikiApi mwApi;
|
||||
@Inject
|
||||
SessionManager sessionManager;
|
||||
|
||||
public static final int NOTIFICATION_SEND_THANK = 0x102;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private NotificationCompat.Builder notificationBuilder;
|
||||
private Context context;
|
||||
private Media media;
|
||||
private Revision revision;
|
||||
|
||||
public SendThankTask(Context context, Media media, Revision revision){
|
||||
this.context = context;
|
||||
this.media = media;
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute(){
|
||||
ApplicationlessInjection
|
||||
.getInstance(context.getApplicationContext())
|
||||
.getCommonsApplicationComponent()
|
||||
.inject(this);
|
||||
|
||||
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationBuilder = new NotificationCompat.Builder(context);
|
||||
Toast toast = new Toast(context);
|
||||
toast.setGravity(Gravity.CENTER,0,0);
|
||||
toast = Toast.makeText(context, context.getString(R.string.send_thank_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Void ...voids) {
|
||||
publishProgress(0);
|
||||
|
||||
String editToken;
|
||||
String authCookie;
|
||||
|
||||
authCookie = sessionManager.getAuthCookie();
|
||||
mwApi.setAuthCookie(authCookie);
|
||||
|
||||
try {
|
||||
editToken = mwApi.getEditToken();
|
||||
if (editToken.equals("+\\")) {
|
||||
return false;
|
||||
}
|
||||
publishProgress(1);
|
||||
|
||||
mwApi.thank(editToken, revision.revisionId);
|
||||
|
||||
publishProgress(2);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate (Integer... values){
|
||||
super.onProgressUpdate(values);
|
||||
|
||||
int[] messages = new int[]{R.string.getting_edit_token, R.string.send_thank_send};
|
||||
String message = "";
|
||||
if (0 < values[0] && values[0] < messages.length) {
|
||||
message = context.getString(messages[values[0]]);
|
||||
}
|
||||
|
||||
notificationBuilder.setContentTitle(context.getString(R.string.send_thank_notification_title))
|
||||
.setStyle(new NotificationCompat.BigTextStyle()
|
||||
.bigText(message))
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setProgress(messages.length, values[0], false)
|
||||
.setOngoing(true);
|
||||
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
String message = "";
|
||||
String title = "";
|
||||
|
||||
if (result){
|
||||
title = context.getString(R.string.send_thank_success_title);
|
||||
message = context.getString(R.string.send_thank_success_message, media.getDisplayTitle());
|
||||
}
|
||||
else {
|
||||
title = context.getString(R.string.send_thank_failure_title);
|
||||
message = context.getString(R.string.send_thank_failure_message, media.getDisplayTitle());
|
||||
}
|
||||
|
||||
notificationBuilder.setDefaults(NotificationCompat.DEFAULT_ALL)
|
||||
.setContentTitle(title)
|
||||
.setStyle(new NotificationCompat.BigTextStyle()
|
||||
.bigText(message))
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setProgress(0,0,false)
|
||||
.setOngoing(false)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue