Skip to content

Commit

Permalink
Fixes commons-app#1450 Add filter to nearby (commons-app#3178)
Browse files Browse the repository at this point in the history
* Add layout items for nearby filter list and filter item

(cherry picked from commit b96f8a6)

* Edit nearby query

(cherry picked from commit 1f3c8c8)

* Add filter items to nearby parent fragment xml

(cherry picked from commit d0beadd)

* Add icon for green marker

(cherry picked from commit f65ca03)

* Add layout util file to organize layout utilities

(cherry picked from commit 5c57939)

* Add pic parameter to nearby result item

(cherry picked from commit 86007e4)

* Add pic parameter to place type

(cherry picked from commit 25c358b)

* Add green marker styling

(cherry picked from commit 929c92d)

* Inıt search layouts on Nearby parent

(cherry picked from commit 2ac38a1)

* Style green markers at nearby controller

(cherry picked from commit 3e08f39)

* Edit bookmark daos to include pic to tables

(cherry picked from commit 48d69ed)

* TODO foc bookmark dao item but works now

(cherry picked from commit f748399)

* Style nearby filter area

(cherry picked from commit 6267e48)

* fix style of filter tab

(cherry picked from commit 5f843bf)

* Add nearby list adapter

(cherry picked from commit 56334af)

* Current status, list size is working, visibility working, filter mechanism is ready

(cherry picked from commit 7d75c9c)

* Filtering works

(cherry picked from commit 8a13cf7)

* Filter function works

(cherry picked from commit 78368a2)

* Fix style issues

(cherry picked from commit 2204f70)

* Add divider to recyclerview

(cherry picked from commit c8100b5)

* Hide bottom sheets accordingly

(cherry picked from commit c5deba8)

* Code cleanup

(cherry picked from commit cf8f64f)

* Add actions to chips

* Fetch destroyed information from servers

* Add destroyed places icon

* Make chip filter functions work

* Revert irrelevant changes

* Revert accidentally replaced strings

* Remove unneeded lines

* Remove only places expalanation from trings

* Do not filter if nearby places are not loaded

* Add triple checkbox for add none and neutral

* Make tri checkbox work

* Fix travis issue

* Add coments

* fix search this area button locaton

* Set initial place type state and recover it between each populate places
  • Loading branch information
neslihanturan authored and misaochan committed Nov 28, 2019
1 parent 5c6ab3b commit b3c1184
Show file tree
Hide file tree
Showing 35 changed files with 1,265 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -156,8 +157,11 @@ Place fromCursor(Cursor cursor) {
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
location,
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)),
builder.build()
builder.build(),
null,
null
);
// TODO: add pic and destroyed to bookmark location dao
}

