Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Paul Hawke 2017-07-11 08:06:55 -05:00
commit c3649d3efd
18 changed files with 309 additions and 210 deletions

View file

@ -16,6 +16,7 @@ dependencies {
compile "com.android.support:design:${project.supportLibVersion}" compile "com.android.support:design:${project.supportLibVersion}"
compile 'com.google.code.gson:gson:2.8.0' compile 'com.google.code.gson:gson:2.8.0'
compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION" compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
compile 'com.github.pedrovgs:renderers:3.3.0'
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION" annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
compile 'com.jakewharton.timber:timber:4.5.1' compile 'com.jakewharton.timber:timber:4.5.1'
compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com.squareup.okhttp3:okhttp:3.8.1'

View file

@ -10,7 +10,6 @@ import android.net.Uri;
import android.text.TextUtils; import android.text.TextUtils;
import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.data.DBOpenHelper;
import timber.log.Timber; import timber.log.Timber;
public class ContributionsContentProvider extends ContentProvider{ public class ContributionsContentProvider extends ContentProvider{
@ -33,10 +32,8 @@ public class ContributionsContentProvider extends ContentProvider{
return Uri.parse(BASE_URI.toString() + "/" + id); return Uri.parse(BASE_URI.toString() + "/" + id);
} }
private DBOpenHelper dbOpenHelper;
@Override @Override
public boolean onCreate() { public boolean onCreate() {
dbOpenHelper = CommonsApplication.getInstance().getDBOpenHelper();
return false; return false;
} }
@ -47,7 +44,7 @@ public class ContributionsContentProvider extends ContentProvider{
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase();
Cursor cursor; Cursor cursor;
switch(uriType) { switch(uriType) {
@ -81,7 +78,7 @@ public class ContributionsContentProvider extends ContentProvider{
@Override @Override
public Uri insert(Uri uri, ContentValues contentValues) { public Uri insert(Uri uri, ContentValues contentValues) {
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
long id = 0; long id = 0;
switch (uriType) { switch (uriType) {
case CONTRIBUTIONS: case CONTRIBUTIONS:
@ -99,7 +96,7 @@ public class ContributionsContentProvider extends ContentProvider{
int rows = 0; int rows = 0;
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase();
switch(uriType) { switch(uriType) {
case CONTRIBUTIONS_ID: case CONTRIBUTIONS_ID:
@ -120,7 +117,7 @@ public class ContributionsContentProvider extends ContentProvider{
public int bulkInsert(Uri uri, ContentValues[] values) { public int bulkInsert(Uri uri, ContentValues[] values) {
Timber.d("Hello, bulk insert! (ContributionsContentProvider)"); Timber.d("Hello, bulk insert! (ContributionsContentProvider)");
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
sqlDB.beginTransaction(); sqlDB.beginTransaction();
switch (uriType) { switch (uriType) {
case CONTRIBUTIONS: case CONTRIBUTIONS:
@ -148,7 +145,7 @@ public class ContributionsContentProvider extends ContentProvider{
In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise.
*/ */
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
int rowsUpdated = 0; int rowsUpdated = 0;
switch (uriType) { switch (uriType) {
case CONTRIBUTIONS: case CONTRIBUTIONS:

View file

@ -10,7 +10,6 @@ import android.net.Uri;
import android.text.TextUtils; import android.text.TextUtils;
import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.data.DBOpenHelper;
import timber.log.Timber; import timber.log.Timber;
public class ModificationsContentProvider extends ContentProvider{ public class ModificationsContentProvider extends ContentProvider{
@ -33,10 +32,9 @@ public class ModificationsContentProvider extends ContentProvider{
return Uri.parse(BASE_URI.toString() + "/" + id); return Uri.parse(BASE_URI.toString() + "/" + id);
} }
private DBOpenHelper dbOpenHelper;
@Override @Override
public boolean onCreate() { public boolean onCreate() {
dbOpenHelper = CommonsApplication.getInstance().getDBOpenHelper();
return false; return false;
} }
@ -54,7 +52,7 @@ public class ModificationsContentProvider extends ContentProvider{
throw new IllegalArgumentException("Unknown URI" + uri); throw new IllegalArgumentException("Unknown URI" + uri);
} }
SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); SQLiteDatabase db = CommonsApplication.getInstance().getDBOpenHelper().getReadableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder); Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri); cursor.setNotificationUri(getContext().getContentResolver(), uri);
@ -70,7 +68,7 @@ public class ModificationsContentProvider extends ContentProvider{
@Override @Override
public Uri insert(Uri uri, ContentValues contentValues) { public Uri insert(Uri uri, ContentValues contentValues) {
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
long id = 0; long id = 0;
switch (uriType) { switch (uriType) {
case MODIFICATIONS: case MODIFICATIONS:
@ -86,7 +84,7 @@ public class ModificationsContentProvider extends ContentProvider{
@Override @Override
public int delete(Uri uri, String s, String[] strings) { public int delete(Uri uri, String s, String[] strings) {
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
switch (uriType) { switch (uriType) {
case MODIFICATIONS_ID: case MODIFICATIONS_ID:
String id = uri.getLastPathSegment(); String id = uri.getLastPathSegment();
@ -104,7 +102,7 @@ public class ModificationsContentProvider extends ContentProvider{
public int bulkInsert(Uri uri, ContentValues[] values) { public int bulkInsert(Uri uri, ContentValues[] values) {
Timber.d("Hello, bulk insert! (ModificationsContentProvider)"); Timber.d("Hello, bulk insert! (ModificationsContentProvider)");
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
sqlDB.beginTransaction(); sqlDB.beginTransaction();
switch (uriType) { switch (uriType) {
case MODIFICATIONS: case MODIFICATIONS:
@ -132,7 +130,7 @@ public class ModificationsContentProvider extends ContentProvider{
In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise. In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise.
*/ */
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = CommonsApplication.getInstance().getDBOpenHelper().getWritableDatabase();
int rowsUpdated = 0; int rowsUpdated = 0;
switch (uriType) { switch (uriType) {
case MODIFICATIONS: case MODIFICATIONS:

View file

@ -41,8 +41,7 @@ import timber.log.Timber;
public class NearbyActivity extends NavigationBaseActivity { public class NearbyActivity extends NavigationBaseActivity {
@BindView(R.id.progressBar) @BindView(R.id.progressBar) ProgressBar 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;
@ -133,7 +132,7 @@ public class NearbyActivity extends NavigationBaseActivity {
} }
} }
protected void checkGps() { private void checkGps() {
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");
@ -202,15 +201,11 @@ public class NearbyActivity extends NavigationBaseActivity {
} }
} }
protected void refreshView() { private void refreshView() {
nearbyAsyncTask = new NearbyAsyncTask(this); nearbyAsyncTask = new NearbyAsyncTask(this);
nearbyAsyncTask.execute(); nearbyAsyncTask.execute();
} }
public LocationServiceManager getLocationManager() {
return locationManager;
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
@ -221,17 +216,12 @@ public class NearbyActivity extends NavigationBaseActivity {
private class NearbyAsyncTask extends AsyncTask<Void, Integer, List<Place>> { private class NearbyAsyncTask extends AsyncTask<Void, Integer, List<Place>> {
private Context mContext; private final Context mContext;
private NearbyAsyncTask (Context context) { private NearbyAsyncTask (Context context) {
mContext = context; mContext = context;
} }
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override @Override
protected void onProgressUpdate(Integer... values) { protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values); super.onProgressUpdate(values);
@ -284,7 +274,7 @@ public class NearbyActivity extends NavigationBaseActivity {
/** /**
* Calls fragment for map view. * Calls fragment for map view.
*/ */
public void setMapFragment() { private void setMapFragment() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment fragment = new NearbyMapFragment(); Fragment fragment = new NearbyMapFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);
@ -295,7 +285,7 @@ public class NearbyActivity extends NavigationBaseActivity {
/** /**
* Calls fragment for list view. * Calls fragment for list view.
*/ */
public void setListFragment() { private void setListFragment() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment fragment = new NearbyListFragment(); Fragment fragment = new NearbyListFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);

View file

@ -1,44 +0,0 @@
package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import fr.free.nrw.commons.R;
import timber.log.Timber;
public class NearbyAdapter extends ArrayAdapter<Place> {
/** Accepts activity context and list of places.
* @param context activity context
*/
public NearbyAdapter(Context context) {
super(context, R.layout.item_place);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Place place = getItem(position);
Timber.v(String.valueOf(place));
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext())
.inflate(R.layout.item_place, parent, false);
}
NearbyViewHolder viewHolder = new NearbyViewHolder(convertView);
viewHolder.bindModel(getContext(), place);
// Return the completed view to render on screen
return convertView;
}
@Override
public long getItemId(int position) {
// TODO: use Wikidata Q-ID instead?
return position;
}
}

View file

@ -0,0 +1,24 @@
package fr.free.nrw.commons.nearby;
import com.pedrogomez.renderers.ListAdapteeCollection;
import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererBuilder;
import java.util.Collections;
import java.util.List;
class NearbyAdapterFactory {
private PlaceRenderer.PlaceClickedListener listener;
NearbyAdapterFactory(PlaceRenderer.PlaceClickedListener listener) {
this.listener = listener;
}
public RVRendererAdapter<Place> create(List<Place> placeList) {
RendererBuilder<Place> builder = new RendererBuilder<Place>()
.bind(Place.class, new PlaceRenderer(listener));
ListAdapteeCollection<Place> collection = new ListAdapteeCollection<>(
placeList != null ? placeList : Collections.<Place>emptyList());
return new RVRendererAdapter<>(builder, collection);
}
}

View file

@ -17,16 +17,11 @@ import fr.free.nrw.commons.utils.UriSerializer;
public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBaseMarker> { public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBaseMarker> {
private Place place; private Place place;
public NearbyBaseMarker() {
NearbyBaseMarker() {
} }
public NearbyBaseMarker place(Place place) { private NearbyBaseMarker(Parcel in) {
this.place = place;
return getThis();
}
public NearbyBaseMarker(Parcel in) {
Gson gson = new GsonBuilder() Gson gson = new GsonBuilder()
.registerTypeAdapter(Uri.class, new UriDeserializer()) .registerTypeAdapter(Uri.class, new UriDeserializer())
.create(); .create();
@ -42,6 +37,11 @@ public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBase
place(gson.fromJson(gsonString, Place.class)); place(gson.fromJson(gsonString, Place.class));
} }
public NearbyBaseMarker place(Place place) {
this.place = place;
return this;
}
@Override @Override
public NearbyBaseMarker getThis() { public NearbyBaseMarker getThis() {
return this; return this;
@ -52,6 +52,10 @@ public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBase
return new NearbyMarker(this, place); return new NearbyMarker(this, place);
} }
public Place getPlace() {
return place;
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;
@ -71,10 +75,6 @@ public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBase
dest.writeString(gson.toJson(place)); dest.writeString(gson.toJson(place));
} }
public Place getPlace() {
return place;
}
public static final Parcelable.Creator<NearbyBaseMarker> CREATOR public static final Parcelable.Creator<NearbyBaseMarker> CREATOR
= new Parcelable.Creator<NearbyBaseMarker>() { = new Parcelable.Creator<NearbyBaseMarker>() {
public NearbyBaseMarker createFromParcel(Parcel in) { public NearbyBaseMarker createFromParcel(Parcel in) {

View file

@ -29,19 +29,12 @@ public class NearbyInfoDialog extends OverlayDialog {
private final static String ARG_LONGITUDE = "longitude"; private final static String ARG_LONGITUDE = "longitude";
private final static String ARG_SITE_LINK = "sitelink"; private final static String ARG_SITE_LINK = "sitelink";
@BindView(R.id.link_preview_title) @BindView(R.id.link_preview_title) TextView placeTitle;
TextView placeTitle; @BindView(R.id.link_preview_extract) TextView placeDescription;
@BindView(R.id.link_preview_extract) @BindView(R.id.link_preview_go_button) TextView goToButton;
TextView placeDescription; @BindView(R.id.link_preview_overflow_button) ImageView overflowButton;
@BindView(R.id.link_preview_go_button)
TextView goToButton;
@BindView(R.id.link_preview_overflow_button)
ImageView overflowButton;
private Unbinder unbinder; private Unbinder unbinder;
private LatLng location; private LatLng location;
private Sitelinks sitelinks; private Sitelinks sitelinks;
@ -64,7 +57,7 @@ public class NearbyInfoDialog extends OverlayDialog {
private void getArticleLink(Bundle bundle) { private void getArticleLink(Bundle bundle) {
this.sitelinks = bundle.getParcelable(ARG_SITE_LINK); this.sitelinks = bundle.getParcelable(ARG_SITE_LINK);
if (sitelinks.getWikipediaLink().equals(Uri.EMPTY)) { if (sitelinks == null || Uri.EMPTY.equals(sitelinks.getWikipediaLink())) {
goToButton.setVisibility(View.GONE); goToButton.setVisibility(View.GONE);
} }
@ -99,7 +92,7 @@ public class NearbyInfoDialog extends OverlayDialog {
|| !sitelinks.getWikidataLink().equals(Uri.EMPTY); || !sitelinks.getWikidataLink().equals(Uri.EMPTY);
} }
private PopupMenu.OnMenuItemClickListener menuListener = new PopupMenu private final PopupMenu.OnMenuItemClickListener menuListener = new PopupMenu
.OnMenuItemClickListener() { .OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {

View file

@ -2,37 +2,37 @@ package fr.free.nrw.commons.nearby;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ListFragment; import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ListView;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List; import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemClick;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.utils.UriDeserializer; import fr.free.nrw.commons.utils.UriDeserializer;
import timber.log.Timber; import timber.log.Timber;
public class NearbyListFragment extends ListFragment { public class NearbyListFragment extends Fragment {
private List<Place> placeList; private static final Type LIST_TYPE = new TypeToken<List<Place>>() {
}.getType();
private static final Type CUR_LAT_LNG_TYPE = new TypeToken<LatLng>() {
}.getType();
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Uri.class, new UriDeserializer())
.create();
@BindView(R.id.listView) ListView listview; private NearbyAdapterFactory adapterFactory;
private RecyclerView recyclerView;
private NearbyAdapter adapter;
public NearbyListFragment() {
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -41,55 +41,39 @@ public class NearbyListFragment extends ListFragment {
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
Timber.d("NearbyListFragment created"); Timber.d("NearbyListFragment created");
View view = inflater.inflate(R.layout.fragment_nearby, container, false); View view = inflater.inflate(R.layout.fragment_nearby, container, false);
ButterKnife.bind(this, view); recyclerView = (RecyclerView) view.findViewById(R.id.listView);
adapter = new NearbyAdapter(getActivity()); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
listview.setAdapter(adapter); adapterFactory = new NearbyAdapterFactory(new PlaceRenderer.PlaceClickedListener() {
@Override
public void placeClicked(Place place) {
NearbyInfoDialog.showYourself(getActivity(), place);
}
});
return view; return view;
} }
@Override @Override
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
// Check that this is the first time view is created, // Check that this is the first time view is created,
// to avoid double list when screen orientation changed // to avoid double list when screen orientation changed
List<Place> placeList = Collections.emptyList();
Bundle bundle = this.getArguments(); Bundle bundle = this.getArguments();
Gson gson = new GsonBuilder()
.registerTypeAdapter(Uri.class, new UriDeserializer())
.create();
if (bundle != null) { if (bundle != null) {
String gsonPlaceList = bundle.getString("PlaceList"); String gsonPlaceList = bundle.getString("PlaceList");
placeList = gson.fromJson(gsonPlaceList, LIST_TYPE);
String gsonLatLng = bundle.getString("CurLatLng"); String gsonLatLng = bundle.getString("CurLatLng");
Type listType = new TypeToken<List<Place>>() {}.getType(); LatLng curLatLng = gson.fromJson(gsonLatLng, CUR_LAT_LNG_TYPE);
placeList = gson.fromJson(gsonPlaceList, listType);
Type curLatLngType = new TypeToken<LatLng>() {}.getType();
LatLng curLatLng = gson.fromJson(gsonLatLng, curLatLngType);
placeList = NearbyController.loadAttractionsFromLocationToPlaces(curLatLng, placeList); placeList = NearbyController.loadAttractionsFromLocationToPlaces(curLatLng, placeList);
} }
if (savedInstanceState == null) {
adapter.clear();
Timber.d("Saved instance state is null, populating ListView");
}
adapter.clear(); recyclerView.setAdapter(adapterFactory.create(placeList));
adapter.addAll(placeList);
adapter.notifyDataSetChanged();
}
@OnItemClick(R.id.listView)
void onItemClicked(int position) {
Place place = (Place) listview.getItemAtPosition(position);
LatLng placeLatLng = place.location;
double latitude = placeLatLng.getLatitude();
double longitude = placeLatLng.getLongitude();
Timber.d("Item at position %d has coords: Lat: %f Long: %f", position, latitude, longitude);
NearbyInfoDialog.showYourself(getActivity(), place);
} }
} }

View file

@ -5,7 +5,6 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -39,7 +38,6 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
private fr.free.nrw.commons.location.LatLng curLatLng; private fr.free.nrw.commons.location.LatLng curLatLng;
public NearbyMapFragment() { public NearbyMapFragment() {
} }
@Override @Override
@ -123,7 +121,7 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
* which represents the user's position with an accuracy * which represents the user's position with an accuracy
* of 95%. * of 95%.
*/ */
public void addCurrentLocationMarker(MapboxMap mapboxMap) { private void addCurrentLocationMarker(MapboxMap mapboxMap) {
MarkerOptions currentLocationMarker = new MarkerOptions() MarkerOptions currentLocationMarker = new MarkerOptions()
.position(new LatLng(curLatLng.getLatitude(), curLatLng.getLongitude())); .position(new LatLng(curLatLng.getLatitude(), curLatLng.getLongitude()));
mapboxMap.addMarker(currentLocationMarker); mapboxMap.addMarker(currentLocationMarker);
@ -146,7 +144,7 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
* *
* @return List List of LatLng points of the circle. * @return List List of LatLng points of the circle.
*/ */
public List<LatLng> createCircleArray( private List<LatLng> createCircleArray(
double centerLat, double centerLong, float radius, int nodes) { double centerLat, double centerLong, float radius, int nodes) {
List<LatLng> circle = new ArrayList<>(); List<LatLng> circle = new ArrayList<>();
float radiusKilometer = radius / 1000; float radiusKilometer = radius / 1000;
@ -164,11 +162,6 @@ public class NearbyMapFragment extends android.support.v4.app.Fragment {
return circle; return circle;
} }
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override @Override
public void onStart() { public void onStart() {
if (mapView != null) { if (mapView != null) {

View file

@ -2,8 +2,8 @@ package fr.free.nrw.commons.nearby;
import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.Marker;
public class NearbyMarker extends Marker { class NearbyMarker extends Marker {
private Place place; private final Place place;
private NearbyBaseMarker nearbyBaseMarker; private NearbyBaseMarker nearbyBaseMarker;
/** /**
@ -11,21 +11,17 @@ public class NearbyMarker extends Marker {
* *
* @param baseMarkerOptions The builder used to construct the Marker. * @param baseMarkerOptions The builder used to construct the Marker.
*/ */
public NearbyMarker(NearbyBaseMarker baseMarkerOptions, Place place) { NearbyMarker(NearbyBaseMarker baseMarkerOptions, Place place) {
super(baseMarkerOptions); super(baseMarkerOptions);
this.place = place; this.place = place;
this.nearbyBaseMarker = baseMarkerOptions; this.nearbyBaseMarker = baseMarkerOptions;
} }
public NearbyBaseMarker getNearbyBaseMarker() { NearbyBaseMarker getNearbyBaseMarker() {
return nearbyBaseMarker; return nearbyBaseMarker;
} }
public Place getPlace() { public Place getPlace() {
return place; return place;
} }
public void setNearbyBaseMarker(NearbyBaseMarker nearbyBaseMarker) {
this.nearbyBaseMarker = nearbyBaseMarker;
}
} }

View file

@ -34,8 +34,7 @@ public class NearbyPlaces {
public NearbyPlaces() { public NearbyPlaces() {
try { try {
String query = FileUtils.readFromResource("/assets/queries/nearby_query.rq"); wikidataQuery = FileUtils.readFromResource("/assets/queries/nearby_query.rq");
wikidataQuery = query;
Timber.v(wikidataQuery); Timber.v(wikidataQuery);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -106,8 +105,8 @@ public class NearbyPlaces {
String wikiDataLink = Utils.stripLocalizedString(fields[1]); String wikiDataLink = Utils.stripLocalizedString(fields[1]);
String icon = fields[5]; String icon = fields[5];
double latitude = 0; double latitude;
double longitude = 0; double longitude;
Matcher matcher = Matcher matcher =
Pattern.compile("Point\\(([^ ]+) ([^ ]+)\\)").matcher(point); Pattern.compile("Point\\(([^ ]+) ([^ ]+)\\)").matcher(point);
if (!matcher.find()) { if (!matcher.find()) {

View file

@ -1,35 +0,0 @@
package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.ViewHolder;
public class NearbyViewHolder implements ViewHolder<Place> {
@BindView(R.id.tvName) TextView tvName;
@BindView(R.id.tvDesc) TextView tvDesc;
@BindView(R.id.distance) TextView distance;
@BindView(R.id.icon) ImageView icon;
public NearbyViewHolder(View view) {
ButterKnife.bind(this, view);
}
@Override
public void bindModel(Context context, Place place) {
// Populate the data into the template view using the data object
tvName.setText(place.name);
String descriptionText = place.getDescription().getText();
if (descriptionText.equals("?")) {
descriptionText = context.getString(R.string.no_description_found);
}
tvDesc.setText(descriptionText);
distance.setText(place.distance);
icon.setImageResource(place.getDescription().getIcon());
}
}

View file

@ -14,14 +14,14 @@ public class Place {
public final String name; public final String name;
private final Description description; private final Description description;
public final String longDescription; private final String longDescription;
public final Uri secondaryImageUrl; private final Uri secondaryImageUrl;
public final LatLng location; public final LatLng location;
public Bitmap image; public Bitmap image;
public Bitmap secondaryImage; public Bitmap secondaryImage;
public String distance; public String distance;
public Sitelinks siteLinks; public final Sitelinks siteLinks;
public Place(String name, Description description, String longDescription, public Place(String name, Description description, String longDescription,

View file

@ -0,0 +1,64 @@
package fr.free.nrw.commons.nearby;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.pedrogomez.renderers.Renderer;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.R;
class PlaceRenderer extends Renderer<Place> {
@BindView(R.id.tvName) TextView tvName;
@BindView(R.id.tvDesc) TextView tvDesc;
@BindView(R.id.distance) TextView distance;
@BindView(R.id.icon) ImageView icon;
private final PlaceClickedListener listener;
PlaceRenderer(PlaceClickedListener listener) {
this.listener = listener;
}
@Override
protected View inflate(LayoutInflater layoutInflater, ViewGroup viewGroup) {
return layoutInflater.inflate(R.layout.item_place, viewGroup, false);
}
@Override
protected void setUpView(View view) {
ButterKnife.bind(this, view);
}
@Override
protected void hookListeners(View view) {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.placeClicked(getContent());
}
}
});
}
@Override
public void render() {
Place place = getContent();
tvName.setText(place.name);
String descriptionText = place.getDescription().getText();
if (descriptionText.equals("?")) {
descriptionText = getContext().getString(R.string.no_description_found);
}
tvDesc.setText(descriptionText);
distance.setText(place.distance);
icon.setImageResource(place.getDescription().getIcon());
}
interface PlaceClickedListener {
void placeClicked(Place place);
}
}

View file

@ -4,7 +4,7 @@
android:orientation="vertical" android:orientation="vertical"
> >
<ListView <android.support.v7.widget.RecyclerView
android:id="@+id/listView" android:id="@+id/listView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -27,7 +27,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class) @Config(constants = BuildConfig.class, sdk = 21)
public class ApacheHttpClientMediaWikiApiTest { public class ApacheHttpClientMediaWikiApiTest {
private ApacheHttpClientMediaWikiApi testObject; private ApacheHttpClientMediaWikiApi testObject;
@ -36,7 +36,7 @@ public class ApacheHttpClientMediaWikiApiTest {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
server = new MockWebServer(); server = new MockWebServer();
testObject = new ApacheHttpClientMediaWikiApi("http://localhost:" + server.getPort() + "/"); testObject = new ApacheHttpClientMediaWikiApi("http://" + server.getHostName() + ":" + server.getPort() + "/");
} }
@After @After
@ -163,7 +163,7 @@ public class ApacheHttpClientMediaWikiApiTest {
} }
@Test @Test
public void editToken() throws Exception{ public void editToken() throws Exception {
server.enqueue(new MockResponse().setBody("<?xml version=\"1.0\"?><api><tokens edittoken=\"baz\" /></api>")); server.enqueue(new MockResponse().setBody("<?xml version=\"1.0\"?><api><tokens edittoken=\"baz\" /></api>"));
String result = testObject.getEditToken(); String result = testObject.getEditToken();

View file

@ -0,0 +1,139 @@
package fr.free.nrw.commons.nearby;
import android.support.annotation.NonNull;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.pedrogomez.renderers.RVRendererAdapter;
import com.pedrogomez.renderers.RendererViewHolder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowDrawable;
import java.util.Collections;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.location.LatLng;
import static org.junit.Assert.*;
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class NearbyAdapterFactoryTest {
private static final Place PLACE = new Place("name", Place.Description.AIRPORT,
"desc", null, new LatLng(38.6270, -90.1994, 0), null);
private static final Place UNKNOWN_PLACE = new Place("name", Place.Description.UNKNOWN,
"desc", null, new LatLng(39.7392, -104.9903, 0), null);
private Place clickedPlace;
@Test
public void factoryHandlesNullListAndNullListener() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(null);
assertNotNull(result);
assertEquals(0, result.getItemCount());
}
@Test
public void factoryHandlesEmptyListAndNullListener() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(Collections.<Place>emptyList());
assertNotNull(result);
assertEquals(0, result.getItemCount());
}
@Test
public void factoryHandlesNonEmptyListAndNullListener() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
assertNotNull(result);
assertEquals(1, result.getItemCount());
assertEquals(PLACE, result.getItem(0));
}
@Test
public void rendererCorrectlyBound() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
RendererViewHolder viewHolder = renderComponent(result);
assertNotNull(viewHolder.itemView.findViewById(R.id.tvName));
assertEquals("name",
((TextView) viewHolder.itemView.findViewById(R.id.tvName)).getText().toString());
assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
assertEquals("airport",
((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());
assertNotNull(viewHolder.itemView.findViewById(R.id.distance));
assertEquals("",
((TextView) viewHolder.itemView.findViewById(R.id.distance)).getText().toString());
assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
ShadowDrawable shadow = Shadows.shadowOf(imageView.getDrawable());
assertEquals(R.drawable.round_icon_airport, shadow.getCreatedFromResId());
}
@Test
public void rendererCorrectlyBoundForUnknownPlace() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(null);
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(UNKNOWN_PLACE));
RendererViewHolder viewHolder = renderComponent(result);
assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
assertEquals("no description found",
((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());
assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
ShadowDrawable shadow = Shadows.shadowOf(imageView.getDrawable());
assertEquals(R.drawable.round_icon_unknown, shadow.getCreatedFromResId());
}
@Test
public void clickView() {
NearbyAdapterFactory testObject = new NearbyAdapterFactory(new MockPlaceClickedListener());
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
RendererViewHolder viewHolder = renderComponent(result);
viewHolder.itemView.performClick();
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
private RendererViewHolder renderComponent(RVRendererAdapter<Place> result) {
FrameLayout viewGroup = new FrameLayout(RuntimeEnvironment.application);
int itemViewType = result.getItemViewType(0);
RendererViewHolder viewHolder = result.onCreateViewHolder(viewGroup, itemViewType);
assertNotNull(viewHolder);
result.bindViewHolder(viewHolder, 0);
return viewHolder;
}
private class MockPlaceClickedListener implements PlaceRenderer.PlaceClickedListener {
@Override
public void placeClicked(Place place) {
clickedPlace = place;
}
}
}