diff --git a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java index 0e9e503f0..21e13f4a5 100644 --- a/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java +++ b/src/org/thoughtcrime/securesms/components/rangeslider/TimeRangeSlider.java @@ -90,6 +90,12 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. public interface OnTimestampChangedListener { void onTimestampChanged(long startTimestamp, long stopTimestamp); + + /** + * filter for lastPosition beginning from startTimestamp to now + * @param startTimestamp begin of time frame + */ + void onFilterLastPosition(long startTimestamp); } @@ -101,9 +107,15 @@ public class TimeRangeSlider extends RangeSliderView implements RangeSliderView. public void onValueChanged(int minValue, int maxValue) { if (listener != null) { long minTimeStamp = getTimestampForValue(minValue); - if (minValue == maxValue) { - // filter for time of event with delta before and after - listener.onTimestampChanged(minTimeStamp - (long) DEFAULT_DELTA, minTimeStamp + (long) DEFAULT_DELTA); + if (maxValue == getCount()) { + if (minValue == maxValue) { + listener.onFilterLastPosition(System.currentTimeMillis() - (long) DEFAULT_DELTA); + } else { + listener.onFilterLastPosition(minTimeStamp); + } + } else if (minValue == maxValue) { + // filter for time of event with delta before and after + listener.onTimestampChanged(minTimeStamp - (long) DEFAULT_DELTA, minTimeStamp + (long) DEFAULT_DELTA); } else { //filter for time span listener.onTimestampChanged(minTimeStamp, getTimestampForValue(maxValue)); diff --git a/src/org/thoughtcrime/securesms/map/MapActivity.java b/src/org/thoughtcrime/securesms/map/MapActivity.java index 6b3ad3dc5..e994238a3 100644 --- a/src/org/thoughtcrime/securesms/map/MapActivity.java +++ b/src/org/thoughtcrime/securesms/map/MapActivity.java @@ -235,4 +235,11 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid } + @Override + public void onFilterLastPosition(long startTimestamp) { + if (this.mapboxMap == null) { + return; + } + mapDataManager.filterLastPositions(startTimestamp); + } } diff --git a/src/org/thoughtcrime/securesms/map/MapDataManager.java b/src/org/thoughtcrime/securesms/map/MapDataManager.java index 94e472957..79cfa0207 100644 --- a/src/org/thoughtcrime/securesms/map/MapDataManager.java +++ b/src/org/thoughtcrime/securesms/map/MapDataManager.java @@ -21,7 +21,6 @@ import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; import com.mapbox.geojson.LineString; import com.mapbox.geojson.Point; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.exceptions.InvalidLatLngBoundsException; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; @@ -49,10 +48,10 @@ import static com.b44t.messenger.DcContext.DC_EVENT_LOCATION_CHANGED; import static com.b44t.messenger.DcContext.DC_GCL_ADD_SELF; import static com.mapbox.mapboxsdk.style.expressions.Expression.all; import static com.mapbox.mapboxsdk.style.expressions.Expression.eq; -import static com.mapbox.mapboxsdk.style.expressions.Expression.neq; import static com.mapbox.mapboxsdk.style.expressions.Expression.get; import static com.mapbox.mapboxsdk.style.expressions.Expression.length; import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.neq; import static com.mapbox.mapboxsdk.style.expressions.Expression.not; import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; import static com.mapbox.mapboxsdk.style.expressions.Expression.toBool; @@ -70,6 +69,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOpacity; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; @@ -131,8 +131,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn initLastPositionLayer(); filterProvider.setMessageFilter(true); - long now = System.currentTimeMillis(); - filterProvider.setRangeFilter(now - DEFAULT_LAST_POSITION_DELTA, now); + filterProvider.setLastPositionFilter(System.currentTimeMillis() - DEFAULT_LAST_POSITION_DELTA); applyLastPositionFilter(); for (int contactId : contactIds) { updateSource(chatId, contactId, boundingBuilder); @@ -251,6 +250,12 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn applyFilters(contactIds); } + public void filterLastPositions(long timestamp) { + int[] contactIds = getContactIds(chatId); + filterProvider.setLastPositionFilter(timestamp); + applyFilters(contactIds); + } + public void showTraces(boolean show) { int[] contactIds = getContactIds(chatId); this.showTraces = show; @@ -278,7 +283,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private void applyLastPositionFilter() { SymbolLayer markerLayer = (SymbolLayer) mapboxStyle.getLayer(LAST_POSITION_LAYER); - markerLayer.setFilter(filterProvider.getRangeFilter()); + markerLayer.setFilter(filterProvider.getTimeFilter()); } private void applyMarkerFilter(MapSource source) { @@ -288,7 +293,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn private void applyLineFilter(MapSource source) { LineLayer lineLayer = (LineLayer) mapboxStyle.getLayer(source.getLineLayer()); - lineLayer.setFilter(filterProvider.getRangeFilter()); + lineLayer.setFilter(filterProvider.getTimeFilter()); } private void updateSource(int chatId, int contactId) { @@ -327,7 +332,6 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn locations.getMarker(i) != null ? locations.getMarker(i) : ""; - Log.d(TAG, "codepointChar: " + codepointChar); Feature pointFeature = Feature.fromGeometry(point, new JsonObject(), String.valueOf(locations.getLocationId(i))); pointFeature.addBooleanProperty(MARKER_SELECTED, false); @@ -406,8 +410,10 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn } private void initInfoWindowLayer() { - Expression iconOffset = switchCase(toBool(get(LAST_LOCATION)), - literal(new Float[] {-2f, -25f}), literal(new Float[] {-2f, -15f})); + Expression iconOffset = switchCase( + toBool(get(LAST_LOCATION)), literal(new Float[] {-2f, -25f}), + neq(length(get(MARKER_CHAR)), literal(0)), literal(new Float[] {-2f, -20f}), + literal(new Float[] {-2f, -15f})); GeoJsonSource infoWindowSource = new GeoJsonSource(INFO_WINDOW_SRC); mapboxStyle.addSource(infoWindowSource); mapboxStyle.addLayer(new SymbolLayer(INFO_WINDOW_LAYER, INFO_WINDOW_SRC).withProperties( @@ -431,7 +437,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn iconAllowOverlap(true), iconIgnorePlacement(true), iconSize(markerSize) - ).withFilter(filterProvider.getRangeFilter()), INFO_WINDOW_LAYER); + ).withFilter(filterProvider.getTimeFilter()), INFO_WINDOW_LAYER); } private void initContactBasedLayers(MapSource source) { @@ -457,7 +463,7 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn lineColor(source.getColorArgb()), visibility(NONE) ) - .withFilter(filterProvider.getRangeFilter()), + .withFilter(filterProvider.getTimeFilter()), LAST_POSITION_LAYER); @@ -469,8 +475,8 @@ public class MapDataManager implements DcEventCenter.DcEventDelegate, GenerateIn textIgnorePlacement(true), iconIgnorePlacement(false), iconAllowOverlap(false), - textField(get(MARKER_CHAR)) - ) + textField(get(MARKER_CHAR)), + textColor("#FFFFFF")) .withFilter(all(filterProvider.getMarkerFilter(), not(get(LAST_LOCATION)))), LAST_POSITION_LAYER); diff --git a/src/org/thoughtcrime/securesms/map/model/FilterProvider.java b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java index 667d66fa0..e50b0bf75 100644 --- a/src/org/thoughtcrime/securesms/map/model/FilterProvider.java +++ b/src/org/thoughtcrime/securesms/map/model/FilterProvider.java @@ -14,6 +14,7 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.lte; import static com.mapbox.mapboxsdk.style.expressions.Expression.neq; import static org.thoughtcrime.securesms.map.MapDataManager.MESSAGE_ID; import static org.thoughtcrime.securesms.map.MapDataManager.TIMESTAMP; +import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.LAST_POSITION; import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.MESSAGES; import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.RANGE; @@ -23,6 +24,7 @@ import static org.thoughtcrime.securesms.map.model.FilterProvider.FilterType.RAN public class FilterProvider { public enum FilterType { + LAST_POSITION, RANGE, MESSAGES } @@ -31,11 +33,17 @@ public class FilterProvider { public void setRangeFilter(long startTimestamp, long endTimestamp) { + removeFilter(LAST_POSITION); addFilter(RANGE, all( lte(get(TIMESTAMP), endTimestamp), gte(get(TIMESTAMP), startTimestamp))); } + public void setLastPositionFilter(long startTimestamp) { + removeFilter(RANGE); + addFilter(LAST_POSITION, gte(get(TIMESTAMP), startTimestamp)); + } + public void setMessageFilter(boolean filter) { if (filter) { addFilter(MESSAGES, neq(get(MESSAGE_ID), literal(0))); @@ -48,7 +56,7 @@ public class FilterProvider { expressions.put(type, expression); } - public void removeFilter(FilterType type) { + private void removeFilter(FilterType type) { expressions.remove(type); } @@ -56,10 +64,13 @@ public class FilterProvider { return all(expressions.values().toArray(new Expression[expressions.values().size()])); } - public Expression getRangeFilter() { - if (expressions.get(RANGE) != null) { + public Expression getTimeFilter() { + if (expressions.get(LAST_POSITION) != null) { + return expressions.get(LAST_POSITION); + } else if (expressions.get(RANGE) != null) { return expressions.get(RANGE); } + return all(); }