private ContentValues toContentValues(Place bookmarkLocation) {
Expand All @@ -172,6 +176,7 @@ private ContentValues toContentValues(Place bookmarkLocation) {
cv.put(BookmarkLocationsDao.Table.COLUMN_COMMONS_LINK, bookmarkLocation.siteLinks.getCommonsLink().toString());
cv.put(BookmarkLocationsDao.Table.COLUMN_LAT, bookmarkLocation.location.getLatitude());
cv.put(BookmarkLocationsDao.Table.COLUMN_LONG, bookmarkLocation.location.getLongitude());
cv.put(BookmarkLocationsDao.Table.COLUMN_PIC, bookmarkLocation.pic);
return cv;
}

Expand All @@ -189,6 +194,7 @@ public static class Table {
static final String COLUMN_WIKIPEDIA_LINK = "location_wikipedia_link";
static final String COLUMN_WIKIDATA_LINK = "location_wikidata_link";
static final String COLUMN_COMMONS_LINK = "location_commons_link";
static final String COLUMN_PIC = "location_pic";

// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
public static final String[] ALL_FIELDS = {
Expand All @@ -202,7 +208,8 @@ public static class Table {
COLUMN_IMAGE_URL,
COLUMN_WIKIPEDIA_LINK,
COLUMN_WIKIDATA_LINK,
COLUMN_COMMONS_LINK
COLUMN_COMMONS_LINK,
COLUMN_PIC
};

static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
Expand All @@ -218,7 +225,8 @@ public static class Table {
+ COLUMN_IMAGE_URL + " STRING,"
+ COLUMN_WIKIPEDIA_LINK + " STRING,"
+ COLUMN_WIKIDATA_LINK + " STRING,"
+ COLUMN_COMMONS_LINK + " STRING"
+ COLUMN_COMMONS_LINK + " STRING,"
+ COLUMN_PIC + " STRING"
+ ");";

public static void onCreate(SQLiteDatabase db) {
Expand Down
195 changes: 195 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/nearby/CheckBoxTriStates.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package fr.free.nrw.commons.nearby;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.widget.CompoundButton;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatCheckBox;

import fr.free.nrw.commons.R;
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;

/**
* Base on https://stackoverflow.com/a/40939367/3950497 answer.
*/
public class CheckBoxTriStates extends AppCompatCheckBox {

static public final int UNKNOWN = -1;

static public final int UNCHECKED = 0;

static public final int CHECKED = 1;

private int state;

/**
* This is the listener set to the super class which is going to be evoke each
* time the check state has changed.
*/
private final OnCheckedChangeListener privateListener = new CompoundButton.OnCheckedChangeListener() {

// checkbox status is changed from uncheck to checked.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
switch (state) {
case UNKNOWN:
setState(UNCHECKED);;
break;
case UNCHECKED:
setState(CHECKED);
break;
case CHECKED:
setState(UNKNOWN);
break;
}
}
};

/**
* Holds a reference to the listener set by a client, if any.
*/
private OnCheckedChangeListener clientListener;

/**
* This flag is needed to avoid accidentally changing the current {@link #state} when
* {@link #onRestoreInstanceState(Parcelable)} calls {@link #setChecked(boolean)}
* evoking our {@link #privateListener} and therefore changing the real state.
*/
private boolean restoring;

public CheckBoxTriStates(Context context) {
super(context);
init();
}

public CheckBoxTriStates(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public CheckBoxTriStates(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

public int getState() {
return state;
}

public void setState(int state) {
if(!this.restoring && this.state != state) {
this.state = state;

if(this.clientListener != null) {
this.clientListener.onCheckedChanged(this, this.isChecked());
}

if (NearbyController.currentLocation != null) {
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(null, state, false, true);
}
updateBtn();
}
}

@Override
public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {

// we never truly set the listener to the client implementation, instead we only hold
// a reference to it and evoke it when needed.
if(this.privateListener != listener) {
this.clientListener = listener;
}

// always use our implementation
super.setOnCheckedChangeListener(privateListener);
}

@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();

SavedState ss = new SavedState(superState);

ss.state = state;

return ss;
}

@Override
public void onRestoreInstanceState(Parcelable state) {
this.restoring = true; // indicates that the ui is restoring its state
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setState(ss.state);
requestLayout();
this.restoring = false;
}

private void init() {
state = UNKNOWN;
updateBtn();
}

public void addAction() {
setOnCheckedChangeListener(this.privateListener);
}

private void updateBtn() {
int btnDrawable = R.drawable.ic_indeterminate_check_box_black_24dp;
switch (state) {
case UNKNOWN:
btnDrawable = R.drawable.ic_indeterminate_check_box_black_24dp;
break;
case UNCHECKED:
btnDrawable = R.drawable.ic_check_box_outline_blank_black_24dp;
break;
case CHECKED:
btnDrawable = R.drawable.ic_check_box_black_24dp;
break;
}
setButtonDrawable(btnDrawable);

}

static class SavedState extends BaseSavedState {
int state;

SavedState(Parcelable superState) {
super(superState);
}

private SavedState(Parcel in) {
super(in);
state = in.readInt();
}

@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeValue(state);
}

@Override
public String toString() {
return "CheckboxTriState.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " state=" + state + "}";
}

@SuppressWarnings("hiding")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}

@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
15 changes: 14 additions & 1 deletion app/src/main/java/fr/free/nrw/commons/nearby/Label.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public enum Label {
TEMPLE("Q44539", R.drawable.round_icon_church),
UNKNOWN("?", R.drawable.round_icon_unknown);

private static final Map<String, Label> TEXT_TO_DESCRIPTION
public static final Map<String, Label> TEXT_TO_DESCRIPTION
= new HashMap<>(Label.values().length);

static {
Expand All @@ -54,6 +54,7 @@ public enum Label {
private final String text;
@DrawableRes
private final int icon;
private boolean selected;

Label(String text, @DrawableRes int icon) {
this.text = text;
Expand All @@ -65,6 +66,18 @@ public enum Label {
this.icon = in.readInt();
}

/**
* Will be used for nearby filter, to determine if place type is selected or not
* @param isSelected true if user selected the place type
*/
public void setSelected(boolean isSelected) {
this.selected = isSelected;
}

public boolean isSelected() {
return selected;
}

public String getText() {
return text;
}
Expand Down
31 changes: 31 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/nearby/MarkerPlaceGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package fr.free.nrw.commons.nearby;

import com.mapbox.mapboxsdk.annotations.Marker;

/**
* This class groups visual map item Marker with the reated data of displayed place and information
* of bookmark
*/
public class MarkerPlaceGroup {
private Marker marker; // Marker item from the map
private boolean isBookmarked; // True if user bookmarked the place
private Place place; // Place of the location displayed by the marker

public MarkerPlaceGroup(Marker marker, boolean isBookmarked, Place place) {
this.marker = marker;
this.isBookmarked = isBookmarked;
this.place = place;
}

public Marker getMarker() {
return marker;
}

public Place getPlace() {
return place;
}

public boolean getIsBookmarked() {
return isBookmarked;
}
}
33 changes: 29 additions & 4 deletions app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;

import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -33,6 +34,10 @@ public class NearbyController {
public static LatLng latestSearchLocation; // Can be current and camera target on search this area button is used
public static double latestSearchRadius = 10.0; // Any last search radius except closest result search

public static List<MarkerPlaceGroup> markerLabelList = new ArrayList<>();
public static Map<Boolean, Marker> markerExistsMap;
public static Map<Boolean, Marker> markerNeedPicMap;

@Inject
public NearbyController(NearbyPlaces nearbyPlaces) {
this.nearbyPlaces = nearbyPlaces;
Expand Down Expand Up @@ -158,6 +163,8 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS));

VectorDrawableCompat vectorDrawable = null;
VectorDrawableCompat vectorDrawableGreen = null;
VectorDrawableCompat vectorDrawableGrey = null;
try {
vectorDrawable = VectorDrawableCompat.create(
context.getResources(), R.drawable.ic_custom_bookmark_marker, context.getTheme()
Expand Down Expand Up @@ -191,13 +198,18 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
vectorDrawable = null;
try {
vectorDrawable = VectorDrawableCompat.create(
context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme()
);
context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme());
vectorDrawableGreen = VectorDrawableCompat.create(
context.getResources(), R.drawable.ic_custom_map_marker_green, context.getTheme());
vectorDrawableGrey = VectorDrawableCompat.create(
context.getResources(), R.drawable.ic_custom_map_marker_grey, context.getTheme());
} catch (Resources.NotFoundException e) {
// ignore when running tests.
}
if (vectorDrawable != null) {
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
Bitmap iconGreen = UiUtils.getBitmap(vectorDrawableGreen);
Bitmap iconGrey = UiUtils.getBitmap(vectorDrawableGrey);

for (Place place : placeList) {
String distance = formatDistanceBetween(curLatLng, place.location);
Expand All @@ -210,8 +222,21 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
place.location.getLatitude(),
place.location.getLongitude()));
nearbyBaseMarker.place(place);
nearbyBaseMarker.icon(IconFactory.getInstance(context)
.fromBitmap(icon));
// Check if string is only spaces or empty, if so place doesn't have any picture
if (!place.pic.trim().isEmpty()) {
if (iconGreen != null) {
nearbyBaseMarker.icon(IconFactory.getInstance(context)
.fromBitmap(iconGreen));
}
} else if (!place.destroyed.trim().isEmpty()) { // Means place is destroyed
if (iconGrey != null) {
nearbyBaseMarker.icon(IconFactory.getInstance(context)
.fromBitmap(iconGrey));
}
} else {
nearbyBaseMarker.icon(IconFactory.getInstance(context)
.fromBitmap(icon));
}

baseMarkerOptions.add(nearbyBaseMarker);
}
Expand Down
Loading

0 comments on commit b3c1184

Please sign in to comment.