From dfd8d67480becde803ea99a15b1ebf7d93ccf65f Mon Sep 17 00:00:00 2001 From: cyBerta Date: Mon, 25 Mar 2019 15:02:27 +0100 Subject: [PATCH] if slider has max position, show 'Last Position', implement longpress for moving both thumb views, initial filter implementation --- res/values/strings.xml | 1 + .../rangeslider/RangeSliderView.java | 42 +++++++++++++++---- .../rangeslider/TimeRangeSlider.java | 3 ++ .../securesms/map/MapActivity.java | 24 ++++++++++- .../securesms/map/MapDataManager.java | 20 ++++++++- 5 files changed, 80 insertions(+), 10 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a0986a0e3..67860c29a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -221,6 +221,7 @@ Show location traces in time frame + Last position diff --git a/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java b/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java index 5dfacf477..8e361e55b 100644 --- a/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java +++ b/src/org/thoughtcrime/securesms/components/rangeslider/RangeSliderView.java @@ -7,6 +7,7 @@ import android.graphics.Canvas; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.util.Log; +import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; @@ -43,8 +44,11 @@ public class RangeSliderView extends View { protected float delta; private float beginTrackOffsetX; + private boolean isThumbViewLocked; private OnValueChangedListener onValueChangedListener; + GestureDetector longPressDetector; + public interface OnValueChangedListener { void onValueChanged(int minValue, int maxValue); @@ -125,6 +129,17 @@ public class RangeSliderView extends View { values.add(index); } delta = 0; + + longPressDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { + public void onLongPress(MotionEvent e) { + if (minValue == maxValue && (minValueThumb.isHighlight || maxValueThumb.isHighlight)) { + isThumbViewLocked = true; + minValueThumb.isHighlight = true; + maxValueThumb.isHighlight = true; + invalidate(); + } + } + }); } void setOnValueChangedListener(OnValueChangedListener onValueChangedListener) { @@ -183,21 +198,28 @@ public class RangeSliderView extends View { @Override public boolean onTouchEvent(MotionEvent event) { + longPressDetector.onTouchEvent(event); + if (event.getAction() == MotionEvent.ACTION_CANCEL) { minValueThumb.isHighlight = false; maxValueThumb.isHighlight = false; + isThumbViewLocked = false; invalidate(); return true; } - if (event.getAction() == MotionEvent.ACTION_UP && (minValueThumb.isHighlight || maxValueThumb.isHighlight)) { - if (onValueChangedListener != null) { - onValueChangedListener.onValueChanged(minValue, maxValue); + + if (event.getAction() == MotionEvent.ACTION_UP) { + isThumbViewLocked = false; + if (minValueThumb.isHighlight || maxValueThumb.isHighlight) { + if (onValueChangedListener != null) { + onValueChangedListener.onValueChanged(minValue, maxValue); + } + minValueThumb.isHighlight = false; + maxValueThumb.isHighlight = false; + invalidate(); + return true; } - minValueThumb.isHighlight = false; - maxValueThumb.isHighlight = false; - invalidate(); - return true; } int offsetX = (int) event.getX(); @@ -232,6 +254,7 @@ public class RangeSliderView extends View { minValueThumb.isHighlight = false; maxValueThumb.isHighlight = true; } + int count = values.size(); int index = getIndexFromPosition(offsetX); Log.d(TAG, "move - index: " + index + ", offsetX: " + offsetX); @@ -241,7 +264,10 @@ public class RangeSliderView extends View { index = count - 1; } - if (minValueThumb.isHighlight) { + if (isThumbViewLocked) { + minValue = values.get(index); + maxValue = values.get(index); + } else if (minValueThumb.isHighlight) { if (index > values.indexOf(maxValue)) { minValue = maxValue; } else { diff --git a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java index e4ea2ed40..4a27b0429 100644 --- a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java +++ b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java @@ -108,6 +108,9 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. @Override public String parseMaxValueDisplayText(int maxValue) { + if (minValue == maxValue && maxValue == getCount()) { + return getContext().getResources().getString(R.string.filter_last_position); + } return getStringForValue(maxValue); } diff --git a/src/org/thoughtcrime/securesms/map/MapActivity.java b/src/org/thoughtcrime/securesms/map/MapActivity.java index be60fe1e7..a1ab7ffb0 100644 --- a/src/org/thoughtcrime/securesms/map/MapActivity.java +++ b/src/org/thoughtcrime/securesms/map/MapActivity.java @@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.map; import android.content.Intent; import android.graphics.PointF; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetBehavior; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AlertDialog; @@ -13,8 +15,11 @@ import android.widget.RelativeLayout; import com.b44t.messenger.DcMsg; import com.mapbox.geojson.Feature; import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; +import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Style; import com.mapbox.mapboxsdk.maps.SupportMapFragment; @@ -34,11 +39,12 @@ import java.util.Observer; import static android.support.design.widget.BottomSheetBehavior.STATE_COLLAPSED; import static android.support.design.widget.BottomSheetBehavior.STATE_EXPANDED; +import static android.support.design.widget.BottomSheetBehavior.STATE_HIDDEN; import static com.b44t.messenger.DcChat.DC_CHAT_NO_CHAT; import static org.thoughtcrime.securesms.map.MapDataManager.MARKER_SELECTED; import static org.thoughtcrime.securesms.map.MapDataManager.MESSAGE_ID; -public class MapActivity extends BaseActivity implements Observer { +public class MapActivity extends BaseActivity implements Observer, TimeRangeSlider.OnTimestampChangedListener { public static final String TAG = MapActivity.class.getSimpleName(); public static final String CHAT_ID = "chat_id"; @@ -209,4 +215,20 @@ public class MapActivity extends BaseActivity implements Observer { //TODO: consider implementing a button -> center map to current location } } + + @Override + public void onValueChanged(long startTimestamp, long stopTimestamp) { + if (this.mapboxMap == null) { + return; + } + LatLngBounds.Builder boundingBuilder = new LatLngBounds.Builder(); + mapDataManager.filter(startTimestamp, stopTimestamp, boundingBuilder); + try { + mapboxMap.easeCamera( + CameraUpdateFactory.newLatLngBounds(boundingBuilder.build(), 50, 50, 50, 200), + 500); + } catch (InvalidLatLngBoundsException e) { + e.printStackTrace(); + } + } } diff --git a/src/org/thoughtcrime/securesms/map/MapDataManager.java b/src/org/thoughtcrime/securesms/map/MapDataManager.java index 2cf377ea6..2a7596725 100644 --- a/src/org/thoughtcrime/securesms/map/MapDataManager.java +++ b/src/org/thoughtcrime/securesms/map/MapDataManager.java @@ -204,12 +204,24 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn } } + public void filter(long startTimestamp, long endTimestamp, LatLngBounds.Builder builder) { + int[] contactIds = getContactIds(chatId); + for (int contactId : contactIds) { + resetSource(chatId); + updateSource(chatId, contactId, startTimestamp, endTimestamp, builder); + } + } + private void updateSource(int chatId, int contactId) { updateSource(chatId, contactId, null); } private void updateSource(int chatId, int contactId, LatLngBounds.Builder boundingBuilder) { - DcArray locations = dcContext.getLocations(chatId, contactId, System.currentTimeMillis() - TIMEOUT, TIMESTAMP_NOW); + updateSource(chatId, contactId, System.currentTimeMillis() - TIMEOUT, TIMESTAMP_NOW, boundingBuilder ); + } + + private void updateSource(int chatId, int contactId, long startTimestamp, long endTimestamp, LatLngBounds.Builder boundingBuilder) { + DcArray locations = dcContext.getLocations(chatId, contactId, startTimestamp, endTimestamp); MapSource contactMapMetadata = contactMapSources.get(contactId); if (contactMapMetadata == null) { contactMapMetadata = addContactMapSource(contactId); @@ -405,6 +417,12 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn } } + private void resetSource(int contactId) { + MapSource contactMapMetadata = contactMapSources.get(contactId); + if (contactMapMetadata != null) { + featureCollections.put(contactMapMetadata.getMarkerFeatureCollection(), new FeatureTreeSet()); + } + } private void replaceSelectedMarker(String featureId) { Feature feature = getFeatureWithId(featureId);