diff --git a/OsmAnd/res/layout/auto_complete_suggestion.xml b/OsmAnd/res/layout/auto_complete_suggestion.xml new file mode 100644 index 0000000000..93895cc581 --- /dev/null +++ b/OsmAnd/res/layout/auto_complete_suggestion.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/list_item_auto_complete_text_view.xml b/OsmAnd/res/layout/list_item_auto_complete_text_view.xml index efe8667732..6e84efa2ba 100644 --- a/OsmAnd/res/layout/list_item_auto_complete_text_view.xml +++ b/OsmAnd/res/layout/list_item_auto_complete_text_view.xml @@ -26,6 +26,30 @@ tools:text="Username" /> + + + + + + + + Wrong user name! To From View images added in a certain period. diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 033698c04d..54dba0d14d 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -3,10 +3,8 @@ package net.osmand.plus; import android.app.Activity; import android.app.DatePickerDialog; import android.content.Intent; -import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Build; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.support.annotation.IdRes; @@ -15,7 +13,6 @@ import android.support.v4.app.FragmentActivity; import android.support.v7.widget.AppCompatImageView; import android.text.Editable; import android.text.TextWatcher; -import android.util.TypedValue; import android.view.ContextThemeWrapper; import android.view.View; import android.view.ViewGroup; @@ -37,6 +34,7 @@ import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.actions.AppModeDialog; import net.osmand.plus.dialogs.ConfigureMapMenu; import net.osmand.plus.dialogs.HelpArticleDialogFragment; +import net.osmand.plus.mapillary.MapillaryAutoCompleteAdapter; import org.apache.commons.logging.Log; @@ -44,7 +42,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.Comparator; import java.util.Date; import java.util.LinkedHashSet; import java.util.List; @@ -356,36 +353,11 @@ public class ContextMenuAdapter { final View autoCompleteTextView = convertView.findViewById(R.id.auto_complete_text_view); if (autoCompleteTextView != null) { - AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView; - final ArrayAdapter adapter; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - adapter = new ArrayAdapter<>(getContext(), R.layout.list_textview, new String[]{"username1", "name1", "user1"}); - } else { - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = getContext().getTheme(); - theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true); - final int textColor = typedValue.data; - - adapter = new ArrayAdapter(getContext(), R.layout.list_textview, new String[]{"username1", "name1", "user1"}) { - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final View view = super.getView(position, convertView, parent); - ((TextView) view.findViewById(R.id.textView)).setTextColor(textColor); - return view; - } - }; - } - adapter.sort(new Comparator() { - @Override - public int compare(String first, String second) { - return first.compareTo(second); - } - }); - textView.setAdapter(adapter); + final AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView; + textView.setAdapter(new MapillaryAutoCompleteAdapter(getContext(), R.layout.auto_complete_suggestion, app)); String selectedUsername = app.getSettings().MAPILLARY_FILTER_USERNAME.get(); - if (!selectedUsername.equals("")) { + if (!selectedUsername.equals("") && app.getSettings().USE_MAPILLARY_FILTER.get()) { textView.setText(selectedUsername); textView.setSelection(selectedUsername.length()); } @@ -398,20 +370,25 @@ public class ContextMenuAdapter { @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { - + ((View)textView.getParent().getParent()).findViewById(R.id.warning_linear_layout).setVisibility(View.GONE); } @Override public void afterTextChanged(Editable editable) { - app.getSettings().MAPILLARY_FILTER_USERNAME.set(editable.toString()); + } }); + + ImageView imageView = (ImageView) ((View) textView.getParent().getParent()).findViewById(R.id.warning_image_view); + imageView.setImageDrawable(mIconsCache.getPaintedIcon(R.drawable.ic_small_warning, + app.getResources().getColor(R.color.color_warning))); } final View dateFromEditText = convertView.findViewById(R.id.date_from_edit_text); if (dateFromEditText != null) { final EditText dateFrom = (EditText) dateFromEditText; final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); + final OsmandSettings settings = app.getSettings(); final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { @Override @@ -421,7 +398,7 @@ public class ContextMenuAdapter { from.set(Calendar.MONTH, monthOfYear); from.set(Calendar.DAY_OF_MONTH, dayOfMonth); dateFrom.setText(dateFormat.format(from.getTime())); - app.getSettings().MAPILLARY_FILTER_FROM_DATE.set(from.getTimeInMillis()); + settings.MAPILLARY_FILTER_FROM_DATE.set(from.getTimeInMillis()); } }; @@ -436,9 +413,11 @@ public class ContextMenuAdapter { } }); - long from = app.getSettings().MAPILLARY_FILTER_FROM_DATE.get(); - if (from != 0) { - dateFrom.setText(dateFormat.format(new Date(from))); + if (settings.USE_MAPILLARY_FILTER.get()) { + long from = settings.MAPILLARY_FILTER_FROM_DATE.get(); + if (from != 0) { + dateFrom.setText(dateFormat.format(new Date(from))); + } } dateFrom.setCompoundDrawablesWithIntrinsicBounds(null, null, mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null); @@ -448,6 +427,7 @@ public class ContextMenuAdapter { if (dateToEditText != null) { final EditText dateTo = (EditText) dateToEditText; final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); + final OsmandSettings settings = app.getSettings(); final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { @Override @@ -457,7 +437,7 @@ public class ContextMenuAdapter { to.set(Calendar.MONTH, monthOfYear); to.set(Calendar.DAY_OF_MONTH, dayOfMonth); dateTo.setText(dateFormat.format(to.getTime())); - app.getSettings().MAPILLARY_FILTER_TO_DATE.set(to.getTimeInMillis()); + settings.MAPILLARY_FILTER_TO_DATE.set(to.getTimeInMillis()); } }; @@ -472,9 +452,11 @@ public class ContextMenuAdapter { } }); - long to = app.getSettings().MAPILLARY_FILTER_TO_DATE.get(); - if (to != 0) { - dateTo.setText(dateFormat.format(new Date(to))); + if (settings.USE_MAPILLARY_FILTER.get()) { + long to = settings.MAPILLARY_FILTER_TO_DATE.get(); + if (to != 0) { + dateTo.setText(dateFormat.format(new Date(to))); + } } dateTo.setCompoundDrawablesWithIntrinsicBounds(null, null, mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null); @@ -492,11 +474,11 @@ public class ContextMenuAdapter { String dateTo = ((EditText) list.findViewById(R.id.date_to_edit_text)).getText().toString(); OsmandSettings settings = app.getSettings(); - if (!username.equals("") || !dateFrom.equals("") || !dateTo.equals("")) { + if (!settings.MAPILLARY_FILTER_USERNAME.get().equals("") || !dateFrom.equals("") || !dateTo.equals("")) { settings.USE_MAPILLARY_FILTER.set(true); } - if (username.equals("")) { - settings.MAPILLARY_FILTER_USERNAME.set(""); + if (!username.equals("") && settings.MAPILLARY_FILTER_USERNAME.get().equals("")) { + list.findViewById(R.id.warning_linear_layout).setVisibility(View.VISIBLE); } if (dateFrom.equals("")) { settings.MAPILLARY_FILTER_FROM_DATE.set(0L); @@ -522,6 +504,7 @@ public class ContextMenuAdapter { ((EditText) list.findViewById(R.id.date_to_edit_text)).setText(""); settings.USE_MAPILLARY_FILTER.set(false); + settings.MAPILLARY_FILTER_USER_KEY.set(""); settings.MAPILLARY_FILTER_USERNAME.set(""); settings.MAPILLARY_FILTER_FROM_DATE.set(0L); settings.MAPILLARY_FILTER_TO_DATE.set(0L); diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java index 11807c3ab4..069a55e43a 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java @@ -706,6 +706,7 @@ public class OsmandSettings { public final CommonPreference RULER_MODE = new EnumIntPreference<>("ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); public final CommonPreference USE_MAPILLARY_FILTER = new BooleanPreference("use_mapillary_filters", false).makeGlobal(); + public final CommonPreference MAPILLARY_FILTER_USER_KEY = new StringPreference("mapillary_filter_user_key", "").makeGlobal(); public final CommonPreference MAPILLARY_FILTER_USERNAME = new StringPreference("mapillary_filter_username", "").makeGlobal(); public final CommonPreference MAPILLARY_FILTER_FROM_DATE = new LongPreference("mapillary_filter_from_date", 0).makeGlobal(); public final CommonPreference MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal(); diff --git a/OsmAnd/src/net/osmand/plus/mapillary/MapillaryAutoCompleteAdapter.java b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryAutoCompleteAdapter.java new file mode 100644 index 0000000000..881de2fb44 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/mapillary/MapillaryAutoCompleteAdapter.java @@ -0,0 +1,181 @@ +package net.osmand.plus.mapillary; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Build; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; +import android.util.Pair; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.ImageView; +import android.widget.TextView; + +import net.osmand.osm.io.NetworkUtils; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; + +public class MapillaryAutoCompleteAdapter extends ArrayAdapter implements Filterable { + + private static final String TAG = MapillaryAutoCompleteAdapter.class.getSimpleName(); + private ArrayList names; + private OsmandApplication app; + private boolean wrong; + + public MapillaryAutoCompleteAdapter(@NonNull Context context, @LayoutRes int resource, OsmandApplication app) { + super(context, resource); + names = new ArrayList<>(); + this.app = app; + } + + @Override + public int getCount() { + return names.size(); + } + + @Nullable + @Override + public String getItem(int position) { + return names.get(position); + } + + @NonNull + @Override + public Filter getFilter() { + return new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + FilterResults filterResults = new FilterResults(); + if (constraint != null) { + try { + Pair user = new GetMapillaryUserAsyncTask().execute(constraint.toString()).get(); + names.clear(); + OsmandSettings settings = app.getSettings(); + if (!settings.isInternetConnectionAvailable()) { + names.add(app.getResources().getString(R.string.no_inet_connection)); + wrong = true; + } else if (user != null) { + settings.MAPILLARY_FILTER_USER_KEY.set(user.first); + settings.MAPILLARY_FILTER_USERNAME.set(user.second); + names.add(user.second); + wrong = false; + } else { + settings.MAPILLARY_FILTER_USER_KEY.set(""); + settings.MAPILLARY_FILTER_USERNAME.set(""); + names.add(getContext().getResources().getString(R.string.wrong_user_name)); + wrong = true; + } + } catch (InterruptedException e) { + Log.e(TAG, e.toString()); + } catch (ExecutionException e) { + Log.e(TAG, e.toString()); + } + filterResults.values = names; + filterResults.count = names.size(); + } + + return filterResults; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + if (results != null) { + notifyDataSetChanged(); + } else { + notifyDataSetInvalidated(); + } + } + }; + } + + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(getContext()); + final View view = inflater.inflate(R.layout.auto_complete_suggestion, parent, false); + TextView nameTv = (TextView) view.findViewById(R.id.title); + ImageView iconIv = (ImageView) view.findViewById(R.id.icon); + + nameTv.setText(names.get(position)); + if (wrong) { + Drawable icon = app.getIconsCache().getPaintedIcon(R.drawable.ic_warning, app.getResources().getColor(R.color.color_warning)); + iconIv.setImageDrawable(icon); + iconIv.setVisibility(View.VISIBLE); + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = getContext().getTheme(); + theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true); + nameTv.setTextColor(typedValue.data); + } + + return view; + } + + private class GetMapillaryUserAsyncTask extends AsyncTask> { + + private final String TAG = GetMapillaryUserAsyncTask.class.getSimpleName(); + private static final String DOWNLOAD_PATH = "https://a.mapillary.com/v3/users?usernames=%s&client_id=%s"; + private static final String CLIENT_ID = "LXJVNHlDOGdMSVgxZG5mVzlHQ3ZqQTo0NjE5OWRiN2EzNTFkNDg4"; + + @Override + protected Pair doInBackground(String... params) { + try { + URL url = new URL(String.format(DOWNLOAD_PATH, params[0], CLIENT_ID)); + URLConnection conn = NetworkUtils.getHttpURLConnection(url); + + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + StringBuilder json = new StringBuilder(1024); + String tmp; + + while ((tmp = reader.readLine()) != null) { + json.append(tmp).append("\n"); + } + reader.close(); + + JSONArray data = new JSONArray(json.toString()); + + if (data.length() > 0) { + JSONObject user = data.getJSONObject(0); + String name = user.getString("username"); + String key = user.getString("key"); + if (name != null && key != null) { + return new Pair<>(key, name); + } + } + } catch (MalformedURLException e) { + Log.e(TAG, "Unable to create url", e); + } catch (IOException e) { + Log.e(TAG, "Unable to open connection", e); + } catch (JSONException e) { + Log.e(TAG, "Unable to create json", e); + } + + return null; + } + } +}