mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
* Add layout items for nearby filter list and filter item (cherry picked from commitb96f8a68ce) * Edit nearby query (cherry picked from commit1f3c8c8deb) * Add filter items to nearby parent fragment xml (cherry picked from commitd0beadd0e0) * Add icon for green marker (cherry picked from commitf65ca0387a) * Add layout util file to organize layout utilities (cherry picked from commit5c57939245) * Add pic parameter to nearby result item (cherry picked from commit86007e4bb6) * Add pic parameter to place type (cherry picked from commit25c358b67f) * Add green marker styling (cherry picked from commit929c92d887) * Inıt search layouts on Nearby parent (cherry picked from commit2ac38a1919) * Style green markers at nearby controller (cherry picked from commit3e08f39f8e) * Edit bookmark daos to include pic to tables (cherry picked from commit48d69edf3b) * TODO foc bookmark dao item but works now (cherry picked from commitf748399720) * Style nearby filter area (cherry picked from commit6267e488b0) * fix style of filter tab (cherry picked from commit5f843bf366) * Add nearby list adapter (cherry picked from commit56334afe03) * Current status, list size is working, visibility working, filter mechanism is ready (cherry picked from commit7d75c9c589) * Filtering works (cherry picked from commit8a13cf7728) * Filter function works (cherry picked from commit78368a2c0c) * Fix style issues (cherry picked from commit2204f70255) * Add divider to recyclerview (cherry picked from commitc8100b55d7) * Hide bottom sheets accordingly (cherry picked from commitc5deba8b0b) * Code cleanup (cherry picked from commitcf8f64f3cb) * 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
This commit is contained in:
parent
5c6ab3b253
commit
b3c11842f3
35 changed files with 1264 additions and 66 deletions
|
|
@ -6,6 +6,7 @@ import android.database.Cursor;
|
|||
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;
|
||||
|
|
@ -156,8 +157,11 @@ public class BookmarkLocationsDao {
|
|||
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) {
|
||||
|
|
@ -172,6 +176,7 @@ public class BookmarkLocationsDao {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -189,6 +194,7 @@ public class BookmarkLocationsDao {
|
|||
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 = {
|
||||
|
|
@ -202,7 +208,8 @@ public class BookmarkLocationsDao {
|
|||
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;
|
||||
|
|
@ -218,7 +225,8 @@ public class BookmarkLocationsDao {
|
|||
+ 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) {
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import android.graphics.Bitmap;
|
|||
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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -158,6 +163,8 @@ public class NearbyController {
|
|||
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()
|
||||
|
|
@ -191,13 +198,18 @@ public class NearbyController {
|
|||
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);
|
||||
|
|
@ -210,8 +222,21 @@ public class NearbyController {
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.LinearSmoothScroller;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
|
||||
public class NearbyFilterSearchRecyclerViewAdapter
|
||||
extends RecyclerView.Adapter<NearbyFilterSearchRecyclerViewAdapter.RecyclerViewHolder>
|
||||
implements Filterable {
|
||||
|
||||
private final LayoutInflater inflater;
|
||||
private Context context;
|
||||
private RecyclerView recyclerView;
|
||||
private ArrayList<Label> labels;
|
||||
private ArrayList<Label> displayedLabels;
|
||||
public ArrayList<Label> selectedLabels = new ArrayList<>();
|
||||
|
||||
private int state;
|
||||
|
||||
RecyclerView.SmoothScroller smoothScroller;
|
||||
|
||||
public NearbyFilterSearchRecyclerViewAdapter(Context context, ArrayList<Label> labels, RecyclerView recyclerView) {
|
||||
this.context = context;
|
||||
this.labels = labels;
|
||||
this.displayedLabels = labels;
|
||||
this.recyclerView = recyclerView;
|
||||
smoothScroller = new
|
||||
LinearSmoothScroller(context) {
|
||||
@Override protected int getVerticalSnapPreference() {
|
||||
return LinearSmoothScroller.SNAP_TO_START;
|
||||
}
|
||||
};
|
||||
inflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
public class RecyclerViewHolder extends RecyclerView.ViewHolder {
|
||||
public TextView placeTypeLabel;
|
||||
public ImageView placeTypeIcon;
|
||||
public LinearLayout placeTypeLayout;
|
||||
|
||||
public RecyclerViewHolder(View view) {
|
||||
super(view);
|
||||
placeTypeLabel = view.findViewById(R.id.place_text);
|
||||
placeTypeIcon = view.findViewById(R.id.place_icon);
|
||||
placeTypeLayout = view.findViewById(R.id.search_list_item);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = inflater.inflate(R.layout.nearby_search_list_item, parent, false);
|
||||
return new RecyclerViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {
|
||||
Label label = displayedLabels.get(position);
|
||||
holder.placeTypeIcon.setImageResource(label.getIcon());
|
||||
holder.placeTypeLabel.setText(label.toString());
|
||||
|
||||
holder.placeTypeLayout.setBackgroundColor(label.isSelected() ? ContextCompat.getColor(context, R.color.divider_grey) : Color.WHITE);
|
||||
holder.placeTypeLayout.setOnClickListener(view -> {
|
||||
NearbyParentFragmentPresenter.getInstance().setCheckboxUnknown();
|
||||
if (label.isSelected()) {
|
||||
selectedLabels.remove(label);
|
||||
} else {
|
||||
selectedLabels.add(label);
|
||||
displayedLabels.remove(label);
|
||||
displayedLabels.add(selectedLabels.size()-1, label);
|
||||
notifyDataSetChanged();
|
||||
smoothScroller.setTargetPosition(0);
|
||||
recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
|
||||
}
|
||||
label.setSelected(!label.isSelected());
|
||||
holder.placeTypeLayout.setBackgroundColor(label.isSelected() ? ContextCompat.getColor(context, R.color.divider_grey) : Color.WHITE);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(selectedLabels, 0, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return displayedLabels.get(position).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return displayedLabels.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter() {
|
||||
return new Filter() {
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
FilterResults results = new FilterResults();
|
||||
ArrayList<Label> filteredArrayList = new ArrayList<>();
|
||||
|
||||
if (labels == null) {
|
||||
labels = new ArrayList<>(displayedLabels);
|
||||
}
|
||||
|
||||
if (constraint == null || constraint.length() == 0) {
|
||||
// set the Original result to return
|
||||
results.count = labels.size();
|
||||
results.values = labels;
|
||||
} else {
|
||||
constraint = constraint.toString().toLowerCase();
|
||||
|
||||
for (Label label : labels) {
|
||||
String data = label.toString();
|
||||
if (data.toLowerCase().startsWith(constraint.toString())) {
|
||||
filteredArrayList.add(Label.fromText(label.getText()));
|
||||
}
|
||||
}
|
||||
|
||||
// set the Filtered result to return
|
||||
results.count = filteredArrayList.size();
|
||||
results.values = filteredArrayList;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void publishResults(CharSequence constraint, FilterResults results) {
|
||||
displayedLabels = (ArrayList<Label>) results.values; // has the filtered values
|
||||
notifyDataSetChanged(); // notifies the data with new filtered values
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setRecyclerViewAdapterItemsGreyedOut() {
|
||||
state = CheckBoxTriStates.UNCHECKED;
|
||||
for (Label label : labels) {
|
||||
label.setSelected(false);
|
||||
selectedLabels.remove(label);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setRecyclerViewAdapterAllSelected() {
|
||||
state = CheckBoxTriStates.CHECKED;
|
||||
for (Label label : labels) {
|
||||
label.setSelected(true);
|
||||
if (!selectedLabels.contains(label)) {
|
||||
selectedLabels.add(label);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setRecyclerViewAdapterNeutral() {
|
||||
state = CheckBoxTriStates.UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NearbyFilterState {
|
||||
private boolean existsSelected;
|
||||
private boolean needPhotoSelected;
|
||||
private int checkBoxTriState;
|
||||
private ArrayList<Label> selectedLabels;
|
||||
|
||||
private static NearbyFilterState nearbyFılterStateInstance;
|
||||
|
||||
/**
|
||||
* Define initial filter values here
|
||||
*/
|
||||
private NearbyFilterState() {
|
||||
existsSelected = false;
|
||||
needPhotoSelected = true;
|
||||
checkBoxTriState = -1; // Unknown
|
||||
selectedLabels = new ArrayList<>(); // Initially empty
|
||||
}
|
||||
|
||||
public static NearbyFilterState getInstance() {
|
||||
if (nearbyFılterStateInstance == null) {
|
||||
nearbyFılterStateInstance = new NearbyFilterState();
|
||||
}
|
||||
return nearbyFılterStateInstance;
|
||||
}
|
||||
|
||||
public static void setSelectedLabels(ArrayList<Label> selectedLabels) {
|
||||
getInstance().selectedLabels = selectedLabels;
|
||||
}
|
||||
|
||||
public static void setExistsSelected(boolean existsSelected) {
|
||||
getInstance().existsSelected = existsSelected;
|
||||
}
|
||||
|
||||
public static void setNeedPhotoSelected(boolean needPhotoSelected) {
|
||||
getInstance().needPhotoSelected = needPhotoSelected;
|
||||
}
|
||||
|
||||
public boolean isExistsSelected() {
|
||||
return existsSelected;
|
||||
}
|
||||
|
||||
public boolean isNeedPhotoSelected() {
|
||||
return needPhotoSelected;
|
||||
}
|
||||
|
||||
public int getCheckBoxTriState() {
|
||||
return checkBoxTriState;
|
||||
}
|
||||
|
||||
public ArrayList<Label> getSelectedLabels() {
|
||||
return selectedLabels;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ListView;
|
||||
|
||||
public class NearbyfilterSearchListView extends ListView {
|
||||
public NearbyfilterSearchListView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NearbyfilterSearchListView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NearbyfilterSearchListView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -23,18 +23,21 @@ public class Place implements Parcelable {
|
|||
private final String longDescription;
|
||||
public final LatLng location;
|
||||
private final String category;
|
||||
public final String pic;
|
||||
public final String destroyed;
|
||||
|
||||
public String distance;
|
||||
public final Sitelinks siteLinks;
|
||||
|
||||
|
||||
public Place(String name, Label label, String longDescription, LatLng location, String category, Sitelinks siteLinks) {
|
||||
this.name = name;
|
||||
public Place(String name, Label label, String longDescription, LatLng location, String category, Sitelinks siteLinks, String pic, String destroyed) { this.name = name;
|
||||
this.label = label;
|
||||
this.longDescription = longDescription;
|
||||
this.location = location;
|
||||
this.category = category;
|
||||
this.siteLinks = siteLinks;
|
||||
this.pic = (pic == null) ? "":pic;
|
||||
this.destroyed = (destroyed == null) ? "":destroyed;
|
||||
}
|
||||
|
||||
public Place(Parcel in) {
|
||||
|
|
@ -44,6 +47,10 @@ public class Place implements Parcelable {
|
|||
this.location = in.readParcelable(LatLng.class.getClassLoader());
|
||||
this.category = in.readString();
|
||||
this.siteLinks = in.readParcelable(Sitelinks.class.getClassLoader());
|
||||
String picString = in.readString();
|
||||
this.pic = (picString == null) ? "":picString;
|
||||
String destroyedString = in.readString();
|
||||
this.destroyed = (destroyedString == null) ? "":destroyedString;
|
||||
}
|
||||
|
||||
public static Place from(NearbyResultItem item) {
|
||||
|
|
@ -62,7 +69,9 @@ public class Place implements Parcelable {
|
|||
.setWikipediaLink(item.getWikipediaArticle().getValue())
|
||||
.setCommonsLink(item.getCommonsArticle().getValue())
|
||||
.setWikidataLink(item.getItem().getValue())
|
||||
.build());
|
||||
.build(),
|
||||
item.getPic().getValue(),
|
||||
item.getDestroyed().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -105,7 +114,7 @@ public class Place implements Parcelable {
|
|||
|
||||
/**
|
||||
* Extracts the entity id from the wikidata link
|
||||
* @return returns the entity id if wikidata link exists
|
||||
* @return returns the entity id if wikidata link destroyed
|
||||
*/
|
||||
@Nullable
|
||||
public String getWikiDataEntityId() {
|
||||
|
|
@ -173,6 +182,8 @@ public class Place implements Parcelable {
|
|||
", category='" + category + '\'' +
|
||||
", distance='" + distance + '\'' +
|
||||
", siteLinks='" + siteLinks.toString() + '\'' +
|
||||
", pic='" + pic + '\'' +
|
||||
", destroyed='" + destroyed + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
|||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.Label;
|
||||
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
|
|
@ -27,5 +28,9 @@ public interface NearbyMapContract {
|
|||
void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener);
|
||||
void centerMapToPlace(Place place, boolean isPortraitMode);
|
||||
void removeCurrentLocationMarker();
|
||||
List<NearbyBaseMarker> getBaseMarkerOptions();
|
||||
void filterMarkersByLabels(List<Label> labelList, boolean displayExists, boolean displayNeeds, boolean filterForPlaceState, boolean filterForAllNoneType);
|
||||
void filterOutAllMarkers();
|
||||
void displayAllMarkers();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import java.util.List;
|
|||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.nearby.Label;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
|
||||
public interface NearbyParentFragmentContract {
|
||||
|
|
@ -26,6 +27,7 @@ public interface NearbyParentFragmentContract {
|
|||
void animateFABs();
|
||||
void recenterMap(LatLng curLatLng);
|
||||
void hideBottomSheet();
|
||||
void hideBottomDetailsSheet();
|
||||
void displayBottomSheetWithInfo(Marker marker);
|
||||
void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener);
|
||||
void addSearchThisAreaButtonAction();
|
||||
|
|
@ -35,6 +37,11 @@ public interface NearbyParentFragmentContract {
|
|||
boolean isDetailsBottomSheetVisible();
|
||||
void setBottomSheetDetailsSmaller();
|
||||
boolean isSearchThisAreaButtonVisible();
|
||||
void setRecyclerViewAdapterAllSelected();
|
||||
void setRecyclerViewAdapterItemsGreyedOut();
|
||||
void setCheckBoxAction();
|
||||
void setCheckBoxState(int state);
|
||||
void setFilterState();
|
||||
}
|
||||
|
||||
interface NearbyListView {
|
||||
|
|
@ -49,6 +56,9 @@ public interface NearbyParentFragmentContract {
|
|||
void setActionListeners(JsonKvStore applicationKvStore);
|
||||
void backButtonClicked();
|
||||
MapboxMap.OnCameraMoveListener onCameraMove(MapboxMap mapboxMap);
|
||||
void filterByMarkerType(List<Label> selectedLabels, int state, boolean filterForPlaceState, boolean filterForAllNoneType);
|
||||
void searchViewGainedFocus();
|
||||
void setCheckboxUnknown();
|
||||
}
|
||||
|
||||
interface ViewsAreReadyCallback {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
|||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -36,6 +37,8 @@ import fr.free.nrw.commons.R;
|
|||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.Label;
|
||||
import fr.free.nrw.commons.nearby.MarkerPlaceGroup;
|
||||
import fr.free.nrw.commons.nearby.NearbyBaseMarker;
|
||||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.NearbyMarker;
|
||||
|
|
@ -75,6 +78,7 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
private MapView map;
|
||||
private Marker currentLocationMarker;
|
||||
private Polygon currentLocationPolygon;
|
||||
private List<NearbyBaseMarker> customBaseMarkerOptions;
|
||||
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
|
||||
|
|
@ -273,7 +277,7 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
, Marker selectedMarker
|
||||
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
|
||||
Timber.d("Updates map markers");
|
||||
List<NearbyBaseMarker> customBaseMarkerOptions = NearbyController
|
||||
customBaseMarkerOptions = NearbyController
|
||||
.loadAttractionsFromLocationToBaseMarkerOptions(latLng, // Curlatlang will be used to calculate distances
|
||||
placeList,
|
||||
getActivity(),
|
||||
|
|
@ -336,6 +340,101 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
mapboxMap.removePolygon(currentLocationPolygon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters markers based on selectedLabels and chips
|
||||
* @param selectedLabels label list that user clicked
|
||||
* @param displayExists chip for displaying only existing places
|
||||
* @param displayNeedsPhoto chip for displaying only places need photos
|
||||
* @param filterForPlaceState true if we filter places for place state
|
||||
* @param filterForAllNoneType true if we filter places with all none button
|
||||
*/
|
||||
@Override
|
||||
public void filterMarkersByLabels(List<Label> selectedLabels,
|
||||
boolean displayExists,
|
||||
boolean displayNeedsPhoto,
|
||||
boolean filterForPlaceState,
|
||||
boolean filterForAllNoneType) {
|
||||
|
||||
if (selectedLabels.size() == 0 && filterForPlaceState) { // If nothing is selected, display all
|
||||
greyOutAllMarkers();
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
if (displayExists && displayNeedsPhoto) {
|
||||
// Exists and needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty() && markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (displayExists && !displayNeedsPhoto) {
|
||||
// Exists and all included needs and doesn't needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && displayNeedsPhoto) {
|
||||
// All and only needs photo
|
||||
if (markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && !displayNeedsPhoto) {
|
||||
// all
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
|
||||
//updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else {
|
||||
// First greyed out all markers
|
||||
greyOutAllMarkers();
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
for (Label label : selectedLabels) {
|
||||
if (markerPlaceGroup.getPlace().getLabel().toString().equals(label.toString())) {
|
||||
|
||||
if (displayExists && displayNeedsPhoto) {
|
||||
// Exists and needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty() && markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (displayExists && !displayNeedsPhoto) {
|
||||
// Exists and all included needs and doesn't needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && displayNeedsPhoto) {
|
||||
// All and only needs photo
|
||||
if (markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && !displayNeedsPhoto) {
|
||||
// all
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greys out all markers
|
||||
*/
|
||||
@Override
|
||||
public void filterOutAllMarkers() {
|
||||
greyOutAllMarkers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all markers
|
||||
*/
|
||||
@Override
|
||||
public void displayAllMarkers() {
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NearbyBaseMarker> getBaseMarkerOptions() {
|
||||
return customBaseMarkerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds markers to map
|
||||
* @param baseMarkerList is markers will be added
|
||||
|
|
@ -346,7 +445,22 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
public void addNearbyMarkersToMapBoxMap(@Nullable List<NearbyBaseMarker> baseMarkerList
|
||||
, Marker selectedMarker
|
||||
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
|
||||
mapboxMap.addMarkers(baseMarkerList);
|
||||
List<Marker> markers = mapboxMap.addMarkers(baseMarkerList);
|
||||
NearbyController.markerExistsMap = new HashMap<Boolean, Marker>();
|
||||
NearbyController.markerNeedPicMap = new HashMap<Boolean, Marker>();
|
||||
|
||||
NearbyController.markerLabelList.clear();
|
||||
|
||||
for (int i = 0; i < baseMarkerList.size(); i++) {
|
||||
|
||||
NearbyBaseMarker nearbyBaseMarker = baseMarkerList.get(i);
|
||||
NearbyController.markerLabelList.add(
|
||||
new MarkerPlaceGroup(markers.get(i), bookmarkLocationDao.findBookmarkLocation(baseMarkerList.get(i).getPlace()), nearbyBaseMarker.getPlace()));
|
||||
//TODO: fix bookmark location
|
||||
NearbyController.markerExistsMap.put((baseMarkerList.get(i).getPlace().hasWikidataLink()), markers.get(i));
|
||||
NearbyController.markerNeedPicMap.put(((baseMarkerList.get(i).getPlace().pic == null) ? true : false), markers.get(i));
|
||||
}
|
||||
|
||||
map.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.addMarkers(baseMarkerList);
|
||||
setMapMarkerActions(selectedMarker, nearbyParentFragmentPresenter);
|
||||
|
|
@ -403,6 +517,14 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_bookmark_marker, getContext().getTheme()
|
||||
);
|
||||
} else if (!place.pic.trim().isEmpty()) {
|
||||
vectorDrawable = VectorDrawableCompat.create( // Means place has picture
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker_green, getContext().getTheme()
|
||||
);
|
||||
} else if (!place.destroyed.trim().isEmpty()) { // Means place is destroyed
|
||||
vectorDrawable = VectorDrawableCompat.create( // Means place has picture
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker_grey, getContext().getTheme()
|
||||
);
|
||||
} else {
|
||||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker, getContext().getTheme()
|
||||
|
|
@ -431,6 +553,22 @@ public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greys out all markers except current location marker
|
||||
*/
|
||||
public void greyOutAllMarkers() {
|
||||
VectorDrawableCompat vectorDrawable;
|
||||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_greyed_out_marker, getContext().getTheme());
|
||||
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
||||
for (Marker marker : mapboxMap.getMarkers()) {
|
||||
if (currentLocationMarker.getTitle() != marker.getTitle()) {
|
||||
marker.setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
|
||||
}
|
||||
}
|
||||
addCurrentLocationMarker(NearbyController.currentLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers the map in nearby fragment to a given place
|
||||
* @param place is new center of the map
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.content.Intent;
|
|||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
|
@ -19,6 +20,7 @@ import android.widget.FrameLayout;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
|
@ -26,10 +28,17 @@ import androidx.annotation.NonNull;
|
|||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.recyclerview.widget.DividerItemDecoration;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.chip.Chip;
|
||||
import com.google.android.material.chip.ChipGroup;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.jakewharton.rxbinding2.view.RxView;
|
||||
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
|
|
@ -39,6 +48,9 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
|
|||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
|
|
@ -54,12 +66,16 @@ import fr.free.nrw.commons.contributions.MainActivity;
|
|||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.nearby.CheckBoxTriStates;
|
||||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter;
|
||||
import fr.free.nrw.commons.nearby.NearbyFilterState;
|
||||
import fr.free.nrw.commons.nearby.NearbyMarker;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
import fr.free.nrw.commons.utils.FragmentUtils;
|
||||
import fr.free.nrw.commons.utils.LayoutUtils;
|
||||
import fr.free.nrw.commons.utils.NearbyFABUtils;
|
||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||
|
|
@ -73,6 +89,7 @@ import timber.log.Timber;
|
|||
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED;
|
||||
import static fr.free.nrw.commons.contributions.MainActivity.CONTRIBUTIONS_TAB_POSITION;
|
||||
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED;
|
||||
import static fr.free.nrw.commons.nearby.Label.TEXT_TO_DESCRIPTION;
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
||||
|
||||
|
||||
|
|
@ -106,6 +123,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
@BindView(R.id.container_sheet) FrameLayout frameLayout;
|
||||
@BindView(R.id.loading_nearby_list) ConstraintLayout loadingNearbyLayout;
|
||||
|
||||
@BindView(R.id.choice_chip_exists) Chip chipExists;
|
||||
@BindView(R.id.choice_chip_needs_photo) Chip chipNeedsPhoto;
|
||||
@BindView(R.id.choice_chip_group) ChipGroup choiceChipGroup;
|
||||
@BindView(R.id.search_view) SearchView searchView;
|
||||
@BindView(R.id.search_list_view) RecyclerView recyclerView;
|
||||
@BindView(R.id.nearby_filter_list) View nearbyFilterList;
|
||||
@BindView(R.id.checkbox_tri_states) CheckBoxTriStates checkBoxTriStates;
|
||||
|
||||
@Inject LocationServiceManager locationManager;
|
||||
@Inject NearbyController nearbyController;
|
||||
@Inject @Named("default_preferences") JsonKvStore applicationKvStore;
|
||||
|
|
@ -113,6 +138,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
@Inject ContributionController controller;
|
||||
@Inject WikidataEditListener wikidataEditListener;
|
||||
|
||||
private NearbyFilterSearchRecyclerViewAdapter nearbyFilterSearchRecyclerViewAdapter;
|
||||
|
||||
private BottomSheetBehavior bottomSheetListBehavior;
|
||||
private BottomSheetBehavior bottomSheetDetailsBehavior;
|
||||
private Animation rotate_backward;
|
||||
|
|
@ -178,6 +205,98 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
bottomSheetDetails.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void initNearbyFilter() {
|
||||
nearbyFilterList.setVisibility(View.GONE);
|
||||
|
||||
searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> {
|
||||
if (hasFocus) {
|
||||
nearbyParentFragmentPresenter.searchViewGainedFocus();
|
||||
nearbyFilterList.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
nearbyFilterList.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
|
||||
DividerItemDecoration.VERTICAL));
|
||||
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
|
||||
recyclerView.setLayoutManager(linearLayoutManager);
|
||||
|
||||
nearbyFilterSearchRecyclerViewAdapter = new NearbyFilterSearchRecyclerViewAdapter(getContext(),new ArrayList<>(TEXT_TO_DESCRIPTION.values()), recyclerView);
|
||||
nearbyFilterList.getLayoutParams().width = (int) LayoutUtils.getScreenWidth(getActivity(), 0.75);
|
||||
recyclerView.setAdapter(nearbyFilterSearchRecyclerViewAdapter);
|
||||
LayoutUtils.setLayoutHeightAllignedToWidth(1, nearbyFilterList);
|
||||
|
||||
compositeDisposable.add(RxSearchView.queryTextChanges(searchView)
|
||||
.takeUntil(RxView.detaches(searchView))
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe( query -> {
|
||||
((NearbyFilterSearchRecyclerViewAdapter) recyclerView.getAdapter()).getFilter().filter(query.toString());
|
||||
}));
|
||||
initFilterChips();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCheckBoxAction() {
|
||||
checkBoxTriStates.addAction();
|
||||
checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCheckBoxState(int state) {
|
||||
checkBoxTriStates.setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterState() {
|
||||
Log.d("deneme5","setfilterState");
|
||||
chipNeedsPhoto.setChecked(NearbyFilterState.getInstance().isNeedPhotoSelected());
|
||||
chipExists.setChecked(NearbyFilterState.getInstance().isExistsSelected());
|
||||
|
||||
if (NearbyController.currentLocation != null) {
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initFilterChips() {
|
||||
|
||||
chipNeedsPhoto.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (NearbyController.currentLocation != null) {
|
||||
checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN);
|
||||
if (isChecked) {
|
||||
NearbyFilterState.getInstance().setNeedPhotoSelected(true);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false);
|
||||
} else {
|
||||
NearbyFilterState.getInstance().setNeedPhotoSelected(false);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false);
|
||||
}
|
||||
} else {
|
||||
chipNeedsPhoto.setChecked(!isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chipExists.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (NearbyController.currentLocation != null) {
|
||||
checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN);
|
||||
if (isChecked) {
|
||||
NearbyFilterState.getInstance().setExistsSelected(true);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false);
|
||||
} else {
|
||||
NearbyFilterState.getInstance().setExistsSelected(false);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false);
|
||||
}
|
||||
} else {
|
||||
chipExists.setChecked(!isChecked);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how bottom sheets will act on click
|
||||
*/
|
||||
|
|
@ -385,6 +504,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
nearbyParentFragmentPresenter.nearbyFragmentsAreReady();
|
||||
initViews();
|
||||
nearbyParentFragmentPresenter.setActionListeners(applicationKvStore);
|
||||
initNearbyFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -483,6 +603,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
// showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
||||
setProgressBarVisibility(false);
|
||||
nearbyParentFragmentPresenter.lockUnlockNearby(false);
|
||||
setFilterState();
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
@ -509,6 +630,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
*/
|
||||
private void updateMapMarkers(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||
nearbyParentFragmentPresenter.updateMapMarkers(nearbyPlacesInfo, selectedMarker);
|
||||
setFilterState();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -518,6 +640,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
*/
|
||||
private void updateMapMarkersForCustomLocation(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||
nearbyParentFragmentPresenter.updateMapMarkersForCustomLocation(nearbyPlacesInfo, selectedMarker);
|
||||
setFilterState();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -563,6 +686,20 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecyclerViewAdapterAllSelected() {
|
||||
if (nearbyFilterSearchRecyclerViewAdapter != null && NearbyController.currentLocation != null) {
|
||||
nearbyFilterSearchRecyclerViewAdapter.setRecyclerViewAdapterAllSelected();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecyclerViewAdapterItemsGreyedOut() {
|
||||
if (nearbyFilterSearchRecyclerViewAdapter != null && NearbyController.currentLocation != null) {
|
||||
nearbyFilterSearchRecyclerViewAdapter.setRecyclerViewAdapterItemsGreyedOut();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressBarVisibility(boolean isVisible) {
|
||||
if (isVisible) {
|
||||
|
|
@ -729,6 +866,11 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
bottomSheetListBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideBottomDetailsSheet() {
|
||||
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayBottomSheetWithInfo(Marker marker) {
|
||||
this.selectedMarker = marker;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ public class NearbyResultItem {
|
|||
@SerializedName("class") private final ResultTuple className;
|
||||
@SerializedName("classLabel") private final ResultTuple classLabel;
|
||||
@SerializedName("commonsCategory") private final ResultTuple commonsCategory;
|
||||
@SerializedName("pic") private final ResultTuple pic;
|
||||
@SerializedName("destroyed") private final ResultTuple destroyed;
|
||||
|
||||
public NearbyResultItem(ResultTuple item,
|
||||
ResultTuple wikipediaArticle,
|
||||
|
|
@ -20,7 +22,9 @@ public class NearbyResultItem {
|
|||
ResultTuple label,
|
||||
ResultTuple icon, ResultTuple className,
|
||||
ResultTuple classLabel,
|
||||
ResultTuple commonsCategory) {
|
||||
ResultTuple commonsCategory,
|
||||
ResultTuple pic,
|
||||
ResultTuple destroyed) {
|
||||
this.item = item;
|
||||
this.wikipediaArticle = wikipediaArticle;
|
||||
this.commonsArticle = commonsArticle;
|
||||
|
|
@ -30,6 +34,8 @@ public class NearbyResultItem {
|
|||
this.className = className;
|
||||
this.classLabel = classLabel;
|
||||
this.commonsCategory = commonsCategory;
|
||||
this.pic = pic;
|
||||
this.destroyed = destroyed;
|
||||
}
|
||||
|
||||
public ResultTuple getItem() {
|
||||
|
|
@ -67,4 +73,10 @@ public class NearbyResultItem {
|
|||
public ResultTuple getCommonsCategory() {
|
||||
return commonsCategory == null ? new ResultTuple():commonsCategory;
|
||||
}
|
||||
public ResultTuple getPic() {
|
||||
return pic == null ? new ResultTuple():pic;
|
||||
}
|
||||
public ResultTuple getDestroyed() {
|
||||
return destroyed == null ? new ResultTuple(): destroyed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,16 @@ import android.view.View;
|
|||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.location.LocationUpdateListener;
|
||||
import fr.free.nrw.commons.nearby.CheckBoxTriStates;
|
||||
import fr.free.nrw.commons.nearby.Label;
|
||||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.NearbyFilterState;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyMapContract;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
|
||||
|
|
@ -22,6 +27,9 @@ import static fr.free.nrw.commons.location.LocationServiceManager.LocationChange
|
|||
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SLIGHTLY_CHANGED;
|
||||
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED;
|
||||
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.SEARCH_CUSTOM_AREA;
|
||||
import static fr.free.nrw.commons.nearby.CheckBoxTriStates.CHECKED;
|
||||
import static fr.free.nrw.commons.nearby.CheckBoxTriStates.UNCHECKED;
|
||||
import static fr.free.nrw.commons.nearby.CheckBoxTriStates.UNKNOWN;
|
||||
|
||||
public class NearbyParentFragmentPresenter
|
||||
implements NearbyParentFragmentContract.UserActions,
|
||||
|
|
@ -135,6 +143,7 @@ public class NearbyParentFragmentPresenter
|
|||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED, null);
|
||||
this.nearbyParentFragmentView.addSearchThisAreaButtonAction();
|
||||
this.nearbyMapFragmentView.addOnCameraMoveListener(onCameraMove(getMapboxMap()));
|
||||
nearbyParentFragmentView.setCheckBoxAction();
|
||||
mapInitialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +354,45 @@ public class NearbyParentFragmentPresenter
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filterByMarkerType(List<Label> selectedLabels, int state, boolean filterForPlaceState, boolean filterForAllNoneType) {
|
||||
if (filterForAllNoneType) { // Means we will set labels based on states
|
||||
switch (state) {
|
||||
case UNKNOWN:
|
||||
// Do nothing
|
||||
break;
|
||||
case UNCHECKED:
|
||||
nearbyMapFragmentView.filterOutAllMarkers();
|
||||
nearbyParentFragmentView.setRecyclerViewAdapterItemsGreyedOut();
|
||||
break;
|
||||
case CHECKED:
|
||||
nearbyMapFragmentView.displayAllMarkers();
|
||||
nearbyParentFragmentView.setRecyclerViewAdapterAllSelected();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nearbyMapFragmentView.filterMarkersByLabels(selectedLabels,
|
||||
NearbyFilterState.getInstance().isExistsSelected(),
|
||||
NearbyFilterState.getInstance().isNeedPhotoSelected(),
|
||||
filterForPlaceState, filterForAllNoneType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCheckboxUnknown() {
|
||||
nearbyParentFragmentView.setCheckBoxState(CheckBoxTriStates.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void searchViewGainedFocus() {
|
||||
if(nearbyParentFragmentView.isListBottomSheetExpanded()) {
|
||||
// Back should first hide the bottom sheet if it is expanded
|
||||
nearbyParentFragmentView.hideBottomSheet();
|
||||
} else if (nearbyParentFragmentView.isDetailsBottomSheetVisible()) {
|
||||
nearbyParentFragmentView.hideBottomDetailsSheet();
|
||||
}
|
||||
}
|
||||
|
||||
public View.OnClickListener onSearchThisAreaClicked() {
|
||||
return v -> {
|
||||
// Lock map operations during search this area operation
|
||||
|
|
|
|||
60
app/src/main/java/fr/free/nrw/commons/utils/LayoutUtils.java
Normal file
60
app/src/main/java/fr/free/nrw/commons/utils/LayoutUtils.java
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
public class LayoutUtils {
|
||||
|
||||
/**
|
||||
* Can be used for keeping aspect radios suggested by material guidelines. See:
|
||||
* https://material.io/design/layout/spacing-methods.html#containers-aspect-ratios
|
||||
* In some cases we don't know exact width, for such cases this method measures
|
||||
* width and sets height by multiplying the width with height.
|
||||
* @param rate Aspect ratios, ie 1 for 1:1. (width * rate = height)
|
||||
* @param view view to change height
|
||||
*/
|
||||
public static void setLayoutHeightAllignedToWidth(double rate, View view) {
|
||||
ViewTreeObserver vto = view.getViewTreeObserver();
|
||||
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
|
||||
layoutParams.height = (int) (view.getWidth() * rate);
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used for keeping aspect radios suggested by material guidelines. See:
|
||||
* https://material.io/design/layout/spacing-methods.html#containers-aspect-ratios
|
||||
* In some cases we don't know exact height, for such cases this method measures
|
||||
* height and sets width by multiplying the width with height.
|
||||
* @param rate Aspect ratios, ie 1 for 1:1. (height * rate = width)
|
||||
* @param view view to change width
|
||||
*/
|
||||
public static void setLayoutWidthAllignedToHeight(double rate, View view) {
|
||||
ViewTreeObserver vto = view.getViewTreeObserver();
|
||||
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
|
||||
layoutParams.width = (int) (view.getHeight() * rate);
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static double getScreenWidth(Context context, double rate) {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
return displayMetrics.widthPixels * rate;
|
||||
}
|
||||
}
|
||||
5
app/src/main/res/color/bg_chip_state.xml
Normal file
5
app/src/main/res/color/bg_chip_state.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/current_marker_stroke" android:state_checked="true" />
|
||||
<item android:color="@color/cardview_light_background" />
|
||||
</selector>
|
||||
9
app/src/main/res/drawable/ic_check_box_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_check_box_black_24dp.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/button_blue"
|
||||
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/button_blue"
|
||||
android:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
||||
23
app/src/main/res/drawable/ic_custom_greyed_out_marker.xml
Normal file
23
app/src/main/res/drawable/ic_custom_greyed_out_marker.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="28.0">
|
||||
<path
|
||||
android:fillAlpha="0.1"
|
||||
android:fillColor="#48000000"
|
||||
android:pathData="M6.072,22.223a6.031,3.672 0,1 0,12.062 0a6.031,3.672 0,1 0,-12.062 0z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#4D000000"
|
||||
android:pathData="M11.575,11.62C10.689,11.462 9.902,10.759 9.625,9.878 9.553,9.65 9.535,9.499 9.538,9.14c0.004,-0.397 0.019,-0.492 0.13,-0.787 0.236,-0.631 0.646,-1.099 1.212,-1.382 0.386,-0.193 0.709,-0.272 1.116,-0.272 0.676,0 1.263,0.247 1.744,0.734 0.355,0.359 0.541,0.682 0.657,1.136 0.327,1.278 -0.442,2.611 -1.723,2.987 -0.282,0.083 -0.817,0.114 -1.099,0.063z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#7CE4E0D9"
|
||||
android:pathData="M11.617,21.707C10.518,20.424 9.338,18.864 8.395,17.449 6.524,14.641 5.455,12.305 5.102,10.255 5.014,9.744 5.006,8.628 5.088,8.137 5.348,6.561 6.043,5.221 7.158,4.148 9.148,2.231 12.016,1.668 14.593,2.688c2.043,0.809 3.607,2.581 4.162,4.719 0.174,0.67 0.204,0.933 0.203,1.761 -0.001,0.81 -0.035,1.098 -0.22,1.857 -0.614,2.524 -2.571,5.977 -5.383,9.501 -0.645,0.809 -1.321,1.61 -1.358,1.61 -0.008,0 -0.179,-0.193 -0.381,-0.428zM12.617,11.603c0.783,-0.188 1.457,-0.795 1.738,-1.564 0.516,-1.415 -0.317,-2.962 -1.783,-3.312 -0.216,-0.052 -0.317,-0.059 -0.661,-0.047 -0.354,0.012 -0.441,0.025 -0.682,0.104 -0.673,0.221 -1.205,0.695 -1.506,1.344 -0.176,0.38 -0.218,0.584 -0.217,1.054 0.001,0.324 0.014,0.452 0.064,0.635 0.266,0.97 1.077,1.689 2.079,1.844 0.243,0.038 0.68,0.012 0.968,-0.057z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeColor="#54003B59"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
||||
23
app/src/main/res/drawable/ic_custom_map_marker_green.xml
Normal file
23
app/src/main/res/drawable/ic_custom_map_marker_green.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="28.0">
|
||||
<path
|
||||
android:fillAlpha="0.1"
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M6.072,22.223a6.031,3.672 0,1 0,12.062 0a6.031,3.672 0,1 0,-12.062 0z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M11.575,11.62C10.689,11.462 9.902,10.759 9.625,9.878 9.553,9.65 9.535,9.499 9.538,9.14c0.004,-0.397 0.019,-0.492 0.13,-0.787 0.236,-0.631 0.646,-1.099 1.212,-1.382 0.386,-0.193 0.709,-0.272 1.116,-0.272 0.676,0 1.263,0.247 1.744,0.734 0.355,0.359 0.541,0.682 0.657,1.136 0.327,1.278 -0.442,2.611 -1.723,2.987 -0.282,0.083 -0.817,0.114 -1.099,0.063z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#4CAF50"
|
||||
android:pathData="M11.617,21.707C10.518,20.424 9.338,18.864 8.395,17.449 6.524,14.641 5.455,12.305 5.102,10.255 5.014,9.744 5.006,8.628 5.088,8.137 5.348,6.561 6.043,5.221 7.158,4.148 9.148,2.231 12.016,1.668 14.593,2.688c2.043,0.809 3.607,2.581 4.162,4.719 0.174,0.67 0.204,0.933 0.203,1.761 -0.001,0.81 -0.035,1.098 -0.22,1.857 -0.614,2.524 -2.571,5.977 -5.383,9.501 -0.645,0.809 -1.321,1.61 -1.358,1.61 -0.008,0 -0.179,-0.193 -0.381,-0.428zM12.617,11.603c0.783,-0.188 1.457,-0.795 1.738,-1.564 0.516,-1.415 -0.317,-2.962 -1.783,-3.312 -0.216,-0.052 -0.317,-0.059 -0.661,-0.047 -0.354,0.012 -0.441,0.025 -0.682,0.104 -0.673,0.221 -1.205,0.695 -1.506,1.344 -0.176,0.38 -0.218,0.584 -0.217,1.054 0.001,0.324 0.014,0.452 0.064,0.635 0.266,0.97 1.077,1.689 2.079,1.844 0.243,0.038 0.68,0.012 0.968,-0.057z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeColor="#003b59"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
||||
23
app/src/main/res/drawable/ic_custom_map_marker_grey.xml
Normal file
23
app/src/main/res/drawable/ic_custom_map_marker_grey.xml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="28dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="28.0">
|
||||
<path
|
||||
android:fillAlpha="0.1"
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M6.072,22.223a6.031,3.672 0,1 0,12.062 0a6.031,3.672 0,1 0,-12.062 0z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M11.575,11.62C10.689,11.462 9.902,10.759 9.625,9.878 9.553,9.65 9.535,9.499 9.538,9.14c0.004,-0.397 0.019,-0.492 0.13,-0.787 0.236,-0.631 0.646,-1.099 1.212,-1.382 0.386,-0.193 0.709,-0.272 1.116,-0.272 0.676,0 1.263,0.247 1.744,0.734 0.355,0.359 0.541,0.682 0.657,1.136 0.327,1.278 -0.442,2.611 -1.723,2.987 -0.282,0.083 -0.817,0.114 -1.099,0.063z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:fillAlpha="1"
|
||||
android:fillColor="#454547"
|
||||
android:pathData="M11.617,21.707C10.518,20.424 9.338,18.864 8.395,17.449 6.524,14.641 5.455,12.305 5.102,10.255 5.014,9.744 5.006,8.628 5.088,8.137 5.348,6.561 6.043,5.221 7.158,4.148 9.148,2.231 12.016,1.668 14.593,2.688c2.043,0.809 3.607,2.581 4.162,4.719 0.174,0.67 0.204,0.933 0.203,1.761 -0.001,0.81 -0.035,1.098 -0.22,1.857 -0.614,2.524 -2.571,5.977 -5.383,9.501 -0.645,0.809 -1.321,1.61 -1.358,1.61 -0.008,0 -0.179,-0.193 -0.381,-0.428zM12.617,11.603c0.783,-0.188 1.457,-0.795 1.738,-1.564 0.516,-1.415 -0.317,-2.962 -1.783,-3.312 -0.216,-0.052 -0.317,-0.059 -0.661,-0.047 -0.354,0.012 -0.441,0.025 -0.682,0.104 -0.673,0.221 -1.205,0.695 -1.506,1.344 -0.176,0.38 -0.218,0.584 -0.217,1.054 0.001,0.324 0.014,0.452 0.064,0.635 0.266,0.97 1.077,1.689 2.079,1.844 0.243,0.038 0.68,0.012 0.968,-0.057z"
|
||||
android:strokeAlpha="1"
|
||||
android:strokeColor="#003b59"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="@color/button_blue"
|
||||
android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM17,13L7,13v-2h10v2z"/>
|
||||
</vector>
|
||||
42
app/src/main/res/layout/filter_chip_view.xml
Normal file
42
app/src/main/res/layout/filter_chip_view.xml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<LinearLayout android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="center_vertical"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="15dp"
|
||||
android:text="@string/place_state"
|
||||
android:textColor="@color/white"/>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/choice_chip_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:theme="@style/Theme.MaterialComponents.Light"
|
||||
app:singleSelection="false">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/choice_chip_exists"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:chipBackgroundColor="@color/bg_chip_state"
|
||||
android:text="@string/place_state_exists"/>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/choice_chip_needs_photo"
|
||||
style="@style/Widget.MaterialComponents.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:chipBackgroundColor="@color/bg_chip_state"
|
||||
android:text="@string/place_state_needs_photo"/>
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
|
||||
</LinearLayout>
|
||||
24
app/src/main/res/layout/filter_search_view_layout.xml
Normal file
24
app/src/main/res/layout/filter_search_view_layout.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<LinearLayout android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/search_view_layout"
|
||||
android:paddingVertical="15dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingStart="15dp"
|
||||
android:text="@string/place_type"
|
||||
android:textColor="@color/white"/>
|
||||
|
||||
<SearchView
|
||||
android:id="@+id/search_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:tint="@color/white"
|
||||
android:queryHint="@string/nearby_search_hint"
|
||||
android:searchIcon="@drawable/ic_search_white_24dp">
|
||||
</SearchView>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -8,18 +8,47 @@
|
|||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/status_bar_blue">
|
||||
android:background="@color/status_bar_blue"
|
||||
android:id="@+id/map_layout">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:focusableInTouchMode="true"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<include
|
||||
layout="@layout/nearby_filter_all_items"
|
||||
android:id="@+id/nearby_filter"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
<include layout="@layout/nearby_filter_list"
|
||||
android:id="@+id/nearby_filter_list"
|
||||
android:layout_below="@id/nearby_filter"
|
||||
android:layout_height="160dp"
|
||||
android:layout_width="160dp"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/nearby_filter"/>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/search_this_area_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@color/white"
|
||||
android:padding="8dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/search_this_area"
|
||||
android:textColor="@color/status_bar_blue"
|
||||
android:visibility="gone"
|
||||
app:elevation="6dp"
|
||||
android:layout_below="@id/nearby_filter"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/transparentView"
|
||||
|
|
@ -37,9 +66,9 @@
|
|||
android:id="@+id/fab_recenter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/toolbar"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/nearby_filter"
|
||||
android:clickable="true"
|
||||
android:visibility="visible"
|
||||
app:backgroundTint="@color/main_background_light"
|
||||
|
|
@ -49,7 +78,6 @@
|
|||
app:srcCompat="@drawable/ic_my_location_black_24dp"
|
||||
app:useCompatPadding="true" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<include layout="@layout/bottom_sheet_nearby" />
|
||||
|
|
@ -58,21 +86,6 @@
|
|||
android:id="@+id/bottom_sheet_details"
|
||||
layout="@layout/bottom_sheet_details" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/search_this_area_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@color/white"
|
||||
android:padding="8dp"
|
||||
android:singleLine="true"
|
||||
android:text="@string/search_this_area"
|
||||
android:textColor="@color/status_bar_blue"
|
||||
android:visibility="gone"
|
||||
app:elevation="6dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/map_progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
22
app/src/main/res/layout/nearby_filter_all_items.xml
Normal file
22
app/src/main/res/layout/nearby_filter_all_items.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:orientation="vertical"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<include
|
||||
android:id="@+id/chip_view"
|
||||
layout="@layout/filter_chip_view"
|
||||
android:background="@color/deleteRed"
|
||||
/>
|
||||
|
||||
<include android:id="@+id/search_view_layout" layout="@layout/filter_search_view_layout" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/search_view_layout"
|
||||
android:background="@color/status_bar_blue">
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
31
app/src/main/res/layout/nearby_filter_list.xml
Normal file
31
app/src/main/res/layout/nearby_filter_list.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/nearby_filter_list_layout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:elevation="8dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<fr.free.nrw.commons.nearby.CheckBoxTriStates
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/checkbox_tri_states"
|
||||
android:layout_margin="10dp"
|
||||
android:text="All"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@android:color/darker_gray"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/search_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="10dp"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
21
app/src/main/res/layout/nearby_search_list_item.xml
Normal file
21
app/src/main/res/layout/nearby_search_list_item.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_list_item"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="25dp"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/place_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</ImageView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/place_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
</TextView>
|
||||
</LinearLayout>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* Cblair91
|
||||
-->
|
||||
<resources>
|
||||
<string name="crash_dialog_title">Commons has crashed</string>
|
||||
<string name="crash_dialog_text">Oops. Something went wrong!</string>
|
||||
<string name="crash_dialog_comment_prompt">Tell us what you were doing, then share it via email to us. Will help us fix it!</string>
|
||||
<string name="crash_dialog_ok_toast">Thank you!</string>
|
||||
</resources>
|
||||
|
|
@ -380,7 +380,7 @@
|
|||
<string name="next">ದುಂಬುದ</string>
|
||||
<string name="previous">ಪಿರವುದ</string>
|
||||
<string name="submit">ಒಪ್ಪಿಸಾಲೆ</string>
|
||||
<string name="upload_title_duplicate">ಕಡತಪುದರ್ %1$s ದ ಒಂಜಿ ಕಡತ ಉಂಡು. ಈರ್ ಖಂಡಿತಾ ದುಂಬು ಪೋವರೆ ಬಯಕುವರಾ?\nA file with the file name exists. Are you sure you want to proceed?</string>
|
||||
<string name="upload_title_duplicate">ಕಡತಪುದರ್ %1$s ದ ಒಂಜಿ ಕಡತ ಉಂಡು. ಈರ್ ಖಂಡಿತಾ ದುಂಬು ಪೋವರೆ ಬಯಕುವರಾ?\nA file with the file name destroyed. Are you sure you want to proceed?</string>
|
||||
<string name="map_application_missing">ಹೊಂದುನ ನಕಾಶೆ ಪರಿಕರನ ಇರೆನ ಸಲಕರಣೆಡ್ ತಿಕ್ಕುಜಿ. ಈ ಗುಣಧರ್ಮನ್ ಬಳಸರೆ ದಯಮಲ್ತ್ ಒಂಜಿ ನಕಾಶೆ ಪರಿಕರನ ತಾಪನೆ ಮಲ್ಪುಲೆ.</string>
|
||||
<plurals name="upload_count_title">
|
||||
<item quantity="other">ಒಂಜಿ=%1$d ಮಿತೇರಾಯಿನ</item>
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Authors:
|
||||
* Ерней
|
||||
-->
|
||||
<resources>
|
||||
<string name="crash_dialog_ok_toast">Рәхмәт!</string>
|
||||
</resources>
|
||||
|
|
@ -172,7 +172,7 @@
|
|||
<string name="title_activity_nearby">Nearby Places</string>
|
||||
<string name="no_nearby">No nearby places found</string>
|
||||
<string name="warning">Warning</string>
|
||||
<string name="upload_image_duplicate">This file already exists on Commons. Are you sure you want to proceed?</string>
|
||||
<string name="upload_image_duplicate">This file already destroyed on Commons. Are you sure you want to proceed?</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="media_detail_title">Title</string>
|
||||
|
|
@ -410,7 +410,7 @@
|
|||
<string name="next">Next</string>
|
||||
<string name="previous">Previous</string>
|
||||
<string name="submit">Submit</string>
|
||||
<string name="upload_title_duplicate" formatted="true">A file with the file name %1$s exists. Are you sure you want to proceed?</string>
|
||||
<string name="upload_title_duplicate" formatted="true">A file with the file name %1$s destroyed. Are you sure you want to proceed?</string>
|
||||
<string name="map_application_missing">No compatible map application could be found on your device. Please install a map application to use this feature.</string>
|
||||
<plurals name="upload_count_title">
|
||||
<item quantity="one">%1$d Upload</item>
|
||||
|
|
@ -582,5 +582,10 @@ Upload your first media by tapping on the add button.</string>
|
|||
<string name="text_copy">Text copied to clipboard</string>
|
||||
<string name="notification_mark_read">Notification marked as read</string>
|
||||
<string name="some_error">There was some error!</string>
|
||||
<string name="place_state">Place state:</string>
|
||||
<string name="place_state_exists">Exists</string>
|
||||
<string name="place_state_needs_photo">Needs Photo</string>
|
||||
<string name="place_type">Place type:</string>
|
||||
<string name="nearby_search_hint">Bridge, museum, hotel etc.</string>
|
||||
<string name="you_must_reset_your_passsword">Something went wrong with login, you must reset your password !!</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ SELECT
|
|||
?wikipediaArticle
|
||||
?commonsArticle
|
||||
(SAMPLE(?commonsCategory) as ?commonsCategory)
|
||||
(SAMPLE(?pic) as ?pic)
|
||||
(SAMPLE(?destroyed) as ?destroyed)
|
||||
WHERE {
|
||||
# Around given location...
|
||||
SERVICE wikibase:around {
|
||||
|
|
@ -16,9 +18,6 @@ SELECT
|
|||
bd:serviceParam wikibase:radius "${RAD}" . # Radius in kilometers.
|
||||
}
|
||||
|
||||
# ... and without an image.
|
||||
MINUS {?item wdt:P18 []}
|
||||
|
||||
# Get the label in the preferred language of the user, or any other language if no label is available in that language.
|
||||
OPTIONAL {?item rdfs:label ?itemLabelPreferredLanguage. FILTER (lang(?itemLabelPreferredLanguage) = "${LANG}")}
|
||||
OPTIONAL {?item rdfs:label ?itemLabelAnyLanguage}
|
||||
|
|
@ -26,6 +25,12 @@ SELECT
|
|||
# Get Commons category (P373)
|
||||
OPTIONAL { ?item wdt:P373 ?commonsCategory. }
|
||||
|
||||
# Get (P18)
|
||||
OPTIONAL { ?item wdt:P18 ?pic. }
|
||||
|
||||
# Get (P576)
|
||||
OPTIONAL { ?item wdt:P576 ?destroyed. }
|
||||
|
||||
# Get the class label in the preferred language of the user, or any other language if no label is available in that language.
|
||||
OPTIONAL {
|
||||
?item p:P31/ps:P31 ?classId.
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class BookMarkLocationDaoTest {
|
|||
|
||||
|
||||
examplePlaceBookmark = Place("placeName", exampleLabel, "placeDescription"
|
||||
, exampleLocation, "placeCategory", builder.build())
|
||||
, exampleLocation, "placeCategory", builder.build(),"picName","placeDestroyed")
|
||||
testObject = BookmarkLocationsDao { client }
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ class BookMarkLocationDaoTest {
|
|||
assertTrue(testObject.updateBookmarkLocation(examplePlaceBookmark))
|
||||
verify(client).insert(eq(BASE_URI), captor.capture())
|
||||
captor.firstValue.let { cv ->
|
||||
assertEquals(10, cv.size())
|
||||
assertEquals(11, cv.size())
|
||||
assertEquals(examplePlaceBookmark.name, cv.getAsString(COLUMN_NAME))
|
||||
assertEquals(examplePlaceBookmark.longDescription, cv.getAsString(COLUMN_DESCRIPTION))
|
||||
assertEquals(examplePlaceBookmark.label.text, cv.getAsString(COLUMN_LABEL_TEXT))
|
||||
|
|
@ -156,6 +156,7 @@ class BookMarkLocationDaoTest {
|
|||
assertEquals(examplePlaceBookmark.siteLinks.wikipediaLink.toString(), cv.getAsString(COLUMN_WIKIPEDIA_LINK))
|
||||
assertEquals(examplePlaceBookmark.siteLinks.wikidataLink.toString(), cv.getAsString(COLUMN_WIKIDATA_LINK))
|
||||
assertEquals(examplePlaceBookmark.siteLinks.commonsLink.toString(), cv.getAsString(COLUMN_COMMONS_LINK))
|
||||
assertEquals(examplePlaceBookmark.pic.toString(), cv.getAsString(COLUMN_PIC))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue