Merge branch 'master' into categorization-recycler-view

This commit is contained in:
Paul Hawke 2017-07-25 21:19:21 -05:00
commit bf59afcc3b
31 changed files with 220 additions and 371 deletions

View file

@ -1,4 +1,5 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'jacoco-android' apply plugin: 'jacoco-android'
apply from: 'quality.gradle' apply from: 'quality.gradle'
apply plugin: 'com.getkeepsafe.dexcount' apply plugin: 'com.getkeepsafe.dexcount'
@ -75,6 +76,11 @@ android {
abortOnError false abortOnError false
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
//FIXME: Temporary fix for https://github.com/commons-app/apps-android-commons/issues/709 //FIXME: Temporary fix for https://github.com/commons-app/apps-android-commons/issues/709
configurations.all { configurations.all {
resolutionStrategy.force 'com.android.support:support-annotations:25.2.0' resolutionStrategy.force 'com.android.support:support-annotations:25.2.0'

View file

@ -197,8 +197,8 @@ public class CommonsApplication extends Application {
AccountManager accountManager = AccountManager.get(this); AccountManager accountManager = AccountManager.get(this);
Account[] allAccounts = accountManager.getAccountsByType(AccountUtil.accountType()); Account[] allAccounts = accountManager.getAccountsByType(AccountUtil.accountType());
for (int index = 0; index < allAccounts.length; index++) { for (Account allAccount : allAccounts) {
accountManager.removeAccount(allAccounts[index], null, null); accountManager.removeAccount(allAccount, null, null);
} }
//TODO: fix preference manager //TODO: fix preference manager

View file

@ -27,12 +27,7 @@ public class WelcomeActivity extends BaseActivity {
pager.setAdapter(adapter); pager.setAdapter(adapter);
indicator.setViewPager(pager); indicator.setViewPager(pager);
adapter.setCallback(new WelcomePagerAdapter.Callback() { adapter.setCallback(this::finish);
@Override
public void onYesClicked() {
finish();
}
});
} }
@Override @Override

View file

@ -26,6 +26,9 @@ import fr.free.nrw.commons.PageTitle;
import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.contributions.ContributionsActivity;
import timber.log.Timber; import timber.log.Timber;
import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
public class LoginActivity extends AccountAuthenticatorActivity { public class LoginActivity extends AccountAuthenticatorActivity {
@ -63,18 +66,8 @@ public class LoginActivity extends AccountAuthenticatorActivity {
twoFactorEdit.addTextChangedListener(textWatcher); twoFactorEdit.addTextChangedListener(textWatcher);
passwordEdit.setOnEditorActionListener(newLoginInputActionListener()); passwordEdit.setOnEditorActionListener(newLoginInputActionListener());
loginButton.setOnClickListener(new View.OnClickListener() { loginButton.setOnClickListener(this::performLogin);
@Override signupButton.setOnClickListener(this::signUp);
public void onClick(View v) {
performLogin();
}
});
signupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signUp(v);
}
});
} }
private class LoginTextWatcher implements TextWatcher { private class LoginTextWatcher implements TextWatcher {
@ -98,20 +91,17 @@ public class LoginActivity extends AccountAuthenticatorActivity {
} }
private TextView.OnEditorActionListener newLoginInputActionListener() { private TextView.OnEditorActionListener newLoginInputActionListener() {
return new TextView.OnEditorActionListener() { return (textView, actionId, keyEvent) -> {
@Override if (loginButton.isEnabled()) {
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) { if (actionId == IME_ACTION_DONE) {
if (loginButton.isEnabled()) { performLogin(textView);
if (actionId == EditorInfo.IME_ACTION_DONE) { return true;
performLogin(); } else if ((keyEvent != null) && keyEvent.getKeyCode() == KEYCODE_ENTER) {
return true; performLogin(textView);
} else if ((keyEvent != null) && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER) { return true;
performLogin();
return true;
}
} }
return false;
} }
return false;
}; };
} }
@ -142,7 +132,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
super.onDestroy(); super.onDestroy();
} }
private void performLogin() { private void performLogin(View view) {
Timber.d("Login to start!"); Timber.d("Login to start!");
LoginTask task = getLoginTask(); LoginTask task = getLoginTask();
task.execute(); task.execute();

View file

@ -86,12 +86,9 @@ public class CategorizationFragment extends Fragment implements CategoryClickedL
categoriesList.setLayoutManager(new LinearLayoutManager(getContext())); categoriesList.setLayoutManager(new LinearLayoutManager(getContext()));
categoriesSkip.setOnClickListener(new View.OnClickListener() { categoriesSkip.setOnClickListener(view -> {
@Override getActivity().onBackPressed();
public void onClick(View view) { getActivity().finish();
getActivity().onBackPressed();
getActivity().finish();
}
}); });
ArrayList<CategoryItem> items; ArrayList<CategoryItem> items;
@ -127,15 +124,12 @@ public class CategorizationFragment extends Fragment implements CategoryClickedL
if (rootView != null) { if (rootView != null) {
rootView.setFocusableInTouchMode(true); rootView.setFocusableInTouchMode(true);
rootView.requestFocus(); rootView.requestFocus();
rootView.setOnKeyListener(new View.OnKeyListener() { rootView.setOnKeyListener((v, keyCode, event) -> {
@Override if (event.getAction() == ACTION_UP && keyCode == KEYCODE_BACK) {
public boolean onKey(View v, int keyCode, KeyEvent event) { backButtonDialog();
if (event.getAction() == ACTION_UP && keyCode == KEYCODE_BACK) { return true;
backButtonDialog();
return true;
}
return false;
} }
return false;
}); });
} }
} }
@ -188,18 +182,12 @@ public class CategorizationFragment extends Fragment implements CategoryClickedL
+ "Are you sure you want to submit without selecting " + "Are you sure you want to submit without selecting "
+ "categories?") + "categories?")
.setTitle("No Categories Selected") .setTitle("No Categories Selected")
.setPositiveButton("No, go back", new DialogInterface.OnClickListener() { .setPositiveButton("No, go back", (dialog, id) -> {
@Override //Exit menuItem so user can select their categories
public void onClick(DialogInterface dialog, int id) {
//Exit menuItem so user can select their categories
}
}) })
.setNegativeButton("Yes, submit", new DialogInterface.OnClickListener() { .setNegativeButton("Yes, submit", (dialog, id) -> {
@Override //Proceed to submission
public void onClick(DialogInterface dialog, int id) { onCategoriesSaveHandler.onCategoriesSave(selectedCategories);
//Proceed to submission
onCategoriesSaveHandler.onCategoriesSave(selectedCategories);
}
}) })
.create() .create()
.show(); .show();
@ -465,18 +453,10 @@ public class CategorizationFragment extends Fragment implements CategoryClickedL
.setMessage("Are you sure you want to go back? The image will not " .setMessage("Are you sure you want to go back? The image will not "
+ "have any categories saved.") + "have any categories saved.")
.setTitle("Warning") .setTitle("Warning")
.setPositiveButton("No", new DialogInterface.OnClickListener() { .setPositiveButton("No", (dialog, id) -> {
@Override //No need to do anything, user remains on categorization screen
public void onClick(DialogInterface dialog, int id) {
//No need to do anything, user remains on categorization screen
}
})
.setNegativeButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
getActivity().finish();
}
}) })
.setNegativeButton("Yes", (dialog, id) -> getActivity().finish())
.create() .create()
.show(); .show();
} }

