Skip to content

Commit b3c1184

Browse files
neslihanturanmisaochan
authored andcommitted
Fixes commons-app#1450 Add filter to nearby (commons-app#3178)
* 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
1 parent 5c6ab3b commit b3c1184

35 files changed

+1265
-67
lines changed

app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.database.sqlite.SQLiteDatabase;
77
import android.os.RemoteException;
88
import androidx.annotation.NonNull;
9+
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
910

1011
import java.util.ArrayList;
1112
import java.util.List;
@@ -156,8 +157,11 @@ Place fromCursor(Cursor cursor) {
156157
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
157158
location,
158159
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)),
159-
builder.build()
160+
builder.build(),
161+
null,
162+
null
160163
);
164+
// TODO: add pic and destroyed to bookmark location dao
161165
}
162166

163167
private ContentValues toContentValues(Place bookmarkLocation) {
@@ -172,6 +176,7 @@ private ContentValues toContentValues(Place bookmarkLocation) {
172176
cv.put(BookmarkLocationsDao.Table.COLUMN_COMMONS_LINK, bookmarkLocation.siteLinks.getCommonsLink().toString());
173177
cv.put(BookmarkLocationsDao.Table.COLUMN_LAT, bookmarkLocation.location.getLatitude());
174178
cv.put(BookmarkLocationsDao.Table.COLUMN_LONG, bookmarkLocation.location.getLongitude());
179+
cv.put(BookmarkLocationsDao.Table.COLUMN_PIC, bookmarkLocation.pic);
175180
return cv;
176181
}
177182

@@ -189,6 +194,7 @@ public static class Table {
189194
static final String COLUMN_WIKIPEDIA_LINK = "location_wikipedia_link";
190195
static final String COLUMN_WIKIDATA_LINK = "location_wikidata_link";
191196
static final String COLUMN_COMMONS_LINK = "location_commons_link";
197+
static final String COLUMN_PIC = "location_pic";
192198

193199
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
194200
public static final String[] ALL_FIELDS = {
@@ -202,7 +208,8 @@ public static class Table {
202208
COLUMN_IMAGE_URL,
203209
COLUMN_WIKIPEDIA_LINK,
204210
COLUMN_WIKIDATA_LINK,
205-
COLUMN_COMMONS_LINK
211+
COLUMN_COMMONS_LINK,
212+
COLUMN_PIC
206213
};
207214

208215
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
@@ -218,7 +225,8 @@ public static class Table {
218225
+ COLUMN_IMAGE_URL + " STRING,"
219226
+ COLUMN_WIKIPEDIA_LINK + " STRING,"
220227
+ COLUMN_WIKIDATA_LINK + " STRING,"
221-
+ COLUMN_COMMONS_LINK + " STRING"
228+
+ COLUMN_COMMONS_LINK + " STRING,"
229+
+ COLUMN_PIC + " STRING"
222230
+ ");";
223231

224232
public static void onCreate(SQLiteDatabase db) {
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package fr.free.nrw.commons.nearby;
2+
3+
import android.content.Context;
4+
import android.os.Parcel;
5+
import android.os.Parcelable;
6+
import android.util.AttributeSet;
7+
import android.widget.CompoundButton;
8+
9+
import androidx.annotation.Nullable;
10+
import androidx.appcompat.widget.AppCompatCheckBox;
11+
12+
import fr.free.nrw.commons.R;
13+
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
14+
15+
/**
16+
* Base on https://stackoverflow.com/a/40939367/3950497 answer.
17+
*/
18+
public class CheckBoxTriStates extends AppCompatCheckBox {
19+
20+
static public final int UNKNOWN = -1;
21+
22+
static public final int UNCHECKED = 0;
23+
24+
static public final int CHECKED = 1;
25+
26+
private int state;
27+
28+
/**
29+
* This is the listener set to the super class which is going to be evoke each
30+
* time the check state has changed.
31+
*/
32+
private final OnCheckedChangeListener privateListener = new CompoundButton.OnCheckedChangeListener() {
33+
34+
// checkbox status is changed from uncheck to checked.
35+
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
36+
switch (state) {
37+
case UNKNOWN:
38+
setState(UNCHECKED);;
39+
break;
40+
case UNCHECKED:
41+
setState(CHECKED);
42+
break;
43+
case CHECKED:
44+
setState(UNKNOWN);
45+
break;
46+
}
47+
}
48+
};
49+
50+
/**
51+
* Holds a reference to the listener set by a client, if any.
52+
*/
53+
private OnCheckedChangeListener clientListener;
54+
55+
/**
56+
* This flag is needed to avoid accidentally changing the current {@link #state} when
57+
* {@link #onRestoreInstanceState(Parcelable)} calls {@link #setChecked(boolean)}
58+
* evoking our {@link #privateListener} and therefore changing the real state.
59+
*/
60+
private boolean restoring;
61+
62+
public CheckBoxTriStates(Context context) {
63+
super(context);
64+
init();
65+
}
66+
67+
public CheckBoxTriStates(Context context, AttributeSet attrs) {
68+
super(context, attrs);
69+
init();
70+
}
71+
72+
public CheckBoxTriStates(Context context, AttributeSet attrs, int defStyleAttr) {
73+
super(context, attrs, defStyleAttr);
74+
init();
75+
}
76+
77+
public int getState() {
78+
return state;
79+
}
80+
81+
public void setState(int state) {
82+
if(!this.restoring && this.state != state) {
83+
this.state = state;
84+
85+
if(this.clientListener != null) {
86+
this.clientListener.onCheckedChanged(this, this.isChecked());
87+
}
88+
89+
if (NearbyController.currentLocation != null) {
90+
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(null, state, false, true);
91+
}
92+
updateBtn();
93+
}
94+
}
95+
96+
@Override
97+
public void setOnCheckedChangeListener(@Nullable OnCheckedChangeListener listener) {
98+
99+
// we never truly set the listener to the client implementation, instead we only hold
100+
// a reference to it and evoke it when needed.
101+
if(this.privateListener != listener) {
102+
this.clientListener = listener;
103+
}
104+
105+
// always use our implementation
106+
super.setOnCheckedChangeListener(privateListener);
107+
}
108+
109+
@Override
110+
public Parcelable onSaveInstanceState() {
111+
Parcelable superState = super.onSaveInstanceState();
112+
113+
SavedState ss = new SavedState(superState);
114+
115+
ss.state = state;
116+
117+
return ss;
118+
}
119+
120+
@Override
121+
public void onRestoreInstanceState(Parcelable state) {
122+
this.restoring = true; // indicates that the ui is restoring its state
123+
SavedState ss = (SavedState) state;
124+
super.onRestoreInstanceState(ss.getSuperState());
125+
setState(ss.state);
126+
requestLayout();
127+
this.restoring = false;
128+
}
129+
130+
private void init() {
131+
state = UNKNOWN;
132+
updateBtn();
133+
}
134+
135+
public void addAction() {
136+
setOnCheckedChangeListener(this.privateListener);
137+
}
138+
139+
private void updateBtn() {
140+
int btnDrawable = R.drawable.ic_indeterminate_check_box_black_24dp;
141+
switch (state) {
142+
case UNKNOWN:
143+
btnDrawable = R.drawable.ic_indeterminate_check_box_black_24dp;
144+
break;
145+
case UNCHECKED:
146+
btnDrawable = R.drawable.ic_check_box_outline_blank_black_24dp;
147+
break;
148+
case CHECKED:
149+
btnDrawable = R.drawable.ic_check_box_black_24dp;
150+
break;
151+
}
152+
setButtonDrawable(btnDrawable);
153+
154+
}
155+
156+
static class SavedState extends BaseSavedState {
157+
int state;
158+
159+
SavedState(Parcelable superState) {
160+
super(superState);
161+
}
162+
163+
private SavedState(Parcel in) {
164+
super(in);
165+
state = in.readInt();
166+
}
167+
168+
@Override
169+
public void writeToParcel(Parcel out, int flags) {
170+
super.writeToParcel(out, flags);
171+
out.writeValue(state);
172+
}
173+
174+
@Override
175+
public String toString() {
176+
return "CheckboxTriState.SavedState{"
177+
+ Integer.toHexString(System.identityHashCode(this))
178+
+ " state=" + state + "}";
179+
}
180+
181+
@SuppressWarnings("hiding")
182+
public static final Parcelable.Creator<SavedState> CREATOR =
183+
new Parcelable.Creator<SavedState>() {
184+
@Override
185+
public SavedState createFromParcel(Parcel in) {
186+
return new SavedState(in);
187+
}
188+
189+
@Override
190+
public SavedState[] newArray(int size) {
191+
return new SavedState[size];
192+
}
193+
};
194+
}
195+
}

app/src/main/java/fr/free/nrw/commons/nearby/Label.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public enum Label {
4242
TEMPLE("Q44539", R.drawable.round_icon_church),
4343
UNKNOWN("?", R.drawable.round_icon_unknown);
4444

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

4848
static {
@@ -54,6 +54,7 @@ public enum Label {
5454
private final String text;
5555
@DrawableRes
5656
private final int icon;
57+
private boolean selected;
5758

5859
Label(String text, @DrawableRes int icon) {
5960
this.text = text;
@@ -65,6 +66,18 @@ public enum Label {
6566
this.icon = in.readInt();
6667
}
6768

69+
/**
70+
* Will be used for nearby filter, to determine if place type is selected or not
71+
* @param isSelected true if user selected the place type
72+
*/
73+
public void setSelected(boolean isSelected) {
74+
this.selected = isSelected;
75+
}
76+
77+
public boolean isSelected() {
78+
return selected;
79+
}
80+
6881
public String getText() {
6982
return text;
7083
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package fr.free.nrw.commons.nearby;
2+
3+
import com.mapbox.mapboxsdk.annotations.Marker;
4+
5+
/**
6+
* This class groups visual map item Marker with the reated data of displayed place and information
7+
* of bookmark
8+
*/
9+
public class MarkerPlaceGroup {
10+
private Marker marker; // Marker item from the map
11+
private boolean isBookmarked; // True if user bookmarked the place
12+
private Place place; // Place of the location displayed by the marker
13+
14+
public MarkerPlaceGroup(Marker marker, boolean isBookmarked, Place place) {
15+
this.marker = marker;
16+
this.isBookmarked = isBookmarked;
17+
this.place = place;
18+
}
19+
20+
public Marker getMarker() {
21+
return marker;
22+
}
23+
24+
public Place getPlace() {
25+
return place;
26+
}
27+
28+
public boolean getIsBookmarked() {
29+
return isBookmarked;
30+
}
31+
}

app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
77

88
import com.mapbox.mapboxsdk.annotations.IconFactory;
9+
import com.mapbox.mapboxsdk.annotations.Marker;
910

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

37+
public static List<MarkerPlaceGroup> markerLabelList = new ArrayList<>();
38+
public static Map<Boolean, Marker> markerExistsMap;
39+
public static Map<Boolean, Marker> markerNeedPicMap;
40+
3641
@Inject
3742
public NearbyController(NearbyPlaces nearbyPlaces) {
3843
this.nearbyPlaces = nearbyPlaces;
@@ -158,6 +163,8 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
158163
placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS));
159164

160165
VectorDrawableCompat vectorDrawable = null;
166+
VectorDrawableCompat vectorDrawableGreen = null;
167+
VectorDrawableCompat vectorDrawableGrey = null;
161168
try {
162169
vectorDrawable = VectorDrawableCompat.create(
163170
context.getResources(), R.drawable.ic_custom_bookmark_marker, context.getTheme()
@@ -191,13 +198,18 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
191198
vectorDrawable = null;
192199
try {
193200
vectorDrawable = VectorDrawableCompat.create(
194-
context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme()
195-
);
201+
context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme());
202+
vectorDrawableGreen = VectorDrawableCompat.create(
203+
context.getResources(), R.drawable.ic_custom_map_marker_green, context.getTheme());
204+
vectorDrawableGrey = VectorDrawableCompat.create(
205+
context.getResources(), R.drawable.ic_custom_map_marker_grey, context.getTheme());
196206
} catch (Resources.NotFoundException e) {
197207
// ignore when running tests.
198208
}
199209
if (vectorDrawable != null) {
200210
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
211+
Bitmap iconGreen = UiUtils.getBitmap(vectorDrawableGreen);
212+
Bitmap iconGrey = UiUtils.getBitmap(vectorDrawableGrey);
201213

202214
for (Place place : placeList) {
203215
String distance = formatDistanceBetween(curLatLng, place.location);
@@ -210,8 +222,21 @@ public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOpti
210222
place.location.getLatitude(),
211223
place.location.getLongitude()));
212224
nearbyBaseMarker.place(place);
213-
nearbyBaseMarker.icon(IconFactory.getInstance(context)
214-
.fromBitmap(icon));
225+
// Check if string is only spaces or empty, if so place doesn't have any picture
226+
if (!place.pic.trim().isEmpty()) {
227+
if (iconGreen != null) {
228+
nearbyBaseMarker.icon(IconFactory.getInstance(context)
229+
.fromBitmap(iconGreen));
230+
}
231+
} else if (!place.destroyed.trim().isEmpty()) { // Means place is destroyed
232+
if (iconGrey != null) {
233+
nearbyBaseMarker.icon(IconFactory.getInstance(context)
234+
.fromBitmap(iconGrey));
235+
}
236+
} else {
237+
nearbyBaseMarker.icon(IconFactory.getInstance(context)
238+
.fromBitmap(icon));
239+
}
215240

216241
baseMarkerOptions.add(nearbyBaseMarker);
217242
}

0 commit comments

Comments
 (0)