View file

@ -9,11 +9,8 @@ public class BackgroundPoolExceptionHandler implements ExceptionHandler {
public void onException(@NonNull final Throwable t) { public void onException(@NonNull final Throwable t) {
//Crash for debug build //Crash for debug build
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Thread thread = new Thread(new Runnable() { Thread thread = new Thread(() -> {
@Override throw new RuntimeException(t);
public void run() {
throw new RuntimeException(t);
}
}); });
thread.start(); thread.start();
} }

View file

@ -11,17 +11,13 @@ class ThreadFactoryMaker {
private int count = 0; private int count = 0;
@Override @Override
public Thread newThread(final Runnable runnable) { public Thread newThread(@NonNull final Runnable runnable) {
count++; count++;
Runnable wrapperRunnable = new Runnable() { Runnable wrapperRunnable = () -> {
@Override Process.setThreadPriority(priority);
public void run() { runnable.run();
Process.setThreadPriority(priority);
runnable.run();
}
}; };
Thread t = new Thread(wrapperRunnable, String.format("%s-%s", name, count)); return new Thread(wrapperRunnable, String.format("%s-%s", name, count));
return t;
} }
}; };
} }

View file

@ -29,6 +29,7 @@ import fr.free.nrw.commons.R;
import fr.free.nrw.commons.nearby.NearbyActivity; import fr.free.nrw.commons.nearby.NearbyActivity;
import timber.log.Timber; import timber.log.Timber;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
public class ContributionsListFragment extends Fragment { public class ContributionsListFragment extends Fragment {
@ -110,11 +111,11 @@ public class ContributionsListFragment extends Fragment {
// Here, thisActivity is the current activity // Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(getActivity(), if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.READ_EXTERNAL_STORAGE) READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation? // Should we show an explanation?
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) { if (shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
// Show an explanation to the user *asynchronously* -- don't block // Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user // this thread waiting for the user's response! After the user
@ -122,15 +123,9 @@ public class ContributionsListFragment extends Fragment {
new AlertDialog.Builder(getActivity()) new AlertDialog.Builder(getActivity())
.setMessage(getString(R.string.storage_permission_rationale)) .setMessage(getString(R.string.storage_permission_rationale))
.setPositiveButton("OK", new DialogInterface.OnClickListener() { .setPositiveButton("OK", (dialog, which) -> {
@Override requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, 1);
public void onClick(DialogInterface dialog, int which) { dialog.dismiss();
requestPermissions(
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
1);
dialog.dismiss();
}
}) })
.setNegativeButton("Cancel", null) .setNegativeButton("Cancel", null)
.create() .create()
@ -140,7 +135,7 @@ public class ContributionsListFragment extends Fragment {
// No explanation needed, we can request the permission. // No explanation needed, we can request the permission.
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, requestPermissions(new String[]{READ_EXTERNAL_STORAGE},
1); 1);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an

View file

@ -14,10 +14,10 @@ import fr.free.nrw.commons.concurrency.BackgroundPoolExceptionHandler;
import fr.free.nrw.commons.concurrency.ThreadPoolExecutorService; import fr.free.nrw.commons.concurrency.ThreadPoolExecutorService;
import timber.log.Timber; import timber.log.Timber;
public class UploadCountClient { class UploadCountClient {
private ThreadPoolExecutorService threadPoolExecutor; private ThreadPoolExecutorService threadPoolExecutor;
public UploadCountClient() { UploadCountClient() {
threadPoolExecutor = new ThreadPoolExecutorService.Builder("bg-pool") threadPoolExecutor = new ThreadPoolExecutorService.Builder("bg-pool")
.setPoolSize(Runtime.getRuntime().availableProcessors()) .setPoolSize(Runtime.getRuntime().availableProcessors())
.setExceptionHandler(new BackgroundPoolExceptionHandler()) .setExceptionHandler(new BackgroundPoolExceptionHandler())
@ -27,29 +27,26 @@ public class UploadCountClient {
private static final String UPLOAD_COUNT_URL_TEMPLATE = private static final String UPLOAD_COUNT_URL_TEMPLATE =
"https://tools.wmflabs.org/urbanecmbot/uploadsbyuser/uploadsbyuser.py?user=%s"; "https://tools.wmflabs.org/urbanecmbot/uploadsbyuser/uploadsbyuser.py?user=%s";
public ListenableFuture<Integer> getUploadCount(final String userName) { ListenableFuture<Integer> getUploadCount(final String userName) {
final SettableFuture<Integer> future = SettableFuture.create(); final SettableFuture<Integer> future = SettableFuture.create();
threadPoolExecutor.schedule(new Runnable() { threadPoolExecutor.schedule(() -> {
@Override URL url;
public void run() { try {
URL url; url = new URL(String.format(Locale.ENGLISH, UPLOAD_COUNT_URL_TEMPLATE,
new PageTitle(userName).getText()));
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try { try {
url = new URL(String.format(Locale.ENGLISH, UPLOAD_COUNT_URL_TEMPLATE, BufferedReader bufferedReader = new BufferedReader(new
new PageTitle(userName).getText())); InputStreamReader(urlConnection.getInputStream()));
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); String uploadCount = bufferedReader.readLine();
try { bufferedReader.close();
BufferedReader bufferedReader = new BufferedReader(new future.set(Integer.parseInt(uploadCount));
InputStreamReader(urlConnection.getInputStream())); } finally {
String uploadCount = bufferedReader.readLine(); urlConnection.disconnect();
bufferedReader.close();
future.set(Integer.parseInt(uploadCount));
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
Timber.e("Error getting upload count Error", e);
future.setException(e);
} }
} catch (Exception e) {
Timber.e("Error getting upload count Error", e);
future.setException(e);
} }
}); });
return future; return future;

View file

@ -119,12 +119,7 @@ public class MediaDetailFragment extends Fragment {
licenseList = new LicenseList(getActivity()); licenseList = new LicenseList(getActivity());
// Progressively darken the image in the background when we scroll detail pane up // Progressively darken the image in the background when we scroll detail pane up
scrollListener = new ViewTreeObserver.OnScrollChangedListener() { scrollListener = this::updateTheDarkness;
@Override
public void onScrollChanged() {
updateTheDarkness();
}
};
view.getViewTreeObserver().addOnScrollChangedListener(scrollListener); view.getViewTreeObserver().addOnScrollChangedListener(scrollListener);
// Layout layoutListener to size the spacer item relative to the available space. // Layout layoutListener to size the spacer item relative to the available space.
@ -280,15 +275,12 @@ public class MediaDetailFragment extends Fragment {
textView.setText(catName); textView.setText(catName);
if (categoriesLoaded && categoriesPresent) { if (categoriesLoaded && categoriesPresent) {
textView.setOnClickListener(new View.OnClickListener() { textView.setOnClickListener(view -> {
@Override String selectedCategoryTitle = "Category:" + catName;
public void onClick(View view) { Intent viewIntent = new Intent();
String selectedCategoryTitle = "Category:" + catName; viewIntent.setAction(Intent.ACTION_VIEW);
Intent viewIntent = new Intent(); viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
viewIntent.setAction(Intent.ACTION_VIEW); startActivity(viewIntent);
viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
startActivity(viewIntent);
}
}); });
} }
return item; return item;

View file

@ -72,12 +72,7 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa
public Fragment getItem(int i) { public Fragment getItem(int i) {
if (i == 0) { if (i == 0) {
// See bug https://code.google.com/p/android/issues/detail?id=27526 // See bug https://code.google.com/p/android/issues/detail?id=27526
pager.postDelayed(new Runnable() { pager.postDelayed(() -> getActivity().supportInvalidateOptionsMenu(), 5);
@Override
public void run() {
getActivity().supportInvalidateOptionsMenu();
}
}, 5);
} }
return MediaDetailFragment.forMedia(i, editable); return MediaDetailFragment.forMedia(i, editable);
} }
@ -100,14 +95,11 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa
final int pageNumber = savedInstanceState.getInt("current-page"); final int pageNumber = savedInstanceState.getInt("current-page");
// Adapter doesn't seem to be loading immediately. // Adapter doesn't seem to be loading immediately.
// Dear God, please forgive us for our sins // Dear God, please forgive us for our sins
view.postDelayed(new Runnable() { view.postDelayed(() -> {
@Override pager.setAdapter(adapter);
public void run() { pager.setCurrentItem(pageNumber, false);
pager.setAdapter(adapter); getActivity().supportInvalidateOptionsMenu();
pager.setCurrentItem(pageNumber, false); adapter.notifyDataSetChanged();
getActivity().supportInvalidateOptionsMenu();
adapter.notifyDataSetChanged();
}
}, 100); }, 100);
} else { } else {
pager.setAdapter(adapter); pager.setAdapter(adapter);
@ -196,13 +188,8 @@ public class MediaDetailPagerFragment extends Fragment implements ViewPager.OnPa
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
Snackbar.make(getView(), R.string.storage_permission_rationale, Snackbar.make(getView(), R.string.storage_permission_rationale,
Snackbar.LENGTH_INDEFINITE) Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, new View.OnClickListener() { .setAction(R.string.ok, view -> ActivityCompat.requestPermissions(getActivity(),
@Override new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1)).show();
public void onClick(View view) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
}).show();
} else { } else {
final DownloadManager manager = (DownloadManager)getActivity().getSystemService(Context.DOWNLOAD_SERVICE); final DownloadManager manager = (DownloadManager)getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(req); manager.enqueue(req);

View file

@ -351,12 +351,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
@Override @Override
@NonNull @NonNull
public UploadResult uploadFile(String filename, InputStream file, long dataLength, String pageContents, String editSummary, final ProgressListener progressListener) throws IOException { public UploadResult uploadFile(String filename, InputStream file, long dataLength, String pageContents, String editSummary, final ProgressListener progressListener) throws IOException {
ApiResult result = api.upload(filename, file, dataLength, pageContents, editSummary, new in.yuvi.http.fluent.ProgressListener() { ApiResult result = api.upload(filename, file, dataLength, pageContents, editSummary, progressListener::onProgress);
@Override
public void onProgress(long transferred, long total) {
progressListener.onProgress(transferred, total);
}
});
Log.e("WTF", "Result: "+result.toString()); Log.e("WTF", "Result: "+result.toString());

View file

@ -2,7 +2,6 @@ package fr.free.nrw.commons.nearby;
import android.Manifest; import android.Manifest;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.location.LocationManager; import android.location.LocationManager;
@ -41,7 +40,8 @@ import timber.log.Timber;
public class NearbyActivity extends NavigationBaseActivity { public class NearbyActivity extends NavigationBaseActivity {
@BindView(R.id.progressBar) ProgressBar progressBar; @BindView(R.id.progressBar)
ProgressBar progressBar;
private boolean isMapViewActive = false; private boolean isMapViewActive = false;
private static final int LOCATION_REQUEST = 1; private static final int LOCATION_REQUEST = 1;
@ -115,15 +115,11 @@ public class NearbyActivity extends NavigationBaseActivity {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setMessage(getString(R.string.location_permission_rationale)) .setMessage(getString(R.string.location_permission_rationale))
.setPositiveButton("OK", new DialogInterface.OnClickListener() { .setPositiveButton("OK", (dialog, which) -> {
@Override ActivityCompat.requestPermissions(NearbyActivity.this,
public void onClick(DialogInterface dialog, int which) { new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_REQUEST);
ActivityCompat.requestPermissions(NearbyActivity.this, dialog.dismiss();
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_REQUEST);
dialog.dismiss();
}
}) })
.setNegativeButton("Cancel", null) .setNegativeButton("Cancel", null)
.create() .create()
@ -175,26 +171,19 @@ public class NearbyActivity extends NavigationBaseActivity {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE); LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Timber.d("GPS is not enabled"); Timber.d("GPS is not enabled");
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); new AlertDialog.Builder(this)
alertDialogBuilder.setMessage(R.string.gps_disabled) .setMessage(R.string.gps_disabled)
.setCancelable(false) .setCancelable(false)
.setPositiveButton(R.string.enable_gps, .setPositiveButton(R.string.enable_gps,
new DialogInterface.OnClickListener() { (dialog, id) -> {
public void onClick(DialogInterface dialog, int id) { Intent callGPSSettingIntent = new Intent(
Intent callGPSSettingIntent = new Intent( android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); Timber.d("Loaded settings page");
Timber.d("Loaded settings page"); startActivityForResult(callGPSSettingIntent, 1);
startActivityForResult(callGPSSettingIntent, 1); })
} .setNegativeButton(R.string.menu_cancel_upload, (dialog, id) -> dialog.cancel())
}); .create()
alertDialogBuilder.setNegativeButton(R.string.menu_cancel_upload, .show();
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
} else { } else {
Timber.d("GPS is enabled"); Timber.d("GPS is enabled");
} }
@ -257,7 +246,7 @@ public class NearbyActivity extends NavigationBaseActivity {
private final Context mContext; private final Context mContext;
private NearbyAsyncTask (Context context) { private NearbyAsyncTask(Context context) {
mContext = context; mContext = context;
} }

View file

@ -1,5 +1,7 @@
package fr.free.nrw.commons.nearby; package fr.free.nrw.commons.nearby;
import android.support.annotation.NonNull;
import com.pedrogomez.renderers.ListAdapteeCollection; import com.pedrogomez.renderers.ListAdapteeCollection;
import com.pedrogomez.renderers.RVRendererAdapter; import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererBuilder; import com.pedrogomez.renderers.RendererBuilder;
@ -10,7 +12,7 @@ import java.util.List;
class NearbyAdapterFactory { class NearbyAdapterFactory {
private PlaceRenderer.PlaceClickedListener listener; private PlaceRenderer.PlaceClickedListener listener;
NearbyAdapterFactory(PlaceRenderer.PlaceClickedListener listener) { NearbyAdapterFactory(@NonNull PlaceRenderer.PlaceClickedListener listener) {
this.listener = listener; this.listener = listener;
} }

View file

@ -52,13 +52,10 @@ public class NearbyController {
distances.put(place, computeDistanceBetween(place.location, curLatLng)); distances.put(place, computeDistanceBetween(place.location, curLatLng));
} }
Collections.sort(places, Collections.sort(places,
new Comparator<Place>() { (lhs, rhs) -> {
@Override double lhsDistance = distances.get(lhs);
public int compare(Place lhs, Place rhs) { double rhsDistance = distances.get(rhs);
double lhsDistance = distances.get(lhs); return (int) (lhsDistance - rhsDistance);
double rhsDistance = distances.get(rhs);
return (int) (lhsDistance - rhsDistance);
}
} }
); );
} }

View file

@ -63,15 +63,10 @@ public class NearbyInfoDialog extends OverlayDialog {
overflowButton.setVisibility(showMenu() ? View.VISIBLE : View.GONE); overflowButton.setVisibility(showMenu() ? View.VISIBLE : View.GONE);
overflowButton.setOnClickListener(new View.OnClickListener() { overflowButton.setOnClickListener(this::popupMenuListener);
@Override
public void onClick(View v) {
popupMenuListener();
}
});
} }
private void popupMenuListener() { private void popupMenuListener(View v) {
PopupMenu popupMenu = new PopupMenu(getActivity(), overflowButton); PopupMenu popupMenu = new PopupMenu(getActivity(), overflowButton);
popupMenu.inflate(R.menu.nearby_info_dialog_options); popupMenu.inflate(R.menu.nearby_info_dialog_options);

View file

@ -48,12 +48,7 @@ public class NearbyListFragment extends Fragment {
View view = inflater.inflate(R.layout.fragment_nearby, container, false); View view = inflater.inflate(R.layout.fragment_nearby, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.listView); recyclerView = (RecyclerView) view.findViewById(R.id.listView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapterFactory = new NearbyAdapterFactory(new PlaceRenderer.PlaceClickedListener() { adapterFactory = new NearbyAdapterFactory(place -> NearbyInfoDialog.showYourself(getActivity(), place));
@Override
public void placeClicked(Place place) {
NearbyInfoDialog.showYourself(getActivity(), place);
}
});
return view; return view;
} }

View file

@ -88,25 +88,19 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
// create map // create map
mapView = new MapView(getActivity(), options); mapView = new MapView(getActivity(), options);
mapView.onCreate(savedInstanceState); mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() { mapView.getMapAsync(mapboxMap -> {
@Override mapboxMap.addMarkers(baseMarkerOptions);
public void onMapReady(MapboxMap mapboxMap) {
mapboxMap.addMarkers(baseMarkerOptions);
mapboxMap.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() { mapboxMap.setOnMarkerClickListener(marker -> {
@Override if (marker instanceof NearbyMarker) {
public boolean onMarkerClick(@NonNull Marker marker) { NearbyMarker nearbyMarker = (NearbyMarker) marker;
if (marker instanceof NearbyMarker) { Place place = nearbyMarker.getNearbyBaseMarker().getPlace();
NearbyMarker nearbyMarker = (NearbyMarker) marker; NearbyInfoDialog.showYourself(getActivity(), place);
Place place = nearbyMarker.getNearbyBaseMarker().getPlace(); }
NearbyInfoDialog.showYourself(getActivity(), place); return false;
} });
return false;
}
});
addCurrentLocationMarker(mapboxMap); addCurrentLocationMarker(mapboxMap);
}
}); });
if (PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("theme",true)) { if (PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("theme",true)) {
mapView.setStyleUrl(getResources().getString(R.string.map_theme_dark)); mapView.setStyleUrl(getResources().getString(R.string.map_theme_dark));

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.nearby; package fr.free.nrw.commons.nearby;
import android.support.annotation.NonNull;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -19,7 +20,7 @@ class PlaceRenderer extends Renderer<Place> {
@BindView(R.id.icon) ImageView icon; @BindView(R.id.icon) ImageView icon;
private final PlaceClickedListener listener; private final PlaceClickedListener listener;
PlaceRenderer(PlaceClickedListener listener) { PlaceRenderer(@NonNull PlaceClickedListener listener) {
this.listener = listener; this.listener = listener;
} }
@ -35,14 +36,7 @@ class PlaceRenderer extends Renderer<Place> {
@Override @Override
protected void hookListeners(View view) { protected void hookListeners(View view) {
view.setOnClickListener(new View.OnClickListener() { view.setOnClickListener(v -> listener.placeClicked(getContent()));
@Override
public void onClick(View v) {
if (listener != null) {
listener.placeClicked(getContent());
}
}
});
} }
@Override @Override

View file

@ -28,21 +28,15 @@ public class SettingsFragment extends PreferenceFragment {
licensePreference.setSummary(getString(Utils.licenseNameFor(licensePreference.getValue()))); licensePreference.setSummary(getString(Utils.licenseNameFor(licensePreference.getValue())));
// Keep summary updated when changing value // Keep summary updated when changing value
licensePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { licensePreference.setOnPreferenceChangeListener((preference, newValue) -> {
@Override preference.setSummary(getString(Utils.licenseNameFor((String) newValue)));
public boolean onPreferenceChange(Preference preference, Object newValue) { return true;
preference.setSummary(getString(Utils.licenseNameFor((String) newValue)));
return true;
}
}); });
CheckBoxPreference themePreference = (CheckBoxPreference) findPreference("theme"); CheckBoxPreference themePreference = (CheckBoxPreference) findPreference("theme");
themePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { themePreference.setOnPreferenceChangeListener((preference, newValue) -> {
@Override getActivity().recreate();
public boolean onPreferenceChange(Preference preference, Object newValue) { return true;
getActivity().recreate();
return true;
}
}); });
final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads"); final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads");
@ -51,36 +45,27 @@ public class SettingsFragment extends PreferenceFragment {
int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100); int uploads = sharedPref.getInt(Prefs.UPLOADS_SHOWING, 100);
uploadLimit.setText(uploads + ""); uploadLimit.setText(uploads + "");
uploadLimit.setSummary(uploads + ""); uploadLimit.setSummary(uploads + "");
uploadLimit.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { uploadLimit.setOnPreferenceChangeListener((preference, newValue) -> {
int value = Integer.parseInt(newValue.toString());
@Override final SharedPreferences.Editor editor = sharedPref.edit();
public boolean onPreferenceChange(Preference preference, Object newValue) { if (value > 500) {
int value = Integer.parseInt(newValue.toString()); new AlertDialog.Builder(getActivity())
final SharedPreferences.Editor editor = sharedPref.edit(); .setTitle(R.string.maximum_limit)
if (value > 500) { .setMessage(R.string.maximum_limit_alert)
new AlertDialog.Builder(getActivity()) .setPositiveButton(android.R.string.yes, (dialog, which) -> {})
.setTitle(R.string.maximum_limit) .setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.maximum_limit_alert) .show();
.setPositiveButton(android.R.string.yes, editor.putInt(Prefs.UPLOADS_SHOWING, 500);
new DialogInterface.OnClickListener() { editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,true);
public void onClick(DialogInterface dialog, int which) { uploadLimit.setSummary(500 + "");
} uploadLimit.setText(500 + "");
}) } else {
.setIcon(android.R.drawable.ic_dialog_alert) editor.putInt(Prefs.UPLOADS_SHOWING, Integer.parseInt(newValue.toString()));
.show(); editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,true);
editor.putInt(Prefs.UPLOADS_SHOWING, 500); uploadLimit.setSummary(newValue.toString());
editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,true);
uploadLimit.setSummary(500 + "");
uploadLimit.setText(500 + "");
} else {
editor.putInt(Prefs.UPLOADS_SHOWING, Integer.parseInt(newValue.toString()));
editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED,true);
uploadLimit.setSummary(newValue.toString());
}
editor.apply();
return true;
} }
editor.apply();
return true;
}); });

View file

@ -55,12 +55,7 @@ public class NavigationBaseActivity extends BaseActivity
public void initBackButton() { public void initBackButton() {
int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount(); int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
toggle.setDrawerIndicatorEnabled(backStackEntryCount == 0); toggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
toggle.setToolbarNavigationClickListener(new View.OnClickListener() { toggle.setToolbarNavigationClickListener(v -> onBackPressed());
@Override
public void onClick(View v) {
onBackPressed();
}
});
} }
public void initBack() { public void initBack() {
@ -118,25 +113,17 @@ public class NavigationBaseActivity extends BaseActivity
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setMessage(R.string.logout_verification) .setMessage(R.string.logout_verification)
.setCancelable(false) .setCancelable(false)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(R.string.yes, (dialog, which) -> {
@Override ((CommonsApplication) getApplicationContext())
public void onClick(DialogInterface dialog, int which) { .clearApplicationData(NavigationBaseActivity.this);
((CommonsApplication) getApplicationContext()) Intent nearbyIntent = new Intent(
.clearApplicationData(NavigationBaseActivity.this); NavigationBaseActivity.this, LoginActivity.class);
Intent nearbyIntent = new Intent( nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
NavigationBaseActivity.this, LoginActivity.class); nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(nearbyIntent);
nearbyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); finish();
startActivity(nearbyIntent);
finish();
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}) })
.setNegativeButton(R.string.no, (dialog, which) -> dialog.cancel())
.show(); .show();
return true; return true;
default: default:

View file

@ -72,21 +72,13 @@ public class ExistingFileAsync extends AsyncTask<Void, Void, Boolean> {
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.file_exists) builder.setMessage(R.string.file_exists)
.setTitle(R.string.warning); .setTitle(R.string.warning);
builder.setPositiveButton(R.string.no, new DialogInterface.OnClickListener() { builder.setPositiveButton(R.string.no, (dialog, id) -> {
@Override //Go back to ContributionsActivity
public void onClick(DialogInterface dialog, int id) { Intent intent = new Intent(context, ContributionsActivity.class);
//Go back to ContributionsActivity context.startActivity(intent);
Intent intent = new Intent(context, ContributionsActivity.class); callback.onResult(Result.DUPLICATE_CANCELLED);
context.startActivity(intent);
callback.onResult(Result.DUPLICATE_CANCELLED);
}
});
builder.setNegativeButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
callback.onResult(Result.DUPLICATE_PROCEED);
}
}); });
builder.setNegativeButton(R.string.yes, (dialog, id) -> callback.onResult(Result.DUPLICATE_PROCEED));
AlertDialog dialog = builder.create(); AlertDialog dialog = builder.create();
dialog.show(); dialog.show();

View file

@ -126,19 +126,16 @@ public class MultipleShareActivity
Contribution up = photosList.get(i); Contribution up = photosList.get(i);
final int uploadCount = i + 1; // Goddamn Java final int uploadCount = i + 1; // Goddamn Java
uploadController.startUpload(up, new UploadController.ContributionUploadProgress() { uploadController.startUpload(up, contribution -> {
@Override dialog.setProgress(uploadCount);
public void onUploadStarted(Contribution contribution) { if (uploadCount == photosList.size()) {
dialog.setProgress(uploadCount); dialog.dismiss();
if(uploadCount == photosList.size()) { Toast startingToast = Toast.makeText(
dialog.dismiss(); CommonsApplication.getInstance(),
Toast startingToast = Toast.makeText( R.string.uploading_started,
CommonsApplication.getInstance(), Toast.LENGTH_LONG
R.string.uploading_started, );
Toast.LENGTH_LONG startingToast.show();
);
startingToast.show();
}
} }
}); });
} }

View file

@ -57,7 +57,7 @@ public class MwVolleyApi {
Timber.d("URL: %s", apiUrl); Timber.d("URL: %s", apiUrl);
JsonRequest<QueryResponse> request = new QueryRequest(apiUrl, JsonRequest<QueryResponse> request = new QueryRequest(apiUrl,
new LogResponseListener<QueryResponse>(), new LogResponseErrorListener()); new LogResponseListener<>(), new LogResponseErrorListener());
getQueue().add(request); getQueue().add(request);
} }

View file

@ -45,6 +45,9 @@ import fr.free.nrw.commons.modifications.TemplateRemoveModifier;
import fr.free.nrw.commons.mwapi.EventLog; import fr.free.nrw.commons.mwapi.EventLog;
import timber.log.Timber; import timber.log.Timber;
import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.DUPLICATE_PROCEED;
import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.NO_DUPLICATE;
/** /**
* Activity for the title/desc screen after image is selected. Also starts processing image * Activity for the title/desc screen after image is selected. Also starts processing image
* GPS coordinates or user location (if enabled in Settings) for category suggestions. * GPS coordinates or user location (if enabled in Settings) for category suggestions.
@ -134,12 +137,9 @@ public class ShareActivity
Timber.d("Cache the categories found"); Timber.d("Cache the categories found");
} }
uploadController.startUpload(title, mediaUri, description, mimeType, source, decimalCoords, new UploadController.ContributionUploadProgress() { uploadController.startUpload(title, mediaUri, description, mimeType, source, decimalCoords, c -> {
@Override ShareActivity.this.contribution = c;
public void onUploadStarted(Contribution contribution) { showPostUpload();
ShareActivity.this.contribution = contribution;
showPostUpload();
}
}); });
} }
@ -380,14 +380,10 @@ public class ShareActivity
Timber.d("File SHA1 is: %s", fileSHA1); Timber.d("File SHA1 is: %s", fileSHA1);
ExistingFileAsync fileAsyncTask = ExistingFileAsync fileAsyncTask =
new ExistingFileAsync(fileSHA1, this, new ExistingFileAsync.Callback() { new ExistingFileAsync(fileSHA1, this, result -> {
@Override Timber.d("%s duplicate check: %s", mediaUri.toString(), result);
public void onResult(ExistingFileAsync.Result result) { duplicateCheckPassed = (result == DUPLICATE_PROCEED
Timber.d("%s duplicate check: %s", mediaUri.toString(), result); || result == NO_DUPLICATE);
duplicateCheckPassed =
result == ExistingFileAsync.Result.DUPLICATE_PROCEED
|| result == ExistingFileAsync.Result.NO_DUPLICATE;
}
}); });
fileAsyncTask.execute(); fileAsyncTask.execute();
} catch (IOException e) { } catch (IOException e) {
@ -402,17 +398,12 @@ public class ShareActivity
} }
} }
private Snackbar requestPermissionUsingSnackBar( private Snackbar requestPermissionUsingSnackBar(String rationale,
String rationale, final String[] perms, final int code) { final String[] perms,
final int code) {
Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), rationale, Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), rationale,
Snackbar.LENGTH_INDEFINITE) Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok,
.setAction(R.string.ok, new View.OnClickListener() { view -> ActivityCompat.requestPermissions(ShareActivity.this, perms, code));
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(ShareActivity.this,
perms, code);
}
});
snackbar.show(); snackbar.show();
return snackbar; return snackbar;
} }

View file

@ -7,14 +7,11 @@ import java.util.concurrent.Executor;
public class ExecutorUtils { public class ExecutorUtils {
private static final Executor uiExecutor = new Executor() { private static final Executor uiExecutor = command -> {
@Override if (Looper.myLooper() == Looper.getMainLooper()) {
public void execute(Runnable command) { command.run();
if (Looper.myLooper() == Looper.getMainLooper()) { } else {
command.run(); new Handler(Looper.getMainLooper()).post(command);
} else {
new Handler(Looper.getMainLooper()).post(command);
}
} }
}; };

View file

@ -42,8 +42,8 @@ public class FileUtils {
if (file != null) { if (file != null) {
if (file.isDirectory()) { if (file.isDirectory()) {
String[] children = file.list(); String[] children = file.list();
for (int i = 0; i < children.length; i++) { for (String child : children) {
deletedAll = deleteFile(new File(file, children[i])) && deletedAll; deletedAll = deleteFile(new File(file, child)) && deletedAll;
} }
} else { } else {
deletedAll = file.delete(); deletedAll = file.delete();

View file

@ -56,4 +56,14 @@
android:gravity="center" android:gravity="center"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
/> />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/media_upload_policy"
android:text="@string/media_upload_policy"
android:gravity="start"
android:layout_marginTop="16dp"
/>
</LinearLayout> </LinearLayout>

View file

@ -93,6 +93,7 @@ Tap this message (or hit back) to skip this step.</string>
<string name="menu_retry_upload">Retry</string> <string name="menu_retry_upload">Retry</string>
<string name="menu_cancel_upload">Cancel</string> <string name="menu_cancel_upload">Cancel</string>
<string name="share_license_summary">This image will be licensed under %1$s</string> <string name="share_license_summary">This image will be licensed under %1$s</string>
<string name="media_upload_policy">By submitting this picture, I declare that this is my own work, that it does not contain copyrighted material or selfies, and otherwise adheres to &lt;a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\"&gt;Wikimedia Commons policies&lt;/a&gt;.</string>
<string name="menu_download">Download</string> <string name="menu_download">Download</string>
<string name="preference_license">License</string> <string name="preference_license">License</string>
<string name="use_previous">Use previous title/description</string> <string name="use_previous">Use previous title/description</string>

View file

@ -113,14 +113,6 @@ public class NearbyAdapterFactoryTest {
assertEquals(PLACE, clickedPlace); assertEquals(PLACE, clickedPlace);
} }
@Test
public void clickViewHandlesMisconfiguredListener() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
RendererViewHolder viewHolder = renderComponent(result);
viewHolder.itemView.performClick();
}
@NonNull @NonNull
private RendererViewHolder renderComponent(RVRendererAdapter<Place> result) { private RendererViewHolder renderComponent(RVRendererAdapter<Place> result) {
FrameLayout viewGroup = new FrameLayout(RuntimeEnvironment.application); FrameLayout viewGroup = new FrameLayout(RuntimeEnvironment.application);

View file

@ -8,6 +8,7 @@ buildscript {
classpath "com.android.tools.build:gradle:${project.gradleVersion}" classpath "com.android.tools.build:gradle:${project.gradleVersion}"
classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.1' classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.1'
classpath 'me.tatarka:gradle-retrolambda:3.6.1'
} }
